brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.4 KiB · b399d8e Raw
266 lines · cpp
1// RUN: %clang_cc1 -std=c++14 -triple i686-pc-win32 -fms-extensions -DMSABI -verify %s2// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -verify %s3// RUN: %clang_cc1 -std=c++14 -triple i686-pc-mingw32 -fms-extensions -verify %s4 5typedef void void_fun_t();6typedef void __cdecl cdecl_fun_t();7 8// Pointers to free functions9void            free_func_default(); // expected-note 2 {{previous declaration is here}}10void __cdecl    free_func_cdecl(); // expected-note 2 {{previous declaration is here}}11void __stdcall  free_func_stdcall(); // expected-note 2 {{previous declaration is here}}12void __fastcall free_func_fastcall(); // expected-note 2 {{previous declaration is here}}13void __vectorcall free_func_vectorcall(); // expected-note 2 {{previous declaration is here}}14 15void __cdecl    free_func_default();16void __stdcall  free_func_default(); // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}17void __fastcall free_func_default(); // expected-error {{function declared 'fastcall' here was previously declared without calling convention}}18 19void            free_func_cdecl();20void __stdcall  free_func_cdecl(); // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}21void __fastcall free_func_cdecl(); // expected-error {{function declared 'fastcall' here was previously declared 'cdecl'}}22 23void            free_func_stdcall();24void __cdecl    free_func_stdcall(); // expected-error {{function declared 'cdecl' here was previously declared 'stdcall'}}25void __fastcall free_func_stdcall(); // expected-error {{function declared 'fastcall' here was previously declared 'stdcall'}}26 27void __cdecl    free_func_fastcall(); // expected-error {{function declared 'cdecl' here was previously declared 'fastcall'}}28void __stdcall  free_func_fastcall(); // expected-error {{function declared 'stdcall' here was previously declared 'fastcall'}}29void            free_func_fastcall();30 31void __cdecl    free_func_vectorcall(); // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}}32void __stdcall  free_func_vectorcall(); // expected-error {{function declared 'stdcall' here was previously declared 'vectorcall'}}33void            free_func_vectorcall();34 35// Overloaded functions may have different calling conventions36void __fastcall free_func_default(int);37void __cdecl    free_func_default(int *);38 39void __thiscall free_func_cdecl(char *);40void __cdecl    free_func_cdecl(double);41 42typedef void void_fun_t();43typedef void __cdecl cdecl_fun_t();44 45// Pointers to member functions46struct S {47  void            member_default1(); // expected-note {{previous declaration is here}}48  void            member_default2();49  void __cdecl    member_cdecl1();50  void __cdecl    member_cdecl2(); // expected-note {{previous declaration is here}}51  void __thiscall member_thiscall1();52  void __thiscall member_thiscall2(); // expected-note {{previous declaration is here}}53  void __vectorcall member_vectorcall1();54  void __vectorcall member_vectorcall2(); // expected-note {{previous declaration is here}}55 56  // Typedefs carrying the __cdecl convention are adjusted to __thiscall.57  void_fun_t           member_typedef_default; // expected-note {{previous declaration is here}}58  cdecl_fun_t          member_typedef_cdecl1;  // expected-note {{previous declaration is here}}59  cdecl_fun_t __cdecl  member_typedef_cdecl2;60  void_fun_t __stdcall member_typedef_stdcall;61 62  // Static member functions can't be __thiscall63  static void            static_member_default1();64  static void            static_member_default2();65  static void            static_member_default3(); // expected-note {{previous declaration is here}}66  static void __cdecl    static_member_cdecl1();67  static void __cdecl    static_member_cdecl2(); // expected-note {{previous declaration is here}}68  static void __stdcall  static_member_stdcall1();69  static void __stdcall  static_member_stdcall2();70 71  // Variadic functions can't be other than default or __cdecl72  void            member_variadic_default(int x, ...);73  void __cdecl    member_variadic_cdecl(int x, ...);74 75  static void            static_member_variadic_default(int x, ...);76  static void __cdecl    static_member_variadic_cdecl(int x, ...);77 78  // Structors can't be other than default in MS ABI environment79#ifdef MSABI80  __vectorcall S(); // expected-warning {{vectorcall calling convention is not supported on constructor/destructor}}81#endif82};83 84void __cdecl    S::member_default1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}85void __thiscall S::member_default2() {}86 87void __cdecl   S::member_typedef_default() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}88void __cdecl   S::member_typedef_cdecl1() {} // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}89void __cdecl   S::member_typedef_cdecl2() {}90void __stdcall S::member_typedef_stdcall() {}91 92void            S::member_cdecl1() {}93void __thiscall S::member_cdecl2() {} // expected-error {{function declared 'thiscall' here was previously declared 'cdecl'}}94 95void            S::member_thiscall1() {}96void __cdecl    S::member_thiscall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'thiscall'}}97 98void            S::member_vectorcall1() {}99void __cdecl    S::member_vectorcall2() {} // expected-error {{function declared 'cdecl' here was previously declared 'vectorcall'}}100 101void            S::static_member_default1() {}102void __cdecl    S::static_member_default2() {}103void __stdcall  S::static_member_default3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}104 105void            S::static_member_cdecl1() {}106void __stdcall  S::static_member_cdecl2() {} // expected-error {{function declared 'stdcall' here was previously declared 'cdecl'}}107 108void __cdecl    S::member_variadic_default(int x, ...) { (void)x; }109void            S::member_variadic_cdecl(int x, ...) { (void)x; }110 111void __cdecl    S::static_member_variadic_default(int x, ...) { (void)x; }112void            S::static_member_variadic_cdecl(int x, ...) { (void)x; }113 114// Declare a template using a calling convention.115template <class CharT> inline int __cdecl mystrlen(const CharT *str) {116  int i;117  for (i = 0; str[i]; i++) { }118  return i;119}120extern int sse_strlen(const char *str);121template <> inline int __cdecl mystrlen(const char *str) {122  return sse_strlen(str);123}124void use_tmpl(const char *str, const int *ints) {125  mystrlen(str);126  mystrlen(ints);127}128 129struct MixedCCStaticOverload {130  static void overloaded(int a);131  static void __stdcall overloaded(short a);132};133 134void MixedCCStaticOverload::overloaded(int a) {}135void MixedCCStaticOverload::overloaded(short a) {}136 137// Friend function decls are cdecl by default, not thiscall.  Friend method138// decls should always be redeclarations, because the class cannot be139// incomplete.140struct FriendClass {141  void friend_method() {}142};143void __stdcall friend_stdcall1() {}144class MakeFriendDecls {145  int x;146  friend void FriendClass::friend_method();147  friend void              friend_default();148  friend void              friend_stdcall1();149  friend void __stdcall    friend_stdcall2();150  friend void              friend_stdcall3(); // expected-note {{previous declaration is here}}151};152void           friend_default() {}153void __stdcall friend_stdcall3() {} // expected-error {{function declared 'stdcall' here was previously declared without calling convention}}154void __stdcall friend_stdcall2() {}155 156// Test functions with multiple attributes.157void __attribute__((noreturn)) __stdcall __attribute__((regparm(1))) multi_attribute(int x);158void multi_attribute(int x) { __builtin_unreachable(); }159 160 161// expected-error@+3 {{vectorcall and cdecl attributes are not compatible}}162// expected-error@+2 {{stdcall and cdecl attributes are not compatible}}163// expected-error@+1 {{fastcall and cdecl attributes are not compatible}}164void __cdecl __cdecl __stdcall __cdecl __fastcall __vectorcall multi_cc(int x);165 166template <typename T> void __stdcall StdcallTemplate(T) {}167template <> void StdcallTemplate<int>(int) {}168template <> void __stdcall StdcallTemplate<short>(short) {}169 170// FIXME: Note the template, not the implicit instantiation.171// expected-error@+2 {{function declared 'cdecl' here was previously declared 'stdcall}}172// expected-note@+1 {{previous declaration is here}}173template <> void __cdecl StdcallTemplate<long>(long) {}174 175struct ExactlyInt {176  template <typename T> static int cast_to_int(T) {177    return T::this_is_not_an_int();178  }179};180template <> inline int ExactlyInt::cast_to_int<int>(int x) { return x; }181 182namespace test2 {183  class foo {184    template <typename T> void bar(T v);185  };186  extern template void foo::bar(const void *);187}188 189namespace test3 {190  struct foo {191    typedef void bar();192  };193  bool zed(foo::bar *);194  void bah() {}195  void baz() { zed(bah); }196}197 198namespace test4 {199  class foo {200    template <typename T> static void bar(T v);201  };202  extern template void foo::bar(const void *);203}204 205namespace test5 {206  template <class T>207  class valarray {208    void bar();209  };210  extern template void valarray<int>::bar();211}212 213namespace test6 {214  struct foo {215    int bar();216  };217  typedef int bar_t();218  void zed(bar_t foo::*) {219  }220  void baz() {221    zed(&foo::bar);222  }223}224 225namespace test7 {226  template <typename T>227  struct S {228    void f(T t) {229      t = 42;230    }231  };232  template<> void S<void*>::f(void*);233  void g(S<void*> s, void* p) {234    s.f(p);235  }236}237 238namespace test8 {239  template <typename T>240  struct S {241    void f(T t) { // expected-note {{previous declaration is here}}242      t = 42; // expected-error {{incompatible integer to pointer conversion assigning to 'void *' from 'int'}}243    }244  };245  template<> void __cdecl S<void*>::f(void*); // expected-error {{function declared 'cdecl' here was previously declared without calling convention}}246  void g(S<void*> s, void* p) {247    s.f(p); // expected-note {{in instantiation of member function 'test8::S<void *>::f' requested here}}248  }249}250 251namespace test9 {252  // Used to fail when we forgot to make lambda call operators use __thiscall.253  template <typename F>254  decltype(auto) deduce(F f) {255    return &decltype(f)::operator();256  }257  template <typename C, typename R, typename A>258  decltype(auto) signaturehelper(R (C::*f)(A) const) {259    return R();260  }261  void f() {262    auto l = [](int x) { return x * 2; };263    decltype(signaturehelper(deduce(l))) p;264  }265}266