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