[cfe-commits] r144056 - in /cfe/trunk: lib/AST/Expr.cpp lib/AST/ExprConstant.cpp test/SemaCXX/constant-expression-cxx11.cpp test/SemaCXX/constant-expression.cpp

Richard Smith richard-llvm at metafoo.co.uk
Mon Nov 7 17:31:09 PST 2011


Author: rsmith
Date: Mon Nov  7 19:31:09 2011
New Revision: 144056

URL: http://llvm.org/viewvc/llvm-project?rev=144056&view=rev
Log:
Fix a cluster of related issues involving value-dependence and constant
expression evaluation:
 - When folding a non-value-dependent expression, we may try to use the
   initializer of a value-dependent variable. If that happens, give up.
 - In C++98, actually check that a const, non-volatile DeclRefExpr inside an ICE
   is of integral or enumeration type (a reference isn't OK!)
 - In C++11, DeclRefExprs for objects of const literal type initialized with
   value-dependent expressions are themselves value-dependent.
 - So are references initialized with value-dependent expressions (though this
   case is missing from the C++11 standard, along with many others).

Modified:
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/ExprConstant.cpp
    cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
    cfe/trunk/test/SemaCXX/constant-expression.cpp

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=144056&r1=144055&r2=144056&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Mon Nov  7 19:31:09 2011
@@ -185,21 +185,29 @@
   
   //  (VD) - a constant with integral or enumeration type and is
   //         initialized with an expression that is value-dependent.
+  //  (VD) - a constant with literal type and is initialized with an
+  //         expression that is value-dependent [C++11].
+  //  (VD) - FIXME: Missing from the standard:
+  //       -  an entity with reference type and is initialized with an
+  //          expression that is value-dependent [C++11]
   if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
-    if (Var->getType()->isIntegralOrEnumerationType() &&
-        Var->getType().getCVRQualifiers() == Qualifiers::Const) {
+    if ((D->getASTContext().getLangOptions().CPlusPlus0x ?
+           Var->getType()->isLiteralType() :
+           Var->getType()->isIntegralOrEnumerationType()) &&
+        (Var->getType().getCVRQualifiers() == Qualifiers::Const ||
+         Var->getType()->isReferenceType())) {
       if (const Expr *Init = Var->getAnyInitializer())
         if (Init->isValueDependent()) {
           ValueDependent = true;
           InstantiationDependent = true;
         }
-    } 
-    
+    }
+
     // (VD) - FIXME: Missing from the standard: 
     //      -  a member function or a static data member of the current 
     //         instantiation
-    else if (Var->isStaticDataMember() && 
-             Var->getDeclContext()->isDependentContext()) {
+    if (Var->isStaticDataMember() && 
+        Var->getDeclContext()->isDependentContext()) {
       ValueDependent = true;
       InstantiationDependent = true;
     }
@@ -213,8 +221,7 @@
   if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) {
     ValueDependent = true;
     InstantiationDependent = true;
-    return;
-  }  
+  }
 }
 
 void DeclRefExpr::computeDependence() {

Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=144056&r1=144055&r2=144056&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Mon Nov  7 19:31:09 2011
@@ -552,7 +552,7 @@
     return false;
 
   const Expr *Init = VD->getAnyInitializer();
-  if (!Init)
+  if (!Init || Init->isValueDependent())
     return false;
 
   if (APValue *V = VD->getEvaluatedValue()) {
@@ -3640,6 +3640,9 @@
       //   A variable of non-volatile const-qualified integral or enumeration
       //   type initialized by an ICE can be used in ICEs.
       if (const VarDecl *Dcl = dyn_cast<VarDecl>(D)) {
+        if (!Dcl->getType()->isIntegralOrEnumerationType())
+          return ICEDiag(2, cast<DeclRefExpr>(E)->getLocation());
+
         // Look for a declaration of this variable that has an initializer.
         const VarDecl *ID = 0;
         const Expr *Init = Dcl->getAnyInitializer(ID);

Modified: cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp?rev=144056&r1=144055&r2=144056&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression-cxx11.cpp Mon Nov  7 19:31:09 2011
@@ -322,3 +322,18 @@
 static_assert_fold(**(**(zs + 1) + 1) == 11, "");
 
 }
+
+namespace DependentValues {
+
+struct I { int n; typedef I V[10]; };
+I::V x, y;
+template<bool B> struct S {
+  int k;
+  void f() {
+    I::V &cells = B ? x : y;
+    I &i = cells[k];
+    switch (i.n) {}
+  }
+};
+
+}

Modified: cfe/trunk/test/SemaCXX/constant-expression.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constant-expression.cpp?rev=144056&r1=144055&r2=144056&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constant-expression.cpp (original)
+++ cfe/trunk/test/SemaCXX/constant-expression.cpp Mon Nov  7 19:31:09 2011
@@ -95,3 +95,10 @@
       ;
   }
 }
+
+namespace IntOrEnum {
+  const int k = 0;
+  const int &p = k;
+  template<int n> struct S {};
+  S<p> s; // expected-error {{not an integral constant expression}}
+}





More information about the cfe-commits mailing list