]> granicus.if.org Git - clang/commitdiff
Fix rejects-valid on constexpr function that accesses a not-yet-defined 'extern
authorRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 25 May 2016 22:06:25 +0000 (22:06 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Wed, 25 May 2016 22:06:25 +0000 (22:06 +0000)
const' variable. That variable might be defined as 'constexpr', so we cannot
prove that a use of it could never be a constant expression.

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

lib/AST/ExprConstant.cpp
test/SemaCXX/constant-expression-cxx11.cpp

index 9b17db6f551a7ee06b73ce2c9c77ebe2f5c0c967..6c8a650967e19fbc426b24f182a97738ad0dd09d 100644 (file)
@@ -2706,7 +2706,11 @@ static CompleteObject findCompleteObject(EvalInfo &Info, const Expr *E,
         }
       } else {
         // FIXME: Allow folding of values of any literal type in all languages.
-        if (Info.getLangOpts().CPlusPlus11) {
+        if (Info.checkingPotentialConstantExpression() &&
+            VD->getType().isConstQualified() && !VD->hasDefinition(Info.Ctx)) {
+          // The definition of this variable could be constexpr. We can't
+          // access it right now, but may be able to in future.
+        } else if (Info.getLangOpts().CPlusPlus11) {
           Info.Diag(E, diag::note_constexpr_ltor_non_constexpr, 1) << VD;
           Info.Note(VD->getLocation(), diag::note_declared_at);
         } else {
@@ -5456,8 +5460,9 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
   }
 
   auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
-  Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
-                   std::distance(RD->field_begin(), RD->field_end()));
+  if (Result.isUninit())
+    Result = APValue(APValue::UninitStruct(), CXXRD ? CXXRD->getNumBases() : 0,
+                     std::distance(RD->field_begin(), RD->field_end()));
   unsigned ElementNo = 0;
   bool Success = true;
 
index 47606b4f0367637943c868a43094a8c564c1a4bb..a755f48048a587f09fc00103390c4ca2aa869c74 100644 (file)
@@ -1181,6 +1181,20 @@ namespace ExternConstexpr {
     constexpr int j = 0;
     constexpr int k; // expected-error {{default initialization of an object of const type}}
   }
+
+  extern const int q;
+  constexpr int g() { return q; }
+  constexpr int q = g();
+  static_assert(q == 0, "zero-initialization should precede static initialization");
+
+  extern int r; // expected-note {{here}}
+  constexpr int h() { return r; } // expected-error {{never produces a constant}} expected-note {{read of non-const}}
+
+  struct S { int n; };
+  extern const S s;
+  constexpr int x() { return s.n; }
+  constexpr S s = {x()};
+  static_assert(s.n == 0, "zero-initialization should precede static initialization");
 }
 
 namespace ComplexConstexpr {