]> granicus.if.org Git - clang/commitdiff
Treat list-initialization of scalars as a first-class citizen in C++11.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 24 Sep 2011 17:48:14 +0000 (17:48 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Sat, 24 Sep 2011 17:48:14 +0000 (17:48 +0000)
Allow empty initializer lists for scalars, which mean value-initialization.
Constant evaluation for single-element and empty initializer lists for scalars.
Codegen for empty initializer lists for scalars.
Test case comes in next commit.

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

lib/AST/ExprConstant.cpp
lib/CodeGen/CGExprScalar.cpp
lib/Sema/SemaInit.cpp
test/CodeGenCXX/cxx0x-initializer-scalars.cpp [new file with mode: 0644]

index 2de72f392e0689d18d4aa71cb243dbcc1fd4992b..524afb11b6a44f2e57e2efebf989a154345337a9 100644 (file)
@@ -484,6 +484,13 @@ public:
       return Visit(E->getSubExpr());
     }
   }
+
+  bool VisitInitListExpr(const InitListExpr *E) {
+    if (Info.Ctx.getLangOptions().CPlusPlus0x && E->getNumInits() == 1)
+      return Visit(E->getInit(0));
+    return Error(E);
+  }
+
   // FIXME: Missing: __real__, __imag__
 
 };
@@ -1079,7 +1086,9 @@ public:
 
   bool VisitCXXNoexceptExpr(const CXXNoexceptExpr *E);
   bool VisitSizeOfPackExpr(const SizeOfPackExpr *E);
-    
+
+  bool VisitInitListExpr(const InitListExpr *E);
+
 private:
   CharUnits GetAlignOfExpr(const Expr *E);
   CharUnits GetAlignOfType(QualType T);
@@ -1932,6 +1941,17 @@ bool IntExprEvaluator::VisitCXXNoexceptExpr(const CXXNoexceptExpr *E) {
   return Success(E->getValue(), E);
 }
 
+bool IntExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+  if (!Info.Ctx.getLangOptions().CPlusPlus0x)
+    return Error(E);
+
+  if (E->getNumInits() == 0)
+    return Success(0, E);
+
+  assert(E->getNumInits() == 1 && "Excess initializers for integer in C++11.");
+  return Visit(E->getInit(0));
+}
+
 //===----------------------------------------------------------------------===//
 // Float Evaluation
 //===----------------------------------------------------------------------===//
@@ -1965,6 +1985,8 @@ public:
 
   bool VisitDeclRefExpr(const DeclRefExpr *E);
 
+  bool VisitInitListExpr(const InitListExpr *E);
+
   // FIXME: Missing: array subscript of vector, member of vector,
   //                 ImplicitValueInitExpr
 };
@@ -2233,6 +2255,19 @@ bool FloatExprEvaluator::VisitCXXScalarValueInitExpr(const CXXScalarValueInitExp
   return true;
 }
 
+bool FloatExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
+  if (!Info.Ctx.getLangOptions().CPlusPlus0x)
+    return Error(E);
+
+  if (E->getNumInits() == 0) {
+    Result = APFloat::getZero(Info.Ctx.getFloatTypeSemantics(E->getType()));
+    return true;
+  }
+
+  assert(E->getNumInits() == 1 && "Excess initializers for integer in C++11.");
+  return Visit(E->getInit(0));
+}
+
 //===----------------------------------------------------------------------===//
 // Complex Evaluation (for float and integer)
 //===----------------------------------------------------------------------===//
@@ -2264,7 +2299,7 @@ public:
 
   bool VisitBinaryOperator(const BinaryOperator *E);
   bool VisitUnaryOperator(const UnaryOperator *E);
-  // FIXME Missing: ImplicitValueInitExpr
+  // FIXME Missing: ImplicitValueInitExpr, InitListExpr
 };
 } // end anonymous namespace
 
@@ -2766,7 +2801,6 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
   case Expr::CompoundAssignOperatorClass:
   case Expr::CompoundLiteralExprClass:
   case Expr::ExtVectorElementExprClass:
-  case Expr::InitListExprClass:
   case Expr::DesignatedInitExprClass:
   case Expr::ImplicitValueInitExprClass:
   case Expr::ParenListExprClass:
@@ -2813,6 +2847,17 @@ static ICEDiag CheckICE(const Expr* E, ASTContext &Ctx) {
   case Expr::MaterializeTemporaryExprClass:
     return ICEDiag(2, E->getLocStart());
 
+  case Expr::InitListExprClass:
+    if (Ctx.getLangOptions().CPlusPlus0x) {
+      const InitListExpr *ILE = cast<InitListExpr>(E);
+      if (ILE->getNumInits() == 0)
+        return NoDiag();
+      if (ILE->getNumInits() == 1)
+        return CheckICE(ILE->getInit(0), Ctx);
+      // Fall through for more than 1 expression.
+    }
+    return ICEDiag(2, E->getLocStart());
+
   case Expr::SizeOfPackExprClass:
   case Expr::GNUNullExprClass:
     // GCC considers the GNU __null value to be an integral constant expression.
index 264a71403abfdf3178e9ca8ba7a67de863dbf2b8..c2f871334f8dfb4896b3c445a3fdd74223d3f8c2 100644 (file)
@@ -837,9 +837,14 @@ Value *ScalarExprEmitter::VisitInitListExpr(InitListExpr *E) {
   llvm::VectorType *VType =
     dyn_cast<llvm::VectorType>(ConvertType(E->getType()));
   
-  // We have a scalar in braces. Just use the first element.
-  if (!VType)
+  if (!VType) {
+    if (NumInitElements == 0) {
+      // C++11 value-initialization for the scalar.
+      return EmitNullValue(E->getType());
+    }
+    // We have a scalar in braces. Just use the first element.
     return Visit(E->getInit(0));
+  }
   
   unsigned ResElts = VType->getNumElements();
   
index 7c27e6fbae08024b0f14a7a820a9cf27237a7bdb..2e4b2362b1f60f63ec49fecb9acadafcc3ba090e 100644 (file)
@@ -877,11 +877,12 @@ void InitListChecker::CheckScalarType(const InitializedEntity &Entity,
                                       InitListExpr *StructuredList,
                                       unsigned &StructuredIndex) {
   if (Index >= IList->getNumInits()) {
-    // FIXME: Allowed in C++11.
-    if (!VerifyOnly)
-      SemaRef.Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
-        << IList->getSourceRange();
-    hadError = true;
+    if (!SemaRef.getLangOptions().CPlusPlus0x) {
+      if (!VerifyOnly)
+        SemaRef.Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
+          << IList->getSourceRange();
+      hadError = true;
+    }
     ++Index;
     ++StructuredIndex;
     return;
diff --git a/test/CodeGenCXX/cxx0x-initializer-scalars.cpp b/test/CodeGenCXX/cxx0x-initializer-scalars.cpp
new file mode 100644 (file)
index 0000000..a951dd1
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++0x -S -emit-llvm -o - %s | FileCheck %s
+
+void f()
+{
+  // CHECK: store i32 0
+  int i{};
+}