191 lines
12 KiB
C++
191 lines
12 KiB
C++
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc %s -verify -DBAD_CONVERSION
|
|
// RUN: %clang_cc1 -fsyntax-only -triple i386-windows-pc %s -verify -DBAD_CONVERSION -DWIN32
|
|
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc %s -ast-dump | FileCheck %s --check-prefixes=CHECK,LIN64,NODEF
|
|
// RUN: %clang_cc1 -fsyntax-only -triple i386-windows-pc %s -ast-dump -DWIN32 | FileCheck %s --check-prefixes=CHECK,WIN32,NODEF
|
|
|
|
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc -fdefault-calling-conv=vectorcall %s -verify -DBAD_VEC_CONVERS
|
|
// RUN: %clang_cc1 -fsyntax-only -triple x86_64-linux-pc -fdefault-calling-conv=vectorcall %s -ast-dump | FileCheck %s --check-prefixes=CHECK,VECTDEF
|
|
|
|
void useage() {
|
|
auto normal = [](int, float, double) {}; // #1
|
|
auto vectorcall = [](int, float, double) __attribute__((vectorcall)){}; // #2
|
|
#ifdef WIN32
|
|
auto thiscall = [](int, float, double) __attribute__((thiscall)){}; // #3
|
|
#endif // WIN32
|
|
auto cdecl = [](int, float, double) __attribute__((cdecl)){};
|
|
|
|
auto genericlambda = [](auto a) {}; // #4
|
|
auto genericvectorcalllambda = [](auto a) __attribute__((vectorcall)){}; // #5
|
|
|
|
// None of these should be ambiguous.
|
|
(void)+normal;
|
|
(void)+vectorcall;
|
|
#ifdef WIN32
|
|
(void)+thiscall;
|
|
#endif // WIN32
|
|
(void)+cdecl;
|
|
|
|
#ifdef BAD_CONVERSION
|
|
// expected-error-re@+1 {{invalid argument type {{.*}} to unary expression}}
|
|
(void)+genericlambda;
|
|
// expected-error-re@+1 {{invalid argument type {{.*}} to unary expression}}
|
|
(void)+genericvectorcalllambda;
|
|
#endif // BAD_CONVERSION
|
|
|
|
// CHECK: VarDecl {{.*}} normal '
|
|
// CHECK: LambdaExpr
|
|
// WIN32: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((thiscall)) const'
|
|
// LIN64: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
|
|
// VECTDEF: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
|
|
// NODEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
|
|
// NODEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
|
|
// VECTDEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
|
|
// VECTDEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
|
|
|
|
// CHECK: VarDecl {{.*}} vectorcall '
|
|
// CHECK: LambdaExpr
|
|
// CHECK: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((vectorcall)) const'
|
|
// CHECK: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
|
|
// CHECK: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
|
|
|
|
// WIN32: VarDecl {{.*}} thiscall '
|
|
// WIN32: LambdaExpr
|
|
// WIN32: CXXMethodDecl {{.*}} operator() 'void (int, float, double) __attribute__((thiscall)) const'
|
|
// WIN32: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
|
|
// WIN32: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
|
|
|
|
// CHECK: VarDecl {{.*}} cdecl '
|
|
// CHECK: LambdaExpr
|
|
// CHECK: CXXMethodDecl {{.*}} operator() 'void (int, float, double) const'
|
|
// NODEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) 'void
|
|
// NODEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double)' static inline
|
|
// VECTDEF: CXXConversionDecl {{.*}} operator void (*)(int, float, double) __attribute__((vectorcall)) 'void
|
|
// VECTDEF: CXXMethodDecl {{.*}} __invoke 'void (int, float, double) __attribute__((vectorcall))' static inline
|
|
|
|
// CHECK: VarDecl {{.*}} genericlambda '
|
|
// CHECK: LambdaExpr
|
|
//
|
|
// CHECK: FunctionTemplateDecl {{.*}} operator()
|
|
// LIN64: CXXMethodDecl {{.*}} operator() 'auto (auto) const' inline
|
|
// LIN64: CXXMethodDecl {{.*}} operator() 'void (char) const' inline
|
|
// LIN64: CXXMethodDecl {{.*}} operator() 'void (int) const' inline
|
|
// WIN32: CXXMethodDecl {{.*}} operator() 'auto (auto) __attribute__((thiscall)) const' inline
|
|
// WIN32: CXXMethodDecl {{.*}} operator() 'void (char) __attribute__((thiscall)) const' inline
|
|
// WIN32: CXXMethodDecl {{.*}} operator() 'void (int) __attribute__((thiscall)) const' inline
|
|
//
|
|
// NODEF: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0)
|
|
// VECDEF: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall))
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) 'auto (*() const noexcept)(auto)'
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(char) 'void (*() const noexcept)(char)'
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(int) 'void (*() const noexcept)(int)'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) 'auto (*() __attribute__((thiscall)) const noexcept)(auto)'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) 'void (*() __attribute__((thiscall)) const noexcept)(char)'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) 'void (*() __attribute__((thiscall)) const noexcept)(int)'
|
|
// VECDEF: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() const noexcept)(auto)' __attribute__((vectorcall))
|
|
// VECDEF: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() const noexcept)(char)' __attribute__((vectorcall))
|
|
// VECDEF: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() const noexcept)(int)' __attribute__((vectorcall))
|
|
//
|
|
// CHECK: FunctionTemplateDecl {{.*}} __invoke
|
|
// NODEF: CXXMethodDecl {{.*}} __invoke 'auto (auto)'
|
|
// NODEF: CXXMethodDecl {{.*}} __invoke 'void (char)'
|
|
// NODEF: CXXMethodDecl {{.*}} __invoke 'void (int)'
|
|
// VECDEF: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((vectorcall))'
|
|
// VECDEF: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((vectorcall))'
|
|
// VECDEF: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((vectorcall))'
|
|
//
|
|
// ONLY WIN32 has the duplicate here.
|
|
// WIN32: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((thiscall))
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((thiscall)) 'auto (*() __attribute__((thiscall)) const noexcept)(auto) __attribute__((thiscall))'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((thiscall)) 'void (*() __attribute__((thiscall)) const noexcept)(char) __attribute__((thiscall))'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((thiscall)) 'void (*() __attribute__((thiscall)) const noexcept)(int) __attribute__((thiscall))'
|
|
//
|
|
// WIN32: FunctionTemplateDecl {{.*}} __invoke
|
|
// WIN32: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((thiscall))'
|
|
// WIN32: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((thiscall))'
|
|
// WIN32: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((thiscall))'
|
|
|
|
// CHECK: VarDecl {{.*}} genericvectorcalllambda '
|
|
// CHECK: LambdaExpr
|
|
// CHECK: FunctionTemplateDecl {{.*}} operator()
|
|
// CHECK: CXXMethodDecl {{.*}} operator() 'auto (auto) __attribute__((vectorcall)) const' inline
|
|
// CHECK: CXXMethodDecl {{.*}} operator() 'void (char) __attribute__((vectorcall)) const' inline
|
|
// CHECK: CXXMethodDecl {{.*}} operator() 'void (int) __attribute__((vectorcall)) const' inline
|
|
// CHECK: FunctionTemplateDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall))
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() const noexcept)(auto) __attribute__((vectorcall))'
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() const noexcept)(char) __attribute__((vectorcall))'
|
|
// LIN64: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() const noexcept)(int) __attribute__((vectorcall))'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(type-parameter-0-0) __attribute__((vectorcall)) 'auto (*() __attribute__((thiscall)) const noexcept)(auto) __attribute__((vectorcall))'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(char) __attribute__((vectorcall)) 'void (*() __attribute__((thiscall)) const noexcept)(char) __attribute__((vectorcall))'
|
|
// WIN32: CXXConversionDecl {{.*}} operator auto (*)(int) __attribute__((vectorcall)) 'void (*() __attribute__((thiscall)) const noexcept)(int) __attribute__((vectorcall))'
|
|
// CHECK: FunctionTemplateDecl {{.*}} __invoke
|
|
// CHECK: CXXMethodDecl {{.*}} __invoke 'auto (auto) __attribute__((vectorcall))'
|
|
// CHECK: CXXMethodDecl {{.*}} __invoke 'void (char) __attribute__((vectorcall))'
|
|
// CHECK: CXXMethodDecl {{.*}} __invoke 'void (int) __attribute__((vectorcall))'
|
|
|
|
// NODEF: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
|
|
// NODEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
|
|
// NODEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
|
|
// VECTDEF: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
|
|
// VECTDEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
// VECTDEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
|
|
// CHECK: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
|
|
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
// CHECK-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
|
|
// WIN32: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
|
|
// WIN32-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
|
|
// WIN32-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
|
|
|
|
// NODEF: UnaryOperator {{.*}} 'void (*)(int, float, double)' prefix '+'
|
|
// NODEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double)'
|
|
// NODEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double)'
|
|
// VECTDEF: UnaryOperator {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))' prefix '+'
|
|
// VECTDEF-NEXT: ImplicitCastExpr {{.*}} 'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
// VECTDEF-NEXT: CXXMemberCallExpr {{.*}}'void (*)(int, float, double) __attribute__((vectorcall))'
|
|
|
|
#ifdef BAD_CONVERSION
|
|
// expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double) __attribute__((vectorcall))}}
|
|
// expected-note@#1 {{candidate function}}
|
|
void (*__attribute__((vectorcall)) normal_ptr2)(int, float, double) = normal;
|
|
// expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double)}}
|
|
// expected-note@#2 {{candidate function}}
|
|
void (*vectorcall_ptr2)(int, float, double) = vectorcall;
|
|
#ifdef WIN32
|
|
void (*__attribute__((thiscall)) thiscall_ptr2)(int, float, double) = thiscall;
|
|
#endif // WIN32
|
|
// expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(char) __attribute__((vectorcall))'}}
|
|
// expected-note@#4 {{candidate function}}
|
|
void(__vectorcall * generic_ptr)(char) = genericlambda;
|
|
// expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(char)}}
|
|
// expected-note@#5 {{candidate function}}
|
|
void (*generic_ptr2)(char) = genericvectorcalllambda;
|
|
#endif // BAD_CONVERSION
|
|
|
|
#ifdef BAD_VEC_CONVERS
|
|
void (*__attribute__((vectorcall)) normal_ptr2)(int, float, double) = normal;
|
|
void (*normal_ptr3)(int, float, double) = normal;
|
|
// expected-error-re@+2 {{no viable conversion from {{.*}} to 'void (*)(int, float, double) __attribute__((regcall))}}
|
|
// expected-note@#1 {{candidate function}}
|
|
void (*__attribute__((regcall)) normalptr4)(int, float, double) = normal;
|
|
void (*__attribute__((vectorcall)) vectorcall_ptr2)(int, float, double) = vectorcall;
|
|
void (*vectorcall_ptr3)(int, float, double) = vectorcall;
|
|
#endif // BAD_VEC_CONVERS
|
|
|
|
// Required to force emission of the invoker.
|
|
void (*normal_ptr)(int, float, double) = normal;
|
|
void (*__attribute__((vectorcall)) vectorcall_ptr)(int, float, double) = vectorcall;
|
|
#ifdef WIN32
|
|
void (*thiscall_ptr)(int, float, double) = thiscall;
|
|
#endif // WIN32
|
|
void (*cdecl_ptr)(int, float, double) = cdecl;
|
|
void (*generic_ptr3)(char) = genericlambda;
|
|
void (*generic_ptr4)(int) = genericlambda;
|
|
#ifdef WIN32
|
|
void (*__attribute__((thiscall)) generic_ptr3b)(char) = genericlambda;
|
|
void (*__attribute__((thiscall)) generic_ptr4b)(int) = genericlambda;
|
|
#endif
|
|
void (*__attribute__((vectorcall)) generic_ptr5)(char) = genericvectorcalllambda;
|
|
void (*__attribute__((vectorcall)) generic_ptr6)(int) = genericvectorcalllambda;
|
|
}
|