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).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@144056 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index 848e079..92b0534 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -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() {
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 746b094..d6e263b 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -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);
diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp
index bba949b..8481c8a 100644
--- a/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/test/SemaCXX/constant-expression-cxx11.cpp
@@ -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) {}
+ }
+};
+
+}
diff --git a/test/SemaCXX/constant-expression.cpp b/test/SemaCXX/constant-expression.cpp
index e3f45c5..2d2f1ae 100644
--- a/test/SemaCXX/constant-expression.cpp
+++ b/test/SemaCXX/constant-expression.cpp
@@ -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}}
+}