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