From: Sebastian Redl Date: Mon, 27 Feb 2012 20:34:02 +0000 (+0000) Subject: Convert initializer lists to temporaries in CreateBuiltinBinOp. Allows assignment... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0d8ab2ed4b7555b6fde965238222e5099614d7bb;p=clang Convert initializer lists to temporaries in CreateBuiltinBinOp. Allows assignment of init lists to built-in types and resolves PR12088. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151551 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 10ae8f4bad..30a02b2953 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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(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 diff --git a/test/CXX/expr/expr.ass/p9-cxx11.cpp b/test/CXX/expr/expr.ass/p9-cxx11.cpp index fcef97cde5..bd1603d6ab 100644 --- a/test/CXX/expr/expr.ass/p9-cxx11.cpp +++ b/test/CXX/expr/expr.ass/p9-cxx11.cpp @@ -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 {