1// RUN: %clang_cc1 -fsyntax-only -verify %s -triple spir-unknown-unknown
2
3#pragma OPENCL EXTENSION cl_khr_fp16 : enable
4
5
6// Disallowed: parameters with type
7// bool, half, size_t, ptrdiff_t, intptr_t, and uintptr_t
8// or a struct / union with any of these types in them
9
10// TODO: Ban int types, size_t, ptrdiff_t ...
11
12kernel void bool_arg(bool x) { } // expected-error{{'bool' cannot be used as the type of a kernel parameter}}
13
14kernel void half_arg(half x) { } // expected-error{{'half' cannot be used as the type of a kernel parameter}}
15
16typedef struct ContainsBool // expected-note{{within field of type 'ContainsBool' declared here}}
17{
18  bool x; // expected-note{{field of illegal type 'bool' declared here}}
19} ContainsBool;
20
21kernel void bool_in_struct_arg(ContainsBool x) { } // expected-error{{'ContainsBool' (aka 'struct ContainsBool') cannot be used as the type of a kernel parameter}}
22
23
24
25typedef struct FooImage2D // expected-note{{within field of type 'FooImage2D' declared here}}
26{
27  // TODO: Clean up needed - we don't really need to check for image, event, etc
28  // as a note here any longer.
29  // They are diagnosed as an error for all struct fields (OpenCL v1.2 s6.9b,r).
30  image2d_t imageField; // expected-note{{field of illegal type '__read_only image2d_t' declared here}} expected-error{{the '__read_only image2d_t' type cannot be used to declare a structure or union field}}
31} FooImage2D;
32
33kernel void image_in_struct_arg(FooImage2D arg) { } // expected-error{{struct kernel parameters may not contain pointers}}
34
35typedef struct Foo // expected-note{{within field of type 'Foo' declared here}}
36{
37  int* ptrField; // expected-note{{field of illegal pointer type 'int *' declared here}}
38} Foo;
39
40kernel void pointer_in_struct_arg(Foo arg) { } // expected-error{{struct kernel parameters may not contain pointers}}
41
42typedef union FooUnion // expected-note{{within field of type 'FooUnion' declared here}}
43{
44  int* ptrField; // expected-note{{field of illegal pointer type 'int *' declared here}}
45} FooUnion;
46
47kernel void pointer_in_union_arg(FooUnion arg) { }// expected-error{{union kernel parameters may not contain pointers}}
48
49typedef struct NestedPointer // expected-note 2 {{within field of type 'NestedPointer' declared here}}
50{
51  int x;
52  struct InnerNestedPointer
53  {
54    int* ptrField; // expected-note 3 {{field of illegal pointer type 'int *' declared here}}
55  } inner; // expected-note 3 {{within field of type 'struct InnerNestedPointer' declared here}}
56} NestedPointer;
57
58kernel void pointer_in_nested_struct_arg(NestedPointer arg) { }// expected-error{{struct kernel parameters may not contain pointers}}
59
60struct NestedPointerComplex // expected-note{{within field of type 'NestedPointerComplex' declared here}}
61{
62  int foo;
63  float bar;
64
65  struct InnerNestedPointerComplex
66  {
67    int innerFoo;
68    int* innerPtrField; // expected-note{{field of illegal pointer type 'int *' declared here}}
69  } inner; // expected-note{{within field of type 'struct InnerNestedPointerComplex' declared here}}
70
71  float y;
72  float z[4];
73};
74
75kernel void pointer_in_nested_struct_arg_complex(struct NestedPointerComplex arg) { }// expected-error{{struct kernel parameters may not contain pointers}}
76
77typedef struct NestedBool // expected-note 2 {{within field of type 'NestedBool' declared here}}
78{
79  int x;
80  struct InnerNestedBool
81  {
82    bool boolField; // expected-note 2 {{field of illegal type 'bool' declared here}}
83  } inner; // expected-note 2 {{within field of type 'struct InnerNestedBool' declared here}}
84} NestedBool;
85
86kernel void bool_in_nested_struct_arg(NestedBool arg) { } // expected-error{{'NestedBool' (aka 'struct NestedBool') cannot be used as the type of a kernel parameter}}
87
88// Warning emitted again for argument used in other kernel
89kernel void bool_in_nested_struct_arg_again(NestedBool arg) { } // expected-error{{'NestedBool' (aka 'struct NestedBool') cannot be used as the type of a kernel parameter}}
90
91
92// Check for note with a struct not defined inside the struct
93typedef struct NestedBool2Inner
94{
95  bool boolField; // expected-note{{field of illegal type 'bool' declared here}}
96} NestedBool2Inner;
97
98typedef struct NestedBool2 // expected-note{{within field of type 'NestedBool2' declared here}}
99{
100  int x;
101  NestedBool2Inner inner; // expected-note{{within field of type 'NestedBool2Inner' (aka 'struct NestedBool2Inner') declared here}}
102} NestedBool2;
103
104kernel void bool_in_nested_struct_2_arg(NestedBool2 arg) { } // expected-error{{'NestedBool2' (aka 'struct NestedBool2') cannot be used as the type of a kernel parameter}}
105
106
107struct InnerInner
108{
109  int* foo;
110  bool x;
111};
112
113struct Valid
114{
115  float c;
116  float d;
117};
118
119struct Inner
120{
121  struct Valid v;
122  struct InnerInner a;
123  struct Valid g;
124  struct InnerInner b;
125};
126
127struct AlsoUser // expected-note{{within field of type 'AlsoUser' declared here}}
128{
129  float x;
130  struct Valid valid1;
131  struct Valid valid2;
132  struct NestedPointer aaaa; // expected-note{{within field of type 'struct NestedPointer' declared here}}
133};
134
135kernel void pointer_in_nested_struct_arg_2(struct Valid valid, struct NestedPointer arg, struct AlsoUser also) { } // expected-error 2 {{struct kernel parameters may not contain pointers}}
136