Skip to content

Commit 0a20f54

Browse files
committed
Better codegen support for DLL attributes being dropped after the first declaration (PR20792)
For the following code: __declspec(dllimport) int f(int x); int user(int x) { return f(x); } int f(int x) { return 1; } Clang will drop the dllimport attribute in the AST, but CodeGen would have already put it on the LLVM::Function, and that would never get updated. (The same thing happens for global variables.) This makes Clang check dropped DLL attribute case each time the LLVM object is referenced. This isn't perfect, because we will still get it wrong if the function is never referenced by codegen after the attribute is dropped, but this handles the common cases and makes us not fail in the verifier. llvm-svn: 216699
1 parent 400e725 commit 0a20f54

File tree

2 files changed

+25
-4
lines changed

2 files changed

+25
-4
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,10 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
14491449
Entry->setLinkage(llvm::Function::ExternalLinkage);
14501450
}
14511451

1452+
// Handle dropped DLL attributes.
1453+
if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>())
1454+
Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1455+
14521456
if (Entry->getType()->getElementType() == Ty)
14531457
return Entry;
14541458

@@ -1614,6 +1618,10 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
16141618
Entry->setLinkage(llvm::Function::ExternalLinkage);
16151619
}
16161620

1621+
// Handle dropped DLL attributes.
1622+
if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>())
1623+
Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
1624+
16171625
if (Entry->getType() == Ty)
16181626
return Entry;
16191627

clang/test/CodeGen/dllimport.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,19 @@ __declspec(dllimport) extern int GlobalRedecl3;
4444
extern int GlobalRedecl3; // dllimport ignored
4545
USEVAR(GlobalRedecl3)
4646

47+
// Make sure this works even if the decl has been used before it's defined (PR20792).
48+
// CHECK: @GlobalRedecl4 = common global i32
49+
__declspec(dllimport) extern int GlobalRedecl4;
50+
USEVAR(GlobalRedecl4)
51+
int GlobalRedecl4; // dllimport ignored
52+
53+
4754
// Redeclaration in local context.
48-
// CHECK: @GlobalRedecl4 = external dllimport global i32
49-
__declspec(dllimport) int GlobalRedecl4;
55+
// CHECK: @GlobalRedecl5 = external dllimport global i32
56+
__declspec(dllimport) int GlobalRedecl5;
5057
int functionScope() {
51-
extern int GlobalRedecl4; // still dllimport
52-
return GlobalRedecl4;
58+
extern int GlobalRedecl5; // still dllimport
59+
return GlobalRedecl5;
5360
}
5461

5562

@@ -99,3 +106,9 @@ USE(redecl2)
99106
__declspec(dllimport) void redecl3(void);
100107
void redecl3(void) {} // dllimport ignored
101108
USE(redecl3)
109+
110+
// Make sure this works even if the decl is used before it's defined (PR20792).
111+
// CHECK-DAG: define void @redecl4()
112+
__declspec(dllimport) void redecl4(void);
113+
USE(redecl4)
114+
void redecl4(void) {} // dllimport ignored

0 commit comments

Comments
 (0)