Skip to content

Commit e1de85d

Browse files
committed
[clang][FMV] Allow declaration of function versions in namespaces.
Fixes a bug: ../llvm-project/clang/test/Sema/fmv-namespace.cpp:8:18: warning: attribute declaration must precede definition [-Wignored-attributes] 8 | int __attribute((target_version("sve"))) foo() { return 1; } | ^ ../llvm-project/clang/test/Sema/fmv-namespace.cpp:4:46: note: previous definition is here 4 | int __attribute((target_version("default"))) foo() { return 0; } | ^ ../llvm-project/clang/test/Sema/fmv-namespace.cpp:8:42: error: redefinition of 'foo' 8 | int __attribute((target_version("sve"))) foo() { return 1; } | ^ ../llvm-project/clang/test/Sema/fmv-namespace.cpp:4:46: note: previous definition is here 4 | int __attribute((target_version("default"))) foo() { return 0; } | ^ 1 warning and 1 error generated.
1 parent e5936b2 commit e1de85d

File tree

3 files changed

+72
-2
lines changed

3 files changed

+72
-2
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11868,8 +11868,10 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
1186811868
return false;
1186911869

1187011870
if (!OldDecl || !OldDecl->getAsFunction() ||
11871-
OldDecl->getDeclContext()->getRedeclContext() !=
11872-
NewFD->getDeclContext()->getRedeclContext()) {
11871+
(OldDecl->getDeclContext()->getRedeclContext() !=
11872+
NewFD->getDeclContext()->getRedeclContext() &&
11873+
OldDecl->getDeclContext()->getEnclosingNamespaceContext() !=
11874+
NewFD->getDeclContext()->getEnclosingNamespaceContext())) {
1187311875
// If there's no previous declaration, AND this isn't attempting to cause
1187411876
// multiversioning, this isn't an error condition.
1187511877
if (MVKind == MultiVersionKind::None)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// NOTE: Assertions have been autogenerated by utils/update_cc_test_checks.py UTC_ARGS: --check-globals all --include-generated-funcs --version 5
2+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s
3+
4+
namespace Name {
5+
int __attribute((target_version("default"))) foo() { return 0; }
6+
}
7+
8+
namespace Name {
9+
int __attribute((target_version("sve"))) foo() { return 1; }
10+
}
11+
12+
int bar() { return Name::foo(); }
13+
//.
14+
// CHECK: @__aarch64_cpu_features = external dso_local global { i64 }
15+
// CHECK: @_ZN4Name3fooEv.ifunc = weak_odr alias i32 (), ptr @_ZN4Name3fooEv
16+
// CHECK: @_ZN4Name3fooEv = weak_odr ifunc i32 (), ptr @_ZN4Name3fooEv.resolver
17+
//.
18+
// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv.default(
19+
// CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
20+
// CHECK-NEXT: [[ENTRY:.*:]]
21+
// CHECK-NEXT: ret i32 0
22+
//
23+
//
24+
// CHECK-LABEL: define dso_local noundef i32 @_ZN4Name3fooEv._Msve(
25+
// CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
26+
// CHECK-NEXT: [[ENTRY:.*:]]
27+
// CHECK-NEXT: ret i32 1
28+
//
29+
//
30+
// CHECK-LABEL: define dso_local noundef i32 @_Z3barv(
31+
// CHECK-SAME: ) #[[ATTR0]] {
32+
// CHECK-NEXT: [[ENTRY:.*:]]
33+
// CHECK-NEXT: [[CALL:%.*]] = call noundef i32 @_ZN4Name3fooEv()
34+
// CHECK-NEXT: ret i32 [[CALL]]
35+
//
36+
//
37+
// CHECK-LABEL: define weak_odr ptr @_ZN4Name3fooEv.resolver() comdat {
38+
// CHECK-NEXT: [[RESOLVER_ENTRY:.*:]]
39+
// CHECK-NEXT: call void @__init_cpu_features_resolver()
40+
// CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr @__aarch64_cpu_features, align 8
41+
// CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 1073741824
42+
// CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 1073741824
43+
// CHECK-NEXT: [[TMP3:%.*]] = and i1 true, [[TMP2]]
44+
// CHECK-NEXT: br i1 [[TMP3]], label %[[RESOLVER_RETURN:.*]], label %[[RESOLVER_ELSE:.*]]
45+
// CHECK: [[RESOLVER_RETURN]]:
46+
// CHECK-NEXT: ret ptr @_ZN4Name3fooEv._Msve
47+
// CHECK: [[RESOLVER_ELSE]]:
48+
// CHECK-NEXT: ret ptr @_ZN4Name3fooEv.default
49+
//
50+
//.
51+
// CHECK: attributes #[[ATTR0]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
52+
// CHECK: attributes #[[ATTR1]] = { mustprogress noinline nounwind optnone "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-features"="+fp-armv8,+fullfp16,+neon,+sve" }
53+
//.
54+
// CHECK: [[META0:![0-9]+]] = !{i32 1, !"wchar_size", i32 4}
55+
// CHECK: [[META1:![0-9]+]] = !{!"{{.*}}clang version {{.*}}"}
56+
//.

clang/test/Sema/fmv-namespace.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %clang_cc1 -triple aarch64-linux-gnu -fsyntax-only -verify %s
2+
// expected-no-diagnostics
3+
4+
namespace Name {
5+
int __attribute((target_version("default"))) foo() { return 0; }
6+
}
7+
8+
namespace Name {
9+
int __attribute((target_version("sve"))) foo() { return 1; }
10+
}
11+
12+
int bar() { return Name::foo(); }

0 commit comments

Comments
 (0)