]> granicus.if.org Git - clang/commitdiff
When constant-folding, don't look at the initializer of a global const variable
authorRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 1 Nov 2011 21:06:14 +0000 (21:06 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Tue, 1 Nov 2011 21:06:14 +0000 (21:06 +0000)
if it's marked as weak: that definition may not end up being used.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@143496 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/const-eval.c

index 4dd49c912503b8d765980087e980a92d2eabe3e3..781ffa6fb4de20ea533f51d47ec5f52cd52d2d40 100644 (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;
index df56b06e48c8185c3138b09c2eb9ad2032121dff..c984f5bf840e755335628ce885ce2f54e6dcc9c6 100644 (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}}