Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -1759,6 +1759,8 @@ "remove the %select{'%1' if its condition|condition if it}0 " "is always %select{false|true}2">; def err_init_incomplete_type : Error<"initialization of incomplete type %0">; +def err_list_init_in_parens : Error<"list-initializer for non-class type " + "must not be parenthesized">; def warn_unsequenced_mod_mod : Warning< "multiple unsequenced modifications to %0">, InGroup; Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -1799,6 +1799,7 @@ bool TypeMayContainAuto); void ActOnUninitializedDecl(Decl *dcl, bool TypeMayContainAuto); void ActOnInitializerError(Decl *Dcl); + bool cannotBeInitializededByParenthzedList(QualType TargetType); void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc); void ActOnCXXForRangeDecl(Decl *D); StmtResult ActOnCXXForRangeIdentifier(Scope *S, SourceLocation IdentLoc, Index: lib/Sema/SemaDecl.cpp =================================================================== --- lib/Sema/SemaDecl.cpp +++ lib/Sema/SemaDecl.cpp @@ -9788,6 +9788,18 @@ // Perform the initialization. ParenListExpr *CXXDirectInit = dyn_cast(Init); if (!VDecl->isInvalidDecl()) { + // Handle errors like: int a({0}) + if (CXXDirectInit && CXXDirectInit->getNumExprs() == 1 && + cannotBeInitializededByParenthzedList(VDecl->getType())) + if (auto IList = dyn_cast(CXXDirectInit->getExpr(0))) { + Diag(VDecl->getLocation(), diag::err_list_init_in_parens) + << CXXDirectInit->getSourceRange() + << FixItHint::CreateRemoval(CXXDirectInit->getLocStart()) + << FixItHint::CreateRemoval(CXXDirectInit->getLocEnd()); + Init = IList; + CXXDirectInit = nullptr; + } + InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); InitializationKind Kind = DirectInit @@ -10094,6 +10106,11 @@ // though. } +bool Sema::cannotBeInitializededByParenthzedList(QualType TargetType) { + return !TargetType->isDependentType() && !TargetType->isRecordType() && + !TargetType->getContainedAutoType(); +} + void Sema::ActOnUninitializedDecl(Decl *RealDecl, bool TypeMayContainAuto) { // If there is no declaration, there was an error parsing it. Just ignore it. Index: lib/Sema/SemaExprCXX.cpp =================================================================== --- lib/Sema/SemaExprCXX.cpp +++ lib/Sema/SemaExprCXX.cpp @@ -1221,6 +1221,17 @@ if (!TInfo) TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation()); + // Handle errors like: int({0}) + if (exprs.size() == 1 && cannotBeInitializededByParenthzedList(Ty) && + LParenLoc.isValid() && RParenLoc.isValid()) + if (auto IList = dyn_cast(exprs[0])) { + Diag(TInfo->getTypeLoc().getLocStart(), diag::err_list_init_in_parens) + << IList->getSourceRange() + << FixItHint::CreateRemoval(LParenLoc) + << FixItHint::CreateRemoval(RParenLoc); + LParenLoc = RParenLoc = SourceLocation(); + } + auto Result = BuildCXXTypeConstructExpr(TInfo, LParenLoc, exprs, RParenLoc); // Avoid creating a non-type-dependent expression that contains typos. // Non-type-dependent expressions are liable to be discarded without @@ -1562,8 +1573,20 @@ return ExprError(); SourceRange DirectInitRange; - if (ParenListExpr *List = dyn_cast_or_null(Initializer)) + if (ParenListExpr *List = dyn_cast_or_null(Initializer)) { DirectInitRange = List->getSourceRange(); + // Handle errors like: new int a({0}) + if (List->getNumExprs() == 1 && + cannotBeInitializededByParenthzedList(AllocType)) + if (auto IList = dyn_cast(List->getExpr(0))) { + Diag(TInfo->getTypeLoc().getLocStart(), diag::err_list_init_in_parens) + << List->getSourceRange() + << FixItHint::CreateRemoval(List->getLocStart()) + << FixItHint::CreateRemoval(List->getLocEnd()); + DirectInitRange = SourceRange(); + Initializer = IList; + } + } return BuildCXXNew(SourceRange(StartLoc, D.getLocEnd()), UseGlobal, PlacementLParen, Index: test/SemaCXX/cxx0x-initializer-references.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-references.cpp +++ test/SemaCXX/cxx0x-initializer-references.cpp @@ -72,10 +72,9 @@ } void edge_cases() { - // FIXME: very poor error message - int const &b({0}); // expected-error {{could not bind}} + int const &b({0}); // expected-error {{list-initializer for non-class type must not be parenthesized}} + const int (&arr)[3] ({1, 2, 3}); // expected-error {{list-initializer for non-class type must not be parenthesized}} } - } namespace PR12182 { Index: test/SemaCXX/cxx0x-initializer-scalars.cpp =================================================================== --- test/SemaCXX/cxx0x-initializer-scalars.cpp +++ test/SemaCXX/cxx0x-initializer-scalars.cpp @@ -91,10 +91,9 @@ } void edge_cases() { - // FIXME: very poor error message - int a({0}); // expected-error {{cannot initialize}} - (void) int({0}); // expected-error {{functional-style cast}} - new int({0}); // expected-error {{cannot initialize}} + int a({0}); // expected-error {{list-initializer for non-class type must not be parenthesized}} + (void) int({0}); // expected-error {{list-initializer for non-class type must not be parenthesized}} + new int({0}); // expected-error {{list-initializer for non-class type must not be parenthesized}} } void default_argument(int i = {}) {