When constant-folding, don't look at the initializer of a global const variable

if it's marked as weak: that definition may not end up being used.

llvm-svn: 143496
This commit is contained in:
Richard Smith 2011-11-01 21:06:14 +00:00
parent 1f1f2d8ca3
commit cecf184e64
2 changed files with 15 additions and 5 deletions

View File

@ -270,16 +270,17 @@ static bool IsLiteralLValue(const LValue &Value) {
!isa<MaterializeTemporaryExpr>(Value.Base);
}
static bool IsWeakLValue(const LValue &Value) {
const ValueDecl *Decl = GetLValueBaseDecl(Value);
if (!Decl)
return false;
static bool IsWeakDecl(const ValueDecl *Decl) {
return Decl->hasAttr<WeakAttr>() ||
Decl->hasAttr<WeakRefAttr>() ||
Decl->isWeakImported();
}
static bool IsWeakLValue(const LValue &Value) {
const ValueDecl *Decl = GetLValueBaseDecl(Value);
return Decl && IsWeakDecl(Decl);
}
static bool EvalPointerValueAsBool(const LValue &Value, bool &Result) {
const Expr* Base = Value.Base;
@ -394,6 +395,11 @@ static bool EvaluateVarDeclInit(EvalInfo &Info, const VarDecl *VD,
return true;
}
// Never evaluate the initializer of a weak variable. We can't be sure that
// this is the definition which will be used.
if (IsWeakDecl(VD))
return false;
const Expr *Init = VD->getAnyInitializer();
if (!Init)
return false;

View File

@ -95,3 +95,7 @@ int intLvalue[*(int*)((long)&n ?: 1)] = { 1, 2 }; // expected-error {{variable l
union u { int a; char b[4]; };
char c = ((union u)(123456)).b[0]; // expected-error {{not a compile-time constant}}
extern const int weak_int __attribute__((weak));
const int weak_int = 42;
int weak_int_test = weak_int; // expected-error {{not a compile-time constant}}