155 lines · cpp
1// RUN: %clang_cc1 -fsycl-is-host -std=c++17 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fsycl-is-device -std=c++17 -fsyntax-only -verify %s3// RUN: %clang_cc1 -fsycl-is-host -std=c++20 -fsyntax-only -verify -DCPP20 %s4// RUN: %clang_cc1 -fsycl-is-device -std=c++20 -fsyntax-only -verify -DCPP20 %s5 6// Semantic tests for the sycl_external attribute.7 8// expected-error@+1{{'clang::sycl_external' can only be applied to functions with external linkage}}9[[clang::sycl_external]]10static void func1() {}11 12// expected-error@+2{{'clang::sycl_external' can only be applied to functions with external linkage}}13namespace {14 [[clang::sycl_external]]15 void func2() {}16}17 18// expected-error@+2{{'clang::sycl_external' can only be applied to functions with external linkage}}19namespace { struct S4 {}; }20[[clang::sycl_external]] void func4(S4) {}21 22// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}23namespace { struct S5 {}; }24template<typename> [[clang::sycl_external]] void func5();25template<> [[clang::sycl_external]] void func5<S5>() {}26 27namespace { struct S6 {}; }28template<typename>29[[clang::sycl_external]] void func6() {}30template void func6<S6>();31 32// FIXME: C++23 [temp.expl.spec]p12 states:33// ... Similarly, attributes appearing in the declaration of a template34// have no effect on an explicit specialization of that template.35// Clang currently instantiates and propagates attributes from a function36// template to its explicit specializations resulting in the following37// spurious error.38// expected-error@+3{{'clang::sycl_external' can only be applied to functions with external linkage}}39namespace { struct S7 {}; }40template<typename>41[[clang::sycl_external]] void func7();42template<> void func7<S7>() {}43 44// FIXME: The explicit function template specialization appears to trigger45// instantiation of a declaration from the primary template without the46// attribute leading to a spurious diagnostic that the sycl_external47// attribute is not present on the first declaration.48namespace { struct S8 {}; }49template<typename>50void func8();51template<> [[clang::sycl_external]] void func8<S8>() {}52// expected-warning@-1{{'clang::sycl_external' attribute does not appear on the first declaration}}53// expected-error@-2{{'clang::sycl_external' can only be applied to functions with external linkage}}54// expected-note@-3{{previous declaration is here}}55 56namespace { struct S9 {}; }57struct T9 {58 using type = S9;59};60template<typename>61[[clang::sycl_external]] void func9() {}62template<typename T>63[[clang::sycl_external]] void test_func9() {64 func9<typename T::type>();65}66template void test_func9<T9>();67 68// The first declaration of a SYCL external function is required to have this attribute.69// expected-note@+1{{previous declaration is here}}70int foo();71// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}72[[clang::sycl_external]] int foo();73 74// expected-note@+1{{previous declaration is here}}75void goo();76// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}77[[clang::sycl_external]] void goo();78void goo() {}79 80// expected-note@+1{{previous declaration is here}}81void hoo() {}82// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}83[[clang::sycl_external]] void hoo();84 85// expected-note@+1{{previous declaration is here}}86void joo();87void use_joo() {88 joo();89}90// expected-warning@+1{{'clang::sycl_external' attribute does not appear on the first declaration}}91[[clang::sycl_external]] void joo();92 93// Subsequent declarations of a SYCL external function may optionally specify this attribute.94[[clang::sycl_external]] int boo();95[[clang::sycl_external]] int boo(); // OK96int boo(); // OK97 98class C {99 [[clang::sycl_external]] void member();100};101 102// expected-error@+1{{'clang::sycl_external' cannot be applied to the 'main' function}}103[[clang::sycl_external]] int main()104{105 return 0;106}107 108// expected-error@+2{{'clang::sycl_external' cannot be applied to an explicitly deleted function}}109class D {110 [[clang::sycl_external]] void mdel() = delete;111};112 113// expected-error@+1{{'clang::sycl_external' cannot be applied to an explicitly deleted function}}114[[clang::sycl_external]] void del() = delete;115 116struct NonCopyable {117 ~NonCopyable() = delete;118 [[clang::sycl_external]] NonCopyable(const NonCopyable&) = default;119};120 121class A {122 [[clang::sycl_external]]123 A() {}124 125 [[clang::sycl_external]] void mf() {}126 [[clang::sycl_external]] static void smf();127};128 129class B {130public:131 [[clang::sycl_external]] virtual void foo() {}132 133 [[clang::sycl_external]] virtual void bar() = 0;134};135[[clang::sycl_external]] void B::bar() {}136 137[[clang::sycl_external]] constexpr int square(int x);138 139// Devices that do not support the generic address space shall not specify140// a raw pointer or reference type as the return type or as a parameter type.141[[clang::sycl_external]] int *fun0();142[[clang::sycl_external]] int &fun1();143[[clang::sycl_external]] int &&fun2();144[[clang::sycl_external]] void fun3(int *);145[[clang::sycl_external]] void fun4(int &);146[[clang::sycl_external]] void fun5(int &&);147template<typename T>148[[clang::sycl_external]] void fun6(T) {}149template void fun6(int *);150template<> [[clang::sycl_external]] void fun6<long*>(long *) {}151 152#if CPP20153[[clang::sycl_external]] consteval int func();154#endif155