]> granicus.if.org Git - clang/commitdiff
Convert initializer lists to temporaries in CreateBuiltinBinOp. Allows assignment...
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 27 Feb 2012 20:34:02 +0000 (20:34 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 27 Feb 2012 20:34:02 +0000 (20:34 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151551 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/CXX/expr/expr.ass/p9-cxx11.cpp

index 10ae8f4badbf1418c8bd9a39c773dc9eea618e0c..30a02b2953946997a4166c5d4748d6153f2a4f4c 100644 (file)
@@ -7612,6 +7612,25 @@ static void DiagnoseSelfAssignment(Sema &S, Expr *LHSExpr, Expr *RHSExpr,
 ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc,
                                     BinaryOperatorKind Opc,
                                     Expr *LHSExpr, Expr *RHSExpr) {
+  if (getLangOptions().CPlusPlus0x && isa<InitListExpr>(RHSExpr)) {
+    // The syntax only allows initializer lists on the RHS of assignment,
+    // so we don't need to worry about accepting invalid code for
+    // non-assignment operators.
+    // C++11 5.17p9:
+    //   The meaning of x = {v} [...] is that of x = T(v) [...]. The meaning
+    //   of x = {} is x = T().
+    InitializationKind Kind =
+        InitializationKind::CreateDirectList(RHSExpr->getLocStart());
+    InitializedEntity Entity =
+        InitializedEntity::InitializeTemporary(LHSExpr->getType());
+    InitializationSequence InitSeq(*this, Entity, Kind, &RHSExpr, 1);
+    ExprResult Init = InitSeq.Perform(*this, Entity, Kind,
+                                      MultiExprArg(&RHSExpr, 1));
+    if (Init.isInvalid())
+      return Init;
+    RHSExpr = Init.take();
+  }
+
   ExprResult LHS = Owned(LHSExpr), RHS = Owned(RHSExpr);
   QualType ResultTy;     // Result type of the binary operator.
   // The following two variables are used for compound assignment operators
index fcef97cde5b96fe0d095a228d6c461d4dc1f5966..bd1603d6ab6773142403f932377b15f00d1ed700 100644 (file)
@@ -11,10 +11,9 @@ void std_example() {
   z = { 1, 2 };
   z += { 1, 2 };
 
-  // FIXME: implement semantics of scalar init list assignment.
   int a, b;
-  a = b = { 1 }; // unexpected-error {{incompatible type 'void'}}
-  a = { 1 } = b; // unexpected-error {{incompatible type 'void'}}
+  a = b = { 1 };
+  a = { 1 } = b;
 }
 
 struct S {