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