1 // RUN: %clang_cc1 -triple i686-win32 -fsyntax-only -fms-extensions -verify -std=c99 -DMS %s 2 // RUN: %clang_cc1 -triple x86_64-win32 -fsyntax-only -fms-extensions -verify -std=c11 -DMS %s 3 // RUN: %clang_cc1 -triple i686-mingw32 -fsyntax-only -fms-extensions -verify -std=c11 -DGNU %s 4 // RUN: %clang_cc1 -triple x86_64-mingw32 -fsyntax-only -fms-extensions -verify -std=c99 -DGNU %s 5 // RUN: %clang_cc1 -triple aarch64-win32 -fsyntax-only -fms-extensions -verify -std=c99 -DMS %s 6 // RUN: %clang_cc1 -triple i686-windows-itanium -fsyntax-only -fms-extensions -verify -std=c99 -DWI %s 7 // RUN: %clang_cc1 -triple x86_64-windows-itanium -fsyntax-only -fms-extensions -verify -std=c11 -DWI %s 8 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fms-extensions -verify -std=c11 -DWI %s 9 // RUN: %clang_cc1 -triple x86_64-scei-ps4 -fsyntax-only -fms-extensions -verify -std=c99 -DWI %s 10 11 // Invalid usage. 12 __declspec(dllimport) typedef int typedef1; 13 // expected-warning@-1{{'dllimport' attribute only applies to functions, variables, classes, and Objective-C interfaces}} 14 typedef __declspec(dllimport) int typedef2; 15 // expected-warning@-1{{'dllimport' attribute only applies to}} 16 typedef int __declspec(dllimport) typedef3; 17 // expected-warning@-1{{'dllimport' attribute only applies to}} 18 typedef __declspec(dllimport) void (*FunTy)(); 19 // expected-warning@-1{{'dllimport' attribute only applies to}} 20 enum __declspec(dllimport) Enum { EnumVal }; 21 // expected-warning@-1{{'dllimport' attribute only applies to}} 22 struct __declspec(dllimport) Record {}; 23 // expected-warning@-1{{'dllimport' attribute only applies to}} 24 25 26 27 //===----------------------------------------------------------------------===// 28 // Globals 29 //===----------------------------------------------------------------------===// 30 31 // Import declaration. 32 __declspec(dllimport) extern int ExternGlobalDecl; 33 34 // dllimport implies a declaration. 35 __declspec(dllimport) int GlobalDecl; 36 int **__attribute__((dllimport))* GlobalDeclChunkAttr; 37 int GlobalDeclAttr __attribute__((dllimport)); 38 39 // Address of variables can't be used for initialization in C language modes. 40 int *VarForInit = &GlobalDecl; // expected-error{{initializer element is not a compile-time constant}} 41 42 // Not allowed on definitions. 43 __declspec(dllimport) extern int ExternGlobalInit = 1; // expected-error{{definition of dllimport data}} 44 __declspec(dllimport) int GlobalInit1 = 1; // expected-error{{definition of dllimport data}} 45 int __declspec(dllimport) GlobalInit2 = 1; // expected-error{{definition of dllimport data}} 46 47 // Declare, then reject definition. 48 #ifdef GNU 49 // expected-note@+2{{previous attribute is here}} 50 #endif 51 __declspec(dllimport) extern int ExternGlobalDeclInit; // expected-note{{previous declaration is here}} 52 #if defined(MS) || defined(WI) 53 // expected-warning@+4{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 54 #else 55 // expected-warning@+2{{'ExternGlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 56 #endif 57 int ExternGlobalDeclInit = 1; 58 59 #ifdef GNU 60 // expected-note@+2{{previous attribute is here}} 61 #endif 62 __declspec(dllimport) int GlobalDeclInit; // expected-note{{previous declaration is here}} 63 #if defined(MS) || defined(WI) 64 // expected-warning@+4{{'GlobalDeclInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 65 #else 66 // expected-warning@+2{{'GlobalDeclInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 67 #endif 68 int GlobalDeclInit = 1; 69 70 #ifdef GNU 71 // expected-note@+2{{previous attribute is here}} 72 #endif 73 int *__attribute__((dllimport)) GlobalDeclChunkAttrInit; // expected-note{{previous declaration is here}} 74 #if defined(MS) || defined(WI) 75 // expected-warning@+4{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 76 #else 77 // expected-warning@+2{{'GlobalDeclChunkAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 78 #endif 79 int *GlobalDeclChunkAttrInit = 0; 80 81 #ifdef GNU 82 // expected-note@+2{{previous attribute is here}} 83 #endif 84 int GlobalDeclAttrInit __attribute__((dllimport)); // expected-note{{previous declaration is here}} 85 #if defined(MS) || defined(WI) 86 // expected-warning@+4{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 87 #else 88 // expected-warning@+2{{'GlobalDeclAttrInit' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 89 #endif 90 int GlobalDeclAttrInit = 1; 91 92 // Redeclarations 93 __declspec(dllimport) extern int GlobalRedecl1; 94 __declspec(dllimport) extern int GlobalRedecl1; 95 96 __declspec(dllimport) int GlobalRedecl2a; 97 __declspec(dllimport) int GlobalRedecl2a; 98 99 int *__attribute__((dllimport)) GlobalRedecl2b; 100 int *__attribute__((dllimport)) GlobalRedecl2b; 101 102 int GlobalRedecl2c __attribute__((dllimport)); 103 int GlobalRedecl2c __attribute__((dllimport)); 104 105 // We follow GCC and drop the dllimport with a warning. 106 __declspec(dllimport) extern int GlobalRedecl3; // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 107 extern int GlobalRedecl3; // expected-warning{{'GlobalRedecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 108 109 // Adding an attribute on redeclaration. 110 extern int GlobalRedecl4; // expected-note{{previous declaration is here}} useGlobalRedecl4()111int useGlobalRedecl4() { return GlobalRedecl4; } 112 __declspec(dllimport) extern int GlobalRedecl4; // expected-error{{redeclaration of 'GlobalRedecl4' cannot add 'dllimport' attribute}} 113 114 // Allow with a warning if the decl hasn't been used yet. 115 extern int GlobalRedecl5; // expected-note{{previous declaration is here}} 116 __declspec(dllimport) extern int GlobalRedecl5; // expected-warning{{redeclaration of 'GlobalRedecl5' should not add 'dllimport' attribute}} 117 118 119 // External linkage is required. 120 __declspec(dllimport) static int StaticGlobal; // expected-error{{'StaticGlobal' must have external linkage when declared 'dllimport'}} 121 122 // Thread local variables are invalid. 123 __declspec(dllimport) __thread int ThreadLocalGlobal; // expected-error{{'ThreadLocalGlobal' cannot be thread local when declared 'dllimport'}} 124 125 // Import in local scope. 126 __declspec(dllimport) float LocalRedecl1; // expected-note{{previous declaration is here}} 127 __declspec(dllimport) float LocalRedecl2; // expected-note{{previous declaration is here}} 128 __declspec(dllimport) float LocalRedecl3; // expected-note{{previous declaration is here}} 129 __declspec(dllimport) float LocalRedecl4; functionScope()130void functionScope() { 131 __declspec(dllimport) int LocalRedecl1; // expected-error{{redeclaration of 'LocalRedecl1' with a different type: 'int' vs 'float'}} 132 int *__attribute__((dllimport)) LocalRedecl2; // expected-error{{redeclaration of 'LocalRedecl2' with a different type: 'int *' vs 'float'}} 133 int LocalRedecl3 __attribute__((dllimport)); // expected-error{{redeclaration of 'LocalRedecl3' with a different type: 'int' vs 'float'}} 134 135 __declspec(dllimport) int LocalVarDecl; 136 __declspec(dllimport) int LocalVarDef = 1; // expected-error{{definition of dllimport data}} 137 __declspec(dllimport) extern int ExternLocalVarDecl; 138 __declspec(dllimport) extern int ExternLocalVarDef = 1; // expected-error{{definition of dllimport data}} 139 __declspec(dllimport) static int StaticLocalVar; // expected-error{{'StaticLocalVar' must have external linkage when declared 'dllimport'}} 140 141 // Local extern redeclaration does not drop the attribute. 142 extern float LocalRedecl4; 143 } 144 145 146 147 //===----------------------------------------------------------------------===// 148 // Functions 149 //===----------------------------------------------------------------------===// 150 151 // Import function declaration. Check different placements. 152 __attribute__((dllimport)) void decl1A(); // Sanity check with __attribute__ 153 __declspec(dllimport) void decl1B(); 154 155 void __attribute__((dllimport)) decl2A(); 156 void __declspec(dllimport) decl2B(); 157 158 // Address of functions can be used for initialization in C language modes. 159 // However, the address of the thunk wrapping the function is used instead of 160 // the address in the import address table. 161 void (*FunForInit)() = &decl2A; 162 163 // Not allowed on function definitions. def()164__declspec(dllimport) void def() {} // expected-error{{dllimport cannot be applied to non-inline function definition}} 165 166 // Import inline function. 167 #ifdef GNU 168 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 169 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 170 #endif inlineFunc1()171__declspec(dllimport) inline void inlineFunc1() {} inlineFunc2()172inline void __attribute__((dllimport)) inlineFunc2() {} 173 174 // Redeclarations 175 __declspec(dllimport) void redecl1(); 176 __declspec(dllimport) void redecl1(); 177 178 __declspec(dllimport) void redecl2(); // expected-note{{previous declaration is here}} expected-note{{previous attribute is here}} 179 void redecl2(); // expected-warning{{'redecl2' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 180 181 #ifdef GNU 182 // expected-note@+2{{previous attribute is here}} 183 #endif 184 __declspec(dllimport) void redecl3(); // expected-note{{previous declaration is here}} 185 // NB: Both MSVC and Clang issue a warning and make redecl3 dllexport. 186 #if defined(MS) || defined(WI) 187 // expected-warning@+4{{'redecl3' redeclared without 'dllimport' attribute: 'dllexport' attribute added}} 188 #else 189 // expected-warning@+2{{'redecl3' redeclared without 'dllimport' attribute: previous 'dllimport' ignored}} 190 #endif redecl3()191 void redecl3() {} 192 193 void redecl4(); // expected-note{{previous declaration is here}} useRedecl4()194void useRedecl4() { redecl4(); } 195 __declspec(dllimport) void redecl4(); // expected-warning{{redeclaration of 'redecl4' should not add 'dllimport' attribute}} 196 197 // Allow with a warning if the decl hasn't been used yet. 198 void redecl5(); // expected-note{{previous declaration is here}} 199 __declspec(dllimport) void redecl5(); // expected-warning{{redeclaration of 'redecl5' should not add 'dllimport' attribute}} 200 201 202 // Inline redeclarations. 203 #ifdef GNU 204 // expected-warning@+3{{'redecl6' redeclared inline; 'dllimport' attribute ignored}} 205 #endif 206 __declspec(dllimport) void redecl6(); redecl6()207 inline void redecl6() {} 208 209 #if defined(MS) || defined (WI) 210 // expected-note@+5{{previous declaration is here}} 211 // expected-warning@+5{{redeclaration of 'redecl7' should not add 'dllimport' attribute}} 212 #else 213 // expected-warning@+3{{'dllimport' attribute ignored on inline function}} 214 #endif 215 void redecl7(); redecl7()216__declspec(dllimport) inline void redecl7() {} 217 218 // PR31069: Don't crash trying to merge attributes for redeclaration of invalid 219 // decl. 220 void __declspec(dllimport) redecl8(unknowntype X); // expected-error{{unknown type name 'unknowntype'}} redecl8(unknowntype X)221void redecl8(unknowntype X) { } // expected-error{{unknown type name 'unknowntype'}} 222 // PR32021: Similarly, don't crash trying to merge attributes from a valid 223 // decl to an invalid redeclaration. 224 void __declspec(dllimport) redecl9(void); // expected-note{{previous declaration is here}} redecl9(void)225int redecl9(void) {} // expected-error{{conflicting types for 'redecl9'}} 226 227 // External linkage is required. 228 __declspec(dllimport) static int staticFunc(); // expected-error{{'staticFunc' must have external linkage when declared 'dllimport'}} 229 230 // Static locals don't count as having external linkage. staticLocalFunc()231void staticLocalFunc() { 232 __declspec(dllimport) static int staticLocal; // expected-error{{'staticLocal' must have external linkage when declared 'dllimport'}} 233 } 234