File: sycl-kernel-entry-point-attr-sfinae.cpp

package info (click to toggle)
llvm-toolchain-21 1%3A21.1.6-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 2,245,044 kB
  • sloc: cpp: 7,619,726; ansic: 1,434,018; asm: 1,058,748; python: 252,740; f90: 94,671; objc: 70,685; lisp: 42,813; pascal: 18,401; sh: 8,601; ml: 5,111; perl: 4,720; makefile: 3,666; awk: 3,523; javascript: 2,409; xml: 892; fortran: 770
file content (65 lines) | stat: -rw-r--r-- 3,234 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++17 -fsyntax-only -fsycl-is-device -verify %s
// RUN: %clang_cc1 -triple x86_64-linux-gnu -std=c++20 -fsyntax-only -fsycl-is-device -verify %s

// These tests are intended to validate that a sycl_kernel_entry_point attribute
// appearing in the declaration of a function template does not affect overload
// resolution or cause spurious errors during overload resolution due to either
// a substitution failure in the attribute argument or a semantic check of the
// attribute during instantiation of a specialization unless that specialization
// is selected by overload resolution.

// FIXME: C++23 [temp.expl.spec]p12 states:
// FIXME:   ... Similarly, attributes appearing in the declaration of a template
// FIXME:   have no effect on an explicit specialization of that template.
// FIXME: Clang currently instantiates and propagates attributes from a function
// FIXME: template to its explicit specializations resulting in the following
// FIXME: spurious error.
struct S1; // #S1-decl
// expected-error@+4 {{incomplete type 'S1' named in nested name specifier}}
// expected-note@+5 {{in instantiation of function template specialization 'ok1<S1>' requested here}}
// expected-note@#S1-decl {{forward declaration of 'S1'}}
template<typename T>
[[clang::sycl_kernel_entry_point(typename T::invalid)]] void ok1() {}
template<>
void ok1<S1>() {}
void test_ok1() {
  // ok1<S1>() is not a call to a SYCL kernel entry point function.
  ok1<S1>();
}

// FIXME: The sycl_kernel_entry_point attribute should not be instantiated
// FIXME: until after overload resolution has completed.
struct S2; // #S2-decl
// expected-error@+6 {{incomplete type 'S2' named in nested name specifier}}
// expected-note@+10 {{in instantiation of function template specialization 'ok2<S2>' requested here}}
// expected-note@#S2-decl {{forward declaration of 'S2'}}
template<typename T>
[[clang::sycl_kernel_entry_point(T)]] void ok2(int) {}
template<typename T>
[[clang::sycl_kernel_entry_point(typename T::invalid)]] void ok2(long) {}
void test_ok2() {
  // ok2(int) is a better match and is therefore selected by overload
  // resolution; the attempted instantiation of ok2(long) should not produce
  // an error for the substitution failure into the attribute argument.
  ok2<S2>(2);
}

// FIXME: The sycl_kernel_entry_point attribute should not be instantiated
// FIXME: until after overload resolution has completed.
struct S3;
struct Select3 {
  using bad_type = int;
  using good_type = S3;
};
// expected-error@+5 {{'typename Select3::bad_type' (aka 'int') is not a valid SYCL kernel name type; a non-union class type is required}}
// expected-note@+9 {{in instantiation of function template specialization 'ok3<Select3>' requested here}}
template<typename T>
[[clang::sycl_kernel_entry_point(typename T::good_type)]] void ok3(int) {}
template<typename T>
[[clang::sycl_kernel_entry_point(typename T::bad_type)]] void ok3(long) {}
void test_ok3() {
  // ok3(int) is a better match and is therefore selected by overload
  // resolution; the attempted instantiation of ok3(long) should not produce
  // an error for the invalid kernel name provided as the attribute argument.
  ok3<Select3>(2);
}