1 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc %s -verify -DBAD_CONVERSION
2 // RUN: %clang_cc1 -fsyntax-only -triple i386-windows-pc %s -verify -DBAD_CONVERSION -DWIN32
3 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc %s -ast-dump | FileCheck %s --check-prefixes=CHECK,LIN64,NODEF
4 // RUN: %clang_cc1 -fsyntax-only -triple i386-windows-pc %s -ast-dump -DWIN32 | FileCheck %s --check-prefixes=CHECK,WIN32,NODEF
5 
6 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc -fdefault-calling-conv=vectorcall %s -verify -DBAD_VEC_CONVERS
7 // RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc -fdefault-calling-conv=vectorcall %s -ast-dump | FileCheck %s --check-prefixes=CHECK,VECTDEF
8 
useage()9 void useage() {
10   auto normal = [](int, float, double) {};                                // #1
11   auto vectorcall = [](int, float, double) __attribute__((vectorcall)){}; // #2
12 #ifdef WIN32
13   auto thiscall = [](int, float, double) __attribute__((thiscall)){}; // #3
14 #endif                                                                // WIN32
15   auto cdecl = [](int, float, double) __attribute__((cdecl)){};
16 
17   auto genericlambda = [](auto a) {};                                      // #4
18   auto genericvectorcalllambda = [](auto a) __attribute__((vectorcall)){}; // #5
19 
20   // None of these should be ambiguous.
21   (void)+normal;
22   (void)+vectorcall;
23 #ifdef WIN32
24   (void)+thiscall;
25 #endif // WIN32
26   (void)+cdecl;
27 
28 #ifdef BAD_CONVERSION
29   // expected-error-re@+1 {{invalid argument type {{.*}} to unary expression}}
30   (void)+genericlambda;
31   // expected-error-re@+1 {{invalid argument type {{.*}} to unary expression}}
32   (void)+genericvectorcalllambda;
33 #endif // BAD_CONVERSION
34 
35   // CHECK: VarDecl {{.*}} normal '
36   // CHECK: LambdaExpr
37   // WIN32: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((thiscall)) const'
38   // LIN64: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
39   // VECTDEF: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
40   // NODEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
41   // NODEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
42   // VECTDEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
43   // VECTDEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
44 
45   // CHECK: VarDecl {{.*}} vectorcall '
46   // CHECK: LambdaExpr
47   // CHECK: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((vectorcall)) const'
48   // CHECK: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
49   // CHECK: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
50 
51   // WIN32: VarDecl {{.*}} thiscall '
52   // WIN32: LambdaExpr
53   // WIN32: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((thiscall)) const'
54   // WIN32: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
55   // WIN32: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
56 
57   // CHECK: VarDecl {{.*}} cdecl '
58   // CHECK: LambdaExpr
59   // CHECK: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
60   // NODEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
61   // NODEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
62   // VECTDEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
63   // VECTDEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
64 
65   // CHECK: VarDecl {{.*}} genericlambda '
66   // CHECK: LambdaExpr
67   //
68   // CHECK: FunctionTemplateDecl {{.*}} operator()
69   // LIN64: CXXMethodDecl {{.*}} operator() 'auto (auto) const' inline
70   // LIN64: CXXMethodDecl {{.*}} operator() 'void (char) const' inline
71   // LIN64: CXXMethodDecl {{.*}} operator() 'void (int) const' inline
72   // WIN32: CXXMethodDecl {{.*}} operator() 'auto (auto) __attribute__((thiscall)) const' inline
73   // WIN32: CXXMethodDecl {{.*}} operator() 'void (char) __attribute__((thiscall)) const' inline
74   // WIN32: CXXMethodDecl {{.*}} operator() 'void (int) __attribute__((thiscall)) const' inline
75   //
76   // NODEF: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0)
77   // VECDEF: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall))
78   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) 'auto (*() const noexcept)(auto)'
79   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(char) 'void (*() const noexcept)(char)'
80   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(int) 'void (*() const noexcept)(int)'
81   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) 'auto (*() __attribute__((thiscall)) const noexcept)(auto)'
82   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) 'void (*() __attribute__((thiscall)) const noexcept)(char)'
83   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) 'void (*() __attribute__((thiscall)) const noexcept)(int)'
84   // VECDEF: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() const noexcept)(auto)' __attribute__((vectorcall))
85   // VECDEF: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() const noexcept)(char)' __attribute__((vectorcall))
86   // VECDEF: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() const noexcept)(int)' __attribute__((vectorcall))
87   //
88   // CHECK: FunctionTemplateDecl {{.*}} __invoke
89   // NODEF: CXXMethodDecl {{.*}} __invoke 'auto (auto)'
90   // NODEF: CXXMethodDecl {{.*}} __invoke 'void (char)'
91   // NODEF: CXXMethodDecl {{.*}} __invoke 'void (int)'
92   // VECDEF: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((vectorcall))'
93   // VECDEF: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((vectorcall))'
94   // VECDEF: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((vectorcall))'
95   //
96   // ONLY WIN32 has the duplicate here.
97   // WIN32: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((thiscall))
98   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((thiscall)) 'auto (*() __attribute__((thiscall)) const noexcept)(auto) __attribute__((thiscall))'
99   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((thiscall)) 'void (*() __attribute__((thiscall)) const noexcept)(char) __attribute__((thiscall))'
100   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((thiscall)) 'void (*() __attribute__((thiscall)) const noexcept)(int) __attribute__((thiscall))'
101   //
102   // WIN32: FunctionTemplateDecl {{.*}} __invoke
103   // WIN32: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((thiscall))'
104   // WIN32: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((thiscall))'
105   // WIN32: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((thiscall))'
106 
107   // CHECK: VarDecl {{.*}} genericvectorcalllambda '
108   // CHECK: LambdaExpr
109   // CHECK: FunctionTemplateDecl {{.*}} operator()
110   // CHECK: CXXMethodDecl {{.*}} operator() 'auto (auto) __attribute__((vectorcall)) const' inline
111   // CHECK: CXXMethodDecl {{.*}} operator() 'void (char) __attribute__((vectorcall)) const' inline
112   // CHECK: CXXMethodDecl {{.*}} operator() 'void (int) __attribute__((vectorcall)) const' inline
113   // CHECK: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall))
114   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() const noexcept)(auto) __attribute__((vectorcall))'
115   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() const noexcept)(char) __attribute__((vectorcall))'
116   // LIN64: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() const noexcept)(int) __attribute__((vectorcall))'
117   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() __attribute__((thiscall)) const noexcept)(auto) __attribute__((vectorcall))'
118   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() __attribute__((thiscall)) const noexcept)(char) __attribute__((vectorcall))'
119   // WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() __attribute__((thiscall)) const noexcept)(int) __attribute__((vectorcall))'
120   // CHECK: FunctionTemplateDecl {{.*}} __invoke
121   // CHECK: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((vectorcall))'
122   // CHECK: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((vectorcall))'
123   // CHECK: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((vectorcall))'
124 
125   // NODEF: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
126   // NODEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
127   // NODEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
128   // VECTDEF: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
129   // VECTDEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
130   // VECTDEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
131 
132   // CHECK: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
133   // CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
134   // CHECK-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
135 
136   // WIN32: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
137   // WIN32-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
138   // WIN32-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
139 
140   // NODEF: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
141   // NODEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
142   // NODEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
143   // VECTDEF: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
144   // VECTDEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
145   // VECTDEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
146 
147 #ifdef BAD_CONVERSION
148   // expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double) __attribute__((vectorcall))}}
149   // expected-note@#1 {{candidate function}}
150   void (*__attribute__((vectorcall)) normal_ptr2)(int, float, double) = normal;
151   // expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double)}}
152   // expected-note@#2 {{candidate function}}
153   void (*vectorcall_ptr2)(int, float, double) = vectorcall;
154 #ifdef WIN32
155   void (*__attribute__((thiscall)) thiscall_ptr2)(int, float, double) = thiscall;
156 #endif // WIN32
157   // expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(char) __attribute__((vectorcall))'}}
158   // expected-note@#4 {{candidate function}}
159   void(__vectorcall * generic_ptr)(char) = genericlambda;
160   // expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(char)}}
161   // expected-note@#5 {{candidate function}}
162   void (*generic_ptr2)(char) = genericvectorcalllambda;
163 #endif // BAD_CONVERSION
164 
165 #ifdef BAD_VEC_CONVERS
166   void (*__attribute__((vectorcall)) normal_ptr2)(int, float, double) = normal;
167   void (*normal_ptr3)(int, float, double) = normal;
168   // expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double) __attribute__((regcall))}}
169   // expected-note@#1 {{candidate function}}
170   void (*__attribute__((regcall)) normalptr4)(int, float, double) = normal;
171   void (*__attribute__((vectorcall)) vectorcall_ptr2)(int, float, double) = vectorcall;
172   void (*vectorcall_ptr3)(int, float, double) = vectorcall;
173 #endif // BAD_VEC_CONVERS
174 
175   // Required to force emission of the invoker.
176   void (*normal_ptr)(int, float, double) = normal;
177   void (*__attribute__((vectorcall)) vectorcall_ptr)(int, float, double) = vectorcall;
178 #ifdef WIN32
179   void (*thiscall_ptr)(int, float, double) = thiscall;
180 #endif // WIN32
181   void (*cdecl_ptr)(int, float, double) = cdecl;
182   void (*generic_ptr3)(char) = genericlambda;
183   void (*generic_ptr4)(int) = genericlambda;
184 #ifdef WIN32
185   void (*__attribute__((thiscall)) generic_ptr3b)(char) = genericlambda;
186   void (*__attribute__((thiscall)) generic_ptr4b)(int) = genericlambda;
187 #endif
188   void (*__attribute__((vectorcall)) generic_ptr5)(char) = genericvectorcalllambda;
189   void (*__attribute__((vectorcall)) generic_ptr6)(int) = genericvectorcalllambda;
190 }
191