summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2014-08-29 00:16:06 +0000
committerHans Wennborg <hans@hanshq.net>2014-08-29 00:16:06 +0000
commit0a20f5417c9d241f4774a49da6c7ca8123686671 (patch)
tree165bc69420de0451b623942c4778743ffdf060f9 /clang
parent400e725bde52e5107e7394a3d5443ff6742e1325 (diff)
downloadbcm5719-llvm-0a20f5417c9d241f4774a49da6c7ca8123686671.tar.gz
bcm5719-llvm-0a20f5417c9d241f4774a49da6c7ca8123686671.zip
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
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp8
-rw-r--r--clang/test/CodeGen/dllimport.c21
2 files changed, 25 insertions, 4 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 1f0dd73e65b..aaadbd4633c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1449,6 +1449,10 @@ CodeGenModule::GetOrCreateLLVMFunction(StringRef MangledName,
Entry->setLinkage(llvm::Function::ExternalLinkage);
}
+ // Handle dropped DLL attributes.
+ if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>())
+ Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+
if (Entry->getType()->getElementType() == Ty)
return Entry;
@@ -1614,6 +1618,10 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
Entry->setLinkage(llvm::Function::ExternalLinkage);
}
+ // Handle dropped DLL attributes.
+ if (D && !D->hasAttr<DLLImportAttr>() && !D->hasAttr<DLLExportAttr>())
+ Entry->setDLLStorageClass(llvm::GlobalValue::DefaultStorageClass);
+
if (Entry->getType() == Ty)
return Entry;
diff --git a/clang/test/CodeGen/dllimport.c b/clang/test/CodeGen/dllimport.c
index 6ed60ea1e25..0f592d00f53 100644
--- a/clang/test/CodeGen/dllimport.c
+++ b/clang/test/CodeGen/dllimport.c
@@ -44,12 +44,19 @@ __declspec(dllimport) extern int GlobalRedecl3;
extern int GlobalRedecl3; // dllimport ignored
USEVAR(GlobalRedecl3)
+// Make sure this works even if the decl has been used before it's defined (PR20792).
+// CHECK: @GlobalRedecl4 = common global i32
+__declspec(dllimport) extern int GlobalRedecl4;
+USEVAR(GlobalRedecl4)
+ int GlobalRedecl4; // dllimport ignored
+
+
// Redeclaration in local context.
-// CHECK: @GlobalRedecl4 = external dllimport global i32
-__declspec(dllimport) int GlobalRedecl4;
+// CHECK: @GlobalRedecl5 = external dllimport global i32
+__declspec(dllimport) int GlobalRedecl5;
int functionScope() {
- extern int GlobalRedecl4; // still dllimport
- return GlobalRedecl4;
+ extern int GlobalRedecl5; // still dllimport
+ return GlobalRedecl5;
}
@@ -99,3 +106,9 @@ USE(redecl2)
__declspec(dllimport) void redecl3(void);
void redecl3(void) {} // dllimport ignored
USE(redecl3)
+
+// Make sure this works even if the decl is used before it's defined (PR20792).
+// CHECK-DAG: define void @redecl4()
+__declspec(dllimport) void redecl4(void);
+USE(redecl4)
+ void redecl4(void) {} // dllimport ignored
OpenPOWER on IntegriCloud