[cfe-commits] r150793 - in /cfe/trunk: lib/CodeGen/CGDecl.cpp lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h test/CodeGenCXX/static-mutable.cpp
Richard Smith
richard-llvm at metafoo.co.uk
Thu Feb 16 22:48:11 PST 2012
Author: rsmith
Date: Fri Feb 17 00:48:11 2012
New Revision: 150793
URL: http://llvm.org/viewvc/llvm-project?rev=150793&view=rev
Log:
Bug fix: do not emit static const local variables with mutable members
as constants.
Refactor and simplify all the separate checks for whether a type can be
emitted as a constant.
Added:
cfe/trunk/test/CodeGenCXX/static-mutable.cpp
Modified:
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=150793&r1=150792&r2=150793&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Fri Feb 17 00:48:11 2012
@@ -255,14 +255,13 @@
OldGV->eraseFromParent();
}
+ GV->setConstant(CGM.isTypeConstant(D.getType(), true));
GV->setInitializer(Init);
if (hasNontrivialDestruction(D.getType())) {
// We have a constant initializer, but a nontrivial destructor. We still
// need to perform a guarded "initialization" in order to register the
- // destructor. Since we're running a destructor on this variable, it can't
- // be a constant even if it's const.
- GV->setConstant(false);
+ // destructor.
EmitCXXGuardedInit(D, GV, /*PerformInit*/false);
}
@@ -775,7 +774,7 @@
// If this value is a POD array or struct with a statically
// determinable constant initializer, there are optimizations we can do.
//
- // TODO: we should constant-evaluate any variable of literal type
+ // TODO: We should constant-evaluate the initializer of any variable,
// as long as it is initialized by a constant expression. Currently,
// isConstantInitializer produces wrong answers for structs with
// reference or bitfield members, and a few other cases, and checking
@@ -789,17 +788,13 @@
// If the variable's a const type, and it's neither an NRVO
// candidate nor a __block variable and has no mutable members,
// emit it as a global instead.
- if (CGM.getCodeGenOpts().MergeAllConstants && Ty.isConstQualified() &&
- !NRVO && !isByRef && Ty->isLiteralType()) {
- CXXRecordDecl *RD =
- Ty->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
- if (!RD || !RD->hasMutableFields()) {
- EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
-
- emission.Address = 0; // signal this condition to later callbacks
- assert(emission.wasEmittedAsGlobal());
- return emission;
- }
+ if (CGM.getCodeGenOpts().MergeAllConstants && !NRVO && !isByRef &&
+ CGM.isTypeConstant(Ty, true)) {
+ EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
+
+ emission.Address = 0; // signal this condition to later callbacks
+ assert(emission.wasEmittedAsGlobal());
+ return emission;
}
// Otherwise, tell the initialization code that we're in this case.
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=150793&r1=150792&r2=150793&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Feb 17 00:48:11 2012
@@ -1101,18 +1101,23 @@
ExtraAttrs);
}
-static bool DeclIsConstantGlobal(ASTContext &Context, const VarDecl *D,
- bool ConstantInit) {
- if (!D->getType().isConstant(Context) && !D->getType()->isReferenceType())
+/// isTypeConstant - Determine whether an object of this type can be emitted
+/// as a constant.
+///
+/// If ExcludeCtor is true, the duration when the object's constructor runs
+/// will not be considered. The caller will need to verify that the object is
+/// not written to during its construction.
+bool CodeGenModule::isTypeConstant(QualType Ty, bool ExcludeCtor) {
+ if (!Ty.isConstant(Context) && !Ty->isReferenceType())
return false;
-
+
if (Context.getLangOptions().CPlusPlus) {
- if (const RecordType *Record
- = Context.getBaseElementType(D->getType())->getAs<RecordType>())
- return ConstantInit &&
- !cast<CXXRecordDecl>(Record->getDecl())->hasMutableFields();
+ if (const CXXRecordDecl *Record
+ = Context.getBaseElementType(Ty)->getAsCXXRecordDecl())
+ return ExcludeCtor && !Record->hasMutableFields() &&
+ Record->hasTrivialDestructor();
}
-
+
return true;
}
@@ -1169,7 +1174,7 @@
if (D) {
// FIXME: This code is overly simple and should be merged with other global
// handling.
- GV->setConstant(DeclIsConstantGlobal(Context, D, false));
+ GV->setConstant(isTypeConstant(D->getType(), false));
// Set linkage and visibility in case we never see a definition.
NamedDecl::LinkageInfo LV = D->getLinkageAndVisibility();
@@ -1450,13 +1455,11 @@
GV->setInitializer(Init);
// If it is safe to mark the global 'constant', do so now.
- GV->setConstant(false);
- if (!NeedsGlobalCtor && !NeedsGlobalDtor &&
- DeclIsConstantGlobal(Context, D, true))
- GV->setConstant(true);
+ GV->setConstant(!NeedsGlobalCtor && !NeedsGlobalDtor &&
+ isTypeConstant(D->getType(), true));
GV->setAlignment(getContext().getDeclAlign(D).getQuantity());
-
+
// Set the llvm linkage type as appropriate.
llvm::GlobalValue::LinkageTypes Linkage =
GetLLVMLinkageVarDefinition(D, GV);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=150793&r1=150792&r2=150793&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Feb 17 00:48:11 2012
@@ -448,6 +448,8 @@
llvm::MDNode *getTBAAInfo(QualType QTy);
+ bool isTypeConstant(QualType QTy, bool ExcludeCtorDtor);
+
static void DecorateInstruction(llvm::Instruction *Inst,
llvm::MDNode *TBAAInfo);
Added: cfe/trunk/test/CodeGenCXX/static-mutable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/static-mutable.cpp?rev=150793&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/static-mutable.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/static-mutable.cpp Fri Feb 17 00:48:11 2012
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 %s -triple=i686-linux-gnu -emit-llvm -o - | FileCheck %s
+
+struct S {
+ mutable int n;
+};
+int f() {
+ // The purpose of this test is to ensure that this variable is a global
+ // not a constant.
+ // CHECK: @_ZZ1fvE1s = internal global {{.*}} { i32 12 }
+ static const S s = { 12 };
+ return ++s.n;
+}
More information about the cfe-commits
mailing list