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