]> granicus.if.org Git - clang/commitdiff
PR18283: If a const variable of integral or enumeration type is
authorRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Jan 2014 20:50:08 +0000 (20:50 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Sat, 25 Jan 2014 20:50:08 +0000 (20:50 +0000)
initialized from a constant expression in C++98, it can be used in
constant expressions, even if it was brace-initialized. Patch by
Rahul Jain!

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

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

index 18c3ff1b24af4584fce0b7da55c038e52c3c63a4..9f79064fd77df0f1bd9e571f38386fbdff40c77a 100644 (file)
@@ -8331,10 +8331,20 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
   case Expr::MaterializeTemporaryExprClass:
   case Expr::PseudoObjectExprClass:
   case Expr::AtomicExprClass:
-  case Expr::InitListExprClass:
   case Expr::LambdaExprClass:
     return ICEDiag(IK_NotICE, E->getLocStart());
 
+  case Expr::InitListExprClass: {
+    // C++03 [dcl.init]p13: If T is a scalar type, then a declaration of the
+    // form "T x = { a };" is equivalent to "T x = a;".
+    // Unless we're initializing a reference, T is a scalar as it is known to be
+    // of integral or enumeration type.
+    if (E->isRValue())
+      if (cast<InitListExpr>(E)->getNumInits() == 1)
+        return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
+    return ICEDiag(IK_NotICE, E->getLocStart());
+  }
+
   case Expr::SizeOfPackExprClass:
   case Expr::GNUNullExprClass:
     // GCC considers the GNU __null value to be an integral constant expression.
index 942bf414742b26445e3cf3dfa37954d5a71c4086..2b39de68906e3dda8ffffc62acff4ecec9bda674 100644 (file)
@@ -124,3 +124,12 @@ namespace test3 {
   struct Y { bool b; X x; }; // expected-error {{field has incomplete type 'test3::X'}}
   int f() { return Y().b; }
 }
+
+// PR18283
+namespace test4 {
+  template <int> struct A {};
+  int const i = { 42 };
+  // i can be used as non-type template-parameter as "const int x = { 42 };" is
+  // equivalent to "const int x = 42;" as per C++03 8.5/p13.
+  typedef A<i> Ai; // ok
+}