brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · fb3b0db Raw
206 lines · cpp
1// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-pc-windows-msvc -fsycl-is-device -verify -fsyntax-only -Wno-unused2// RUN: %clang_cc1 %s -std=c++17 -triple x86_64-linux-gnu -fsycl-is-device -verify -fsyntax-only -Wno-unused3 4template <typename KernelName, typename KernelType>5[[clang::sycl_kernel]] void kernel_single_task(KernelType kernelFunc) { // #kernelSingleTask6  kernelFunc();7}8 9// kernel1 - expect error10// The current function is named with a lambda (i.e., takes a lambda as a11// template parameter. Call the builtin on the current function then it is12// passed to a kernel. Test that passing the given function to the unique13// stable name builtin and then to the kernel throws an error because the14// latter causes its name mangling to change.15template <typename Func>16void kernel1func(const Func &F1) {17  constexpr const char *F1_output = __builtin_sycl_unique_stable_name(Func); // #USN_F118  kernel_single_task<class kernel1>(F1); // #kernel1_call19}20 21void callkernel1() {22  kernel1func([]() {}); // #kernel1func_call23}24 25// kernel2 - expect error26// The current function is named with a lambda (i.e., takes a lambda as a27// template parameter). Call the builtin on the given function,28// then an empty lambda is passed to kernel.29// Test that passing the given function to the unique stable name builtin and30// then passing a different lambda to the kernel still throws an error because31// the calling context is part of naming the kernel. Even though the given32// function (F2) is not passed to the kernel, its mangling changes due to33// kernel call with the unrelated lambda.34template <typename Func>35void kernel2func(const Func &F2) {36  constexpr const char *F2_output = __builtin_sycl_unique_stable_name(Func); // #USN_F237  kernel_single_task<class kernel2>([]() {});38}39 40void callkernel2() {41  kernel2func([]() {}); // #kernel2func_call42}43 44template <template <typename> typename Outer, typename Inner>45struct S {46  void operator()() const;47};48 49template <typename Ty>50struct Tangerine {};51 52template <typename Func>53void kernel3_4func(const Func &F) {54  // Test that passing the same lambda to two kernels does not cause an error55  // because the kernel uses do not interfere with each other or invalidate56  // the stable name in any way.57  kernel_single_task<class kernel3>(F);58  kernel_single_task<class kernel4>(F);59  // Using the same functor twice should be fine60}61 62// kernel3 and kernel4 - expect no errors63void callkernel3_4() {64  kernel3_4func([]() {});65}66 67template <typename T>68static constexpr const char *output1 = __builtin_sycl_unique_stable_name(T);69 70#define MACRO()                      \71  auto l14 = []() { return 1; };     \72  constexpr const char *l14_output = \73      __builtin_sycl_unique_stable_name(decltype(l14));74 75int main() {76 77  // kernel5 - expect no error78  // Test that passing the lambda to the unique stable name builtin and then79  // using the lambda in a way that does not  contribute to the kernel name80  // does not cause an error because the  stable name is not invalidated in81  // this situation.82  auto l5 = []() {};83  constexpr const char *l5_output =84      __builtin_sycl_unique_stable_name(decltype(l5));85  kernel_single_task<class kernel5>(86      [=]() { l5(); }); // Used in the kernel, but not the kernel name itself87 88  // kernel6 - expect no error89  // Test that passing the lambda to the unique stable name builtin and then90  // using the same lambda in the naming of a kernel does not cause a diagnostic91  // on the kernel use due to the change in results to the stable name.92  auto l6 = []() { return 1; };93  constexpr const char *l6_output =94      __builtin_sycl_unique_stable_name(decltype(l6)); // #USN_l695  kernel_single_task<class kernel6>(l6); // Used in the kernel name after builtin96 97  // kernel7 - expect no error98  // Same as kernel11 (below) except make the lambda part of naming the kernel.99  // Test that passing a lambda to the unique stable name builtin and then100  // passing a second lambda to the kernel does not throw an error because the101  // first lambda is included in the signature of the second lambda, but does102  // not change the mangling of the kernel.103  auto l7 = []() { return 1; };104  auto l8 = [](decltype(l7) *derp = nullptr) { return 2; };105  constexpr const char *l7_output =106      __builtin_sycl_unique_stable_name(decltype(l7)); // #USN_l7107  kernel_single_task<class kernel7>(l8);108 109  // kernel8 and kernel9 - expect no error110  // Tests that passing a lambda to the unique stable name builtin and passing111  // it to a kernel called with an if constexpr branch does not cause a112  // diagnostic on the kernel9 as it does not change the result to the stable113  // name. This is interesting even though the use of kernel9 happens in the114  // false branch of a constexpr if because both the true and the false branches115  // cause the instantiation of kernel_single_task.116  auto l9 = []() { return 1; };117  auto l10 = []() { return 2; };118  constexpr const char *l10_output =119      __builtin_sycl_unique_stable_name(decltype(l10)); // #USN_l10120  if constexpr (1) {121    kernel_single_task<class kernel8>(l9);122  } else {123    kernel_single_task<class kernel9>(l10);124  }125 126  // kernel11 - expect no error127  // Test that passing a lambda to the unique stable name builtin and then128  // passing a second lambda capturing the first one to the kernel does not129  // throw an error because the first lambda is not involved in naming the130  // kernel i.e., the mangling does not change.131  auto l11 = []() { return 1; };132  auto l12 = [l11]() { return 2; };133  constexpr const char *l11_output =134      __builtin_sycl_unique_stable_name(decltype(l11));135  kernel_single_task<class kernel11>(l12);136 137  // kernel12 - expect no error138  // Test that passing a lambda to the unique stable name builtin and then139  // passing it to the kernel as a template template parameter does not cause a140  // diagnostic on the kernel use due to template template parameter being141  // involved in the mangling of the kernel name.142  auto l13 = []() { return 1; };143  constexpr const char *l13_output =144      __builtin_sycl_unique_stable_name(decltype(l13)); // #USN_l13145  kernel_single_task<class kernel12>(S<Tangerine, decltype(l13)>{});146 147  // kernel13 - expect no error148  // Test that passing a lambda to the unique stable name builtin within a macro149  // and then calling the macro within the kernel does not cause an error on the150  // kernel.151  kernel_single_task<class kernel13>(152      []() {153        MACRO(); // #USN_MACRO154      });155}156 157namespace NS {}158 159void f() {160  // expected-error@+1{{unknown type name 'bad_var'}}161  __builtin_sycl_unique_stable_name(bad_var);162  // expected-error@+1{{use of undeclared identifier 'bad'}}163  __builtin_sycl_unique_stable_name(bad::type);164  // expected-error@+1{{no type named 'still_bad' in namespace 'NS'}}165  __builtin_sycl_unique_stable_name(NS::still_bad);166 167  // FIXME: warning about side-effects in an unevaluated context expected, but168  // none currently emitted.169  int i = 0;170  __builtin_sycl_unique_stable_name(decltype(i++));171 172  // Tests that use within a VLA does not diagnose as a side-effecting use in173  // an unevaluated context because the use within a VLA extent forces174  // evaluation.175  int j = 55;176  __builtin_sycl_unique_stable_name(int[++j]); // expected-warning {{variable length arrays in C++ are a Clang extension}} \177                                                  expected-note {{a constant expression cannot modify an object that is visible outside that expression}}178}179 180template <typename T>181void f2() {182  // expected-error@+1{{no type named 'bad_val' in 'St'}}183  __builtin_sycl_unique_stable_name(typename T::bad_val);184  // expected-error@+1{{no type named 'bad_type' in 'St'}}185  __builtin_sycl_unique_stable_name(typename T::bad_type);186}187 188struct St {};189 190void use() {191  // expected-note@+1{{in instantiation of}}192  f2<St>();193}194 195// A previous implementation resulted in this being an example of the196// kernel-ordering and lexical lambda ordering issue.197void out_of_order_use() {198  auto x = [](){};199  auto y = [](){};200 201  kernel_single_task<decltype(y)>(y);202  constexpr auto USN =__builtin_sycl_unique_stable_name(decltype(y));203  (void)USN;204  kernel_single_task<decltype(x)>(x);205}206