Skip to content

Commit 86e7728

Browse files
committed
Remove diagnostic for implicit template instantiation;
Address other review comments
1 parent a88cf0e commit 86e7728

File tree

5 files changed

+30
-26
lines changed

5 files changed

+30
-26
lines changed

clang/lib/Sema/SemaDecl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,6 +3068,10 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
30683068
cast<SYCLKernelEntryPointAttr>(NewAttribute)->setInvalidAttr();
30693069
++I;
30703070
continue;
3071+
} else if (isa<SYCLExternalAttr>(NewAttribute)) {
3072+
// SYCLExternalAttr may be added after a definition.
3073+
++I;
3074+
continue;
30713075
}
30723076

30733077
S.Diag(NewAttribute->getLocation(),

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,12 @@ static bool CheckSYCLKernelName(Sema &S, SourceLocation Loc,
253253
void SemaSYCL::CheckSYCLExternalFunctionDecl(FunctionDecl *FD) {
254254
const auto *SEAttr = FD->getAttr<SYCLExternalAttr>();
255255
assert(SEAttr && "Missing sycl_external attribute");
256-
if (!FD->isExternallyVisible()) {
257-
Diag(SEAttr->getLocation(), diag::err_sycl_external_invalid_linkage)
258-
<< SEAttr;
256+
if (!FD->isInvalidDecl() && !FD->isTemplated()) {
257+
if (!FD->isExternallyVisible())
258+
if (!FD->isFunctionTemplateSpecialization() ||
259+
FD->getTemplateSpecializationInfo()->isExplicitSpecialization())
260+
Diag(SEAttr->getLocation(), diag::err_sycl_external_invalid_linkage)
261+
<< SEAttr;
259262
}
260263
if (FD->isDeletedAsWritten()) {
261264
Diag(SEAttr->getLocation(),

clang/test/CodeGenSYCL/kernel-caller-entry-point.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ int main() {
101101
// Verify that SYCL kernel caller functions are emitted for each device target.
102102
//
103103
// main() shouldn't be emitted in device code.
104-
// CHECK-NOT: define {{[a-z_ ]*}}noundef i32 @main() #0
104+
// CHECK-NOT: @main()
105105

106106
// IR for the SYCL kernel caller function generated for
107107
// single_purpose_kernel_task with single_purpose_kernel_name as the SYCL kernel

clang/test/CodeGenSYCL/sycl-external-attr.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,23 @@
1010
[[clang::sycl_external]] int squareUsed(int x) { return x*x; }
1111
// CHECK: define dso_local spir_func noundef i32 @_Z10squareUsedi
1212

13-
// Constexpr function defined and not used - symbols emitted
13+
// FIXME: Constexpr function defined and not used - symbols emitted
1414
[[clang::sycl_external]] constexpr int squareInlined(int x) { return x*x; }
1515
// CHECK: define linkonce_odr spir_func noundef i32 @_Z13squareInlinedi
1616

1717
// Function declared but not defined or used - no symbols emitted
1818
[[clang::sycl_external]] int declOnly();
1919
// CHECK-NOT: define {{.*}} i32 @_Z8declOnlyv
20+
// CHECK-NOT: declare {{.*}} i32 @_Z8declOnlyv
2021

22+
// Function declared and used in host but not defined - no symbols emitted
23+
[[clang::sycl_external]] void declUsedInHost(int y);
2124

22-
// FIXME: Function declared and used but not defined - emit external reference
23-
[[clang::sycl_external]] void declUsed(int y);
25+
// Function declared and used in device but not defined - emit external reference
26+
[[clang::sycl_external]] void declUsedInDevice(int y);
27+
// CHECK: define dso_local spir_func void @_Z9deviceUsev
28+
[[clang::sycl_external]] void deviceUse() { declUsedInDevice(3); }
29+
// CHECK: declare spir_func void @_Z16declUsedInDevicei
2430

2531
// Function declared with the attribute and later defined - definition emitted
2632
[[clang::sycl_external]] int func1(int arg);
@@ -66,12 +72,13 @@ template<> void tFunc2<char>(char arg) {}
6672
template<> [[clang::sycl_external]] void tFunc2<long>(long arg) {}
6773
// CHECK: define dso_local spir_func void @_Z6tFunc2IlEvT_
6874

69-
// Test that symbols are not emitted without the sycl_external attribute
75+
// Functions defined without the sycl_external attribute that are used
76+
// in host code, but not in device code are not emitted.
7077
int squareNoAttr(int x) { return x*x; }
7178
// CHECK-NOT: define {{.*}} i32 @_Z12squareNoAttri
7279

7380
int main() {
74-
declUsed(4);
81+
declUsedInHost(4);
7582
int i = squareUsed(5);
7683
int j = squareNoAttr(6);
7784
return 0;

clang/test/SemaSYCL/sycl-external-attr.cpp

Lines changed: 7 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,20 @@ namespace { struct S4 {}; }
2020
[[clang::sycl_external]] void func4(S4) {}
2121

2222
// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}
23+
namespace { struct S5 {}; }
24+
template<typename> [[clang::sycl_external]] void func5();
25+
template<> [[clang::sycl_external]] void func5<S5>() {}
26+
2327
namespace { struct S6 {}; }
2428
template<typename>
2529
[[clang::sycl_external]] void func6() {}
2630
template void func6<S6>();
27-
// expected-note@-1{{in instantiation of function template specialization 'func6<(anonymous namespace)::S6>' requested here}}
28-
29-
// FIXME: C++23 [temp.expl.spec]p12 states:
30-
// ... Similarly, attributes appearing in the declaration of a template
31-
// have no effect on an explicit specialization of that template.
32-
// Clang currently instantiates and propagates attributes from a function
33-
// template to its explicit specializations resulting in the following
34-
// spurious error.
35-
// expected-error@+3 2{{'clang::sycl_external' can only be applied to functions with external linkage}}
31+
32+
// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}
3633
namespace { struct S7 {}; }
3734
template<typename>
3835
[[clang::sycl_external]] void func7();
3936
template<> void func7<S7>() {}
40-
// expected-note@-1{{in instantiation of function template specialization 'func7<(anonymous namespace)::S7>' requested here}}
4137

4238
// FIXME: The explicit function template specialization appears to trigger
4339
// instantiation of a declaration from the primary template without the
@@ -51,21 +47,17 @@ template<> [[clang::sycl_external]] void func8<S8>() {}
5147
// expected-error@-2{{'clang::sycl_external' can only be applied to functions with external linkage}}
5248
// expected-note@-3{{previous declaration is here}}
5349

54-
// FIXME: The implicit instantiation of func9<S9>() is valid.
5550
namespace { struct S9 {}; }
5651
struct T9 {
5752
using type = S9;
5853
};
59-
// expected-error@+2{{'clang::sycl_external' can only be applied to functions with external linkage}}
6054
template<typename>
6155
[[clang::sycl_external]] void func9() {}
62-
// expected-note@+3{{in instantiation of function template specialization 'func9<(anonymous namespace)::S9>' requested here}}
6356
template<typename T>
6457
[[clang::sycl_external]] void test_func9() {
6558
func9<typename T::type>();
6659
}
67-
// expected-note@+1{{in instantiation of function template specialization 'test_func9<T9>' requested here}}
68-
template void test_func9<T9>(); // FIXME: don't diagnose implicit instantiation of func9<S9>().
60+
template void test_func9<T9>();
6961

7062
// The first declaration of a SYCL external function is required to have this attribute.
7163
// expected-note@+1{{previous declaration is here}}
@@ -79,10 +71,8 @@ void goo();
7971
[[clang::sycl_external]] void goo();
8072
void goo() {}
8173

82-
// expected-note@+2{{previous definition is here}}
8374
// expected-note@+1{{previous declaration is here}}
8475
void hoo() {}
85-
// expected-warning@+2{{attribute declaration must precede definition}}
8676
// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}
8777
[[clang::sycl_external]] void hoo();
8878

0 commit comments

Comments
 (0)