Files
clang-p2996/clang/test/SemaOpenCLCXX/invalid-kernel.clcpp
Anastasia Stulova 790cbaafc9 [OpenCL] Fix diagnostics with templates in kernel args.
Improve checking for the standard layout type when diagnosing
the kernel argument with templated types. The check doesn't work
correctly for references or pointers due to the lazy template
instantiation.

Current fix only improves cases where nested types in the templates
do not depend on the template parameters.

Differential Revision: https://reviews.llvm.org/D134445
2022-11-10 18:55:12 +00:00

117 lines
3.7 KiB
Plaintext

// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only -triple spir-unknown-unknown
// RUN: %clang_cc1 %s -pedantic -verify -fsyntax-only -triple spir-unknown-unknown -DUNSAFEKERNELPARAMETER
#ifdef UNSAFEKERNELPARAMETER
#pragma OPENCL EXTENSION __cl_clang_non_portable_kernel_param_types : enable
#endif
struct C {
kernel void m(); //expected-error{{kernel functions cannot be class members}}
};
template <typename T>
//expected-error@+1{{'T' cannot be used as the type of a kernel parameter}}
kernel void templ(T par) { //expected-error{{kernel functions cannot be used in a template declaration, instantiation or specialization}}
}
template <int>
kernel void bar(int par) { //expected-error{{kernel functions cannot be used in a template declaration, instantiation or specialization}}
}
kernel void foo(int); //expected-note{{previous declaration is here}}
kernel void foo(float); //expected-error{{conflicting types for 'foo'}}
kernel void int_v(int in);
kernel void int_p(__global int *in);
kernel void int_r(__global int &in);
kernel void int_p_p(__global int *__global *in);
kernel void int_p_r(__global int *__global &in);
kernel void int_p_p_r(__global int *__global *__global &in);
kernel void k_atomic_v(atomic_int in);
#ifndef UNSAFEKERNELPARAMETER
// expected-error@-2{{'__private atomic_int' (aka '__private _Atomic(int)') cannot be used as the type of a kernel parameter}}
#endif
kernel void k_atomic_p(__global atomic_int *in);
kernel void k_atomic_r(__global atomic_int &in);
kernel void k_pipe(read_only pipe int in, write_only pipe int out);
kernel void k_sampler(sampler_t in);
kernel void k_void(__global void *in);
typedef int int4 __attribute__((ext_vector_type(4)));
kernel void int4_v(int4 in);
kernel void int4_p(__global int4 *in);
kernel void int4_p_p(__global int4 *__global *in);
kernel void int4_r(__global int4 &in);
struct POD {
int a;
int b;
};
kernel void pod_v(POD in) {}
kernel void pod_p(__global POD *in) {}
kernel void pod_p_p(__global POD *__global *in) {}
kernel void pod_r(__global POD &in) {}
struct StandardLayout {
int a;
int b;
StandardLayout(int a, int b) : a(a), b(b) {}
};
kernel void standard_v(StandardLayout in) {}
#ifndef UNSAFEKERNELPARAMETER
//expected-error@-2{{'__private StandardLayout' cannot be used as the type of a kernel parameter}}
#endif
kernel void standard_p(__global StandardLayout *in) {}
kernel void standard_p_p(__global StandardLayout *__global *in) {}
kernel void standard_r(__global StandardLayout &in) {}
struct Trivial {
int a;
private:
int b;
};
kernel void trivial_v(Trivial in) {}
#ifndef UNSAFEKERNELPARAMETER
//expected-error@-2{{'__private Trivial' cannot be used as the type of a kernel parameter}}
#endif
kernel void trivial_p(__global Trivial *in) {}
#ifndef UNSAFEKERNELPARAMETER
//expected-error@-2{{'__global Trivial *__private' cannot be used as the type of a kernel parameter}}
#endif
kernel void trivial_p_p(__global Trivial *__global *in) {}
#ifndef UNSAFEKERNELPARAMETER
//expected-error@-2{{'__global Trivial *__global *__private' cannot be used as the type of a kernel parameter}}
#endif
kernel void trivial_r(__global Trivial &in) {}
#ifndef UNSAFEKERNELPARAMETER
//expected-error@-2{{'__global Trivial &__private' cannot be used as the type of a kernel parameter}}
#endif
// Nested types and templates
struct Outer {
struct Inner{
int i;
};
};
template<class T>
struct OuterTempl {
struct Inner{
int i;
};
};
// FIXME: (PR58590) Use of template parameter dependent types doesn't
// work yet due to lazy instantiation of reference types.
//template<class T>
//struct Templ {
//T i;
//};
extern kernel void nested(constant Outer::Inner& r1, constant OuterTempl<int>::Inner& r2/*, constant Templ<int>& r3*/);