summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2014-08-05 00:01:13 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2014-08-05 00:01:13 +0000
commitc017d3613e2ae3a4f589642734d5fc9f39cf5ad4 (patch)
treec564ce989e7db93f49b5429c1518c3744968a4cc /clang
parent755ffa9b5478c8227cc45cf3aecd5cd47ea7924b (diff)
downloadbcm5719-llvm-c017d3613e2ae3a4f589642734d5fc9f39cf5ad4.tar.gz
bcm5719-llvm-c017d3613e2ae3a4f589642734d5fc9f39cf5ad4.zip
MS ABI: Aligned tentative definitions don't have CommonLinkage
int __declspec(align(16)) foo; is a tentative definition but the storage for that variable should not have CommonLinkage. llvm-svn: 214828
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp12
-rw-r--r--clang/test/CodeGen/ms-align-tentative.c15
2 files changed, 25 insertions, 2 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 54c32200f52..5040965161c 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1951,7 +1951,8 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
DI->EmitGlobalVariable(GV, D);
}
-static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
+static bool isVarDeclStrongDefinition(const ASTContext &Context,
+ const VarDecl *D, bool NoCommon) {
// Don't give variables common linkage if -fno-common was specified unless it
// was overridden by a NoCommon attribute.
if ((NoCommon || D->hasAttr<NoCommonAttr>()) && !D->hasAttr<CommonAttr>())
@@ -1976,6 +1977,12 @@ static bool isVarDeclStrongDefinition(const VarDecl *D, bool NoCommon) {
if (D->hasAttr<WeakImportAttr>())
return true;
+ // Declarations with a required alignment do not have common linakge in MSVC
+ // mode.
+ if (Context.getLangOpts().MSVCCompat &&
+ (Context.isAlignmentRequired(D->getType()) || D->hasAttr<AlignedAttr>()))
+ return true;
+
return false;
}
@@ -2022,7 +2029,8 @@ llvm::GlobalValue::LinkageTypes CodeGenModule::getLLVMLinkageForDeclarator(
// C++ doesn't have tentative definitions and thus cannot have common
// linkage.
if (!getLangOpts().CPlusPlus && isa<VarDecl>(D) &&
- !isVarDeclStrongDefinition(cast<VarDecl>(D), CodeGenOpts.NoCommon))
+ !isVarDeclStrongDefinition(Context, cast<VarDecl>(D),
+ CodeGenOpts.NoCommon))
return llvm::GlobalVariable::CommonLinkage;
// selectany symbols are externally visible, so use weak instead of
diff --git a/clang/test/CodeGen/ms-align-tentative.c b/clang/test/CodeGen/ms-align-tentative.c
new file mode 100644
index 00000000000..ccd76161647
--- /dev/null
+++ b/clang/test/CodeGen/ms-align-tentative.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-compatibility -o - | FileCheck %s
+
+char __declspec(align(8192)) x;
+// CHECK-DAG: @x = global i8 0, align 8192
+
+typedef char __declspec(align(8192)) T;
+T y;
+// CHECK-DAG: @y = global i8 0, align 8192
+
+T __declspec(align(8192)) z;
+// CHECK-DAG: @z = global i8 0, align 8192
+
+int __declspec(align(16)) redef;
+int __declspec(align(32)) redef = 8;
+// CHECK-DAG: @redef = global i32 8, align 32
OpenPOWER on IntegriCloud