Fix for PR5714: make sure globals that will be modified aren't marked const.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91156 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 660dd6c..1cfcfb1 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -760,6 +760,17 @@
   return GetOrCreateLLVMFunction(Name, FTy, GlobalDecl());
 }
 
+static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D) {
+  if (!D->getType().isConstant(Context))
+    return false;
+  if (Context.getLangOptions().CPlusPlus &&
+      Context.getBaseElementType(D->getType())->getAs<RecordType>()) {
+    // FIXME: We should do something fancier here!
+    return false;
+  }
+  return true;
+}
+
 /// GetOrCreateLLVMGlobal - If the specified mangled name is not in the module,
 /// create and return an llvm GlobalVariable with the specified type.  If there
 /// is something in the module with the specified name, return it potentially
@@ -803,7 +814,7 @@
   if (D) {
     // FIXME: This code is overly simple and should be merged with other global
     // handling.
-    GV->setConstant(D->getType().isConstant(Context));
+    GV->setConstant(DeclIsConstantGlobal(Context, D));
 
     // FIXME: Merge with other attribute handling code.
     if (D->getStorageClass() == VarDecl::PrivateExtern)
@@ -978,11 +989,8 @@
 
   // If it is safe to mark the global 'constant', do so now.
   GV->setConstant(false);
-  if (D->getType().isConstant(Context)) {
-    // FIXME: In C++, if the variable has a non-trivial ctor/dtor or any mutable
-    // members, it cannot be declared "LLVM const".
+  if (DeclIsConstantGlobal(Context, D))
     GV->setConstant(true);
-  }
 
   GV->setAlignment(getContext().getDeclAlignInBytes(D));
 
diff --git a/test/CodeGenCXX/global-llvm-constant.cpp b/test/CodeGenCXX/global-llvm-constant.cpp
new file mode 100644
index 0000000..bd43196
--- /dev/null
+++ b/test/CodeGenCXX/global-llvm-constant.cpp
@@ -0,0 +1,10 @@
+// RUN: clang-cc -emit-llvm -o - %s | FileCheck %s
+
+struct A {
+  A() { x = 10; }
+  int x;
+};
+
+const A x;
+
+// CHECK: @x = internal global