]> granicus.if.org Git - clang/commitdiff
Allow constexpr variables' initializers to be folded in C++11 mode. This
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 7 Nov 2011 03:22:51 +0000 (03:22 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 7 Nov 2011 03:22:51 +0000 (03:22 +0000)
partially undoes the revert in r143491, but does not introduce any new instances
of the underlying issue (which is not yet fixed) in code which does not use
the 'constexpr' keyword.

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

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

index 9c9e473f7b5af460bd0a5f3ab72d85f8cc8ed111..6456376d48f64e3b2131ead65f51c4a76fc3d2e5 100644 (file)
@@ -558,12 +558,14 @@ bool HandleLValueToRValueConversion(EvalInfo &Info, QualType Type,
     // them are not permitted.
     const VarDecl *VD = dyn_cast<VarDecl>(D);
     QualType VT = VD->getType();
-    if (!VD)
+    if (!VD || VD->isInvalidDecl())
       return false;
     if (!isa<ParmVarDecl>(VD)) {
       if (!IsConstNonVolatile(VT))
         return false;
-      if (!VT->isIntegralOrEnumerationType() && !VT->isRealFloatingType())
+      // FIXME: Allow folding of values of any literal type in all languages.
+      if (!VT->isIntegralOrEnumerationType() && !VT->isRealFloatingType() &&
+          !VD->isConstexpr())
         return false;
     }
     if (!EvaluateVarDeclInit(Info, VD, Frame, RVal))
index 782b6a1d5b2afbeefc5c02eeb1745541bb867a33..92159a7b6a2c544208ca1141d77d9161b68ec688 100644 (file)
@@ -135,7 +135,6 @@ namespace ParameterScopes {
 
 }
 
-#if 0
 namespace Pointers {
 
   constexpr int f(int n, const int *a, const int *b, const int *c) {
@@ -165,10 +164,9 @@ namespace FunctionPointers {
 
   static_assert_fold(1 + Apply(Select(4), 5) + Apply(Select(3), 7) == 42, "");
 
-  constexpr int Invalid = Apply(Select(0), 0); // xpected-error {{must be initialized by a constant expression}}
+  constexpr int Invalid = Apply(Select(0), 0); // expected-error {{must be initialized by a constant expression}}
 
 }
-#endif
 
 namespace PointerComparison {
 
@@ -211,12 +209,10 @@ static_assert_fold(&x >= &x, "");
 static_assert_fold(&x < &x, "false"); // expected-error {{false}}
 static_assert_fold(&x > &x, "false"); // expected-error {{false}}
 
-#if 0
 constexpr S* sptr = &s;
 // FIXME: This is not a constant expression; check we reject this and move this
 // test elsewhere.
 constexpr bool dyncast = sptr == dynamic_cast<S*>(sptr);
-#endif
 
 extern char externalvar[];
 // FIXME: This is not a constant expression; check we reject this and move this