r298676 - Fix handling of initialization from parenthesized initializer list.

Daniel Jasper via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 27 06:53:18 PDT 2017


-Wunused-value is always triggered if a constructor of an object with a
non-trivial destructor has an initializer list as first parameter. So in
the test, even "Used({});" triggers -Wunused-value. That seems inconsistent
(replacing the init list with something else silences the warning) and also
there is a code pattern where this is used to construct and immediately
destruct an object.

On Mon, Mar 27, 2017 at 3:49 PM, Richard Smith <richard at metafoo.co.uk>
wrote:

> What is the effect on that testcase? (Sorry, heading to vacation and can't
> easily check.)
>
> On 27 Mar 2017 6:33 am, "Daniel Jasper" <djasper at google.com> wrote:
>
>> Hi Richard,
>>
>> this seems to have an unwanted side-effect on -Wunused-value (test case
>> attached). Could you take a look?
>>
>> Cheers,
>> Daniel
>>
>> On Fri, Mar 24, 2017 at 2:14 AM, Richard Smith via cfe-commits <
>> cfe-commits at lists.llvm.org> wrote:
>>
>>> Author: rsmith
>>> Date: Thu Mar 23 20:14:25 2017
>>> New Revision: 298676
>>>
>>> URL: http://llvm.org/viewvc/llvm-project?rev=298676&view=rev
>>> Log:
>>> Fix handling of initialization from parenthesized initializer list.
>>>
>>> This change fixes a crash on initialization of a reference from ({})
>>> during
>>> template instantiation and incidentally improves diagnostics.
>>>
>>> This reverts a prior attempt to handle this in r286721. Instead, we
>>> teach the
>>> initialization code that initialization cannot be performed if a source
>>> type
>>> is required and the initializer is an initializer list (which is not an
>>> expression and does not have a type), and likewise for function-style
>>> cast
>>> expressions.
>>>
>>> Modified:
>>>     cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>>     cfe/trunk/include/clang/Sema/Initialization.h
>>>     cfe/trunk/include/clang/Sema/Sema.h
>>>     cfe/trunk/lib/Sema/SemaDecl.cpp
>>>     cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>>     cfe/trunk/lib/Sema/SemaInit.cpp
>>>     cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
>>>     cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
>>>     cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp
>>>     cfe/trunk/test/SemaCXX/type-convert-construct.cpp
>>>
>>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>>> Basic/DiagnosticSemaKinds.td?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
>>> +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Mar 23
>>> 20:14:25 2017
>>> @@ -1814,8 +1814,9 @@ def note_uninit_fixit_remove_cond : Note
>>>    "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 %0 "
>>> -  "must not be parenthesized">;
>>> +def err_list_init_in_parens : Error<
>>> +  "cannot initialize %select{non-class|reference}0 type %1 with a "
>>> +  "parenthesized initializer list">;
>>>
>>>  def warn_unsequenced_mod_mod : Warning<
>>>    "multiple unsequenced modifications to %0">, InGroup<Unsequenced>;
>>> @@ -5865,8 +5866,8 @@ def err_builtin_func_cast_more_than_one_
>>>    "function-style cast to a builtin type can only take one argument">;
>>>  def err_value_init_for_array_type : Error<
>>>    "array types cannot be value-initialized">;
>>> -def err_value_init_for_function_type : Error<
>>> -  "function types cannot be value-initialized">;
>>> +def err_init_for_function_type : Error<
>>> +  "cannot create object of function type %0">;
>>>  def warn_format_nonliteral_noargs : Warning<
>>>    "format string is not a string literal (potentially insecure)">,
>>>    InGroup<FormatSecurity>;
>>>
>>> Modified: cfe/trunk/include/clang/Sema/Initialization.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>>> Sema/Initialization.h?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/include/clang/Sema/Initialization.h (original)
>>> +++ cfe/trunk/include/clang/Sema/Initialization.h Thu Mar 23 20:14:25
>>> 2017
>>> @@ -822,6 +822,8 @@ public:
>>>    enum FailureKind {
>>>      /// \brief Too many initializers provided for a reference.
>>>      FK_TooManyInitsForReference,
>>> +    /// \brief Reference initialized from a parenthesized initializer
>>> list.
>>> +    FK_ParenthesizedListInitForReference,
>>>      /// \brief Array must be initialized with an initializer list.
>>>      FK_ArrayNeedsInitList,
>>>      /// \brief Array must be initialized with an initializer list or a
>>> @@ -866,6 +868,8 @@ public:
>>>      FK_ConversionFromPropertyFailed,
>>>      /// \brief Too many initializers for scalar
>>>      FK_TooManyInitsForScalar,
>>> +    /// \brief Scalar initialized from a parenthesized initializer list.
>>> +    FK_ParenthesizedListInitForScalar,
>>>      /// \brief Reference initialization from an initializer list
>>>      FK_ReferenceBindingToInitList,
>>>      /// \brief Initialization of some unused destination type with an
>>> @@ -892,7 +896,7 @@ public:
>>>      /// having its address taken.
>>>      FK_AddressOfUnaddressableFunction,
>>>      /// \brief List-copy-initialization chose an explicit constructor.
>>> -    FK_ExplicitConstructor
>>> +    FK_ExplicitConstructor,
>>>    };
>>>
>>>  private:
>>>
>>> Modified: cfe/trunk/include/clang/Sema/Sema.h
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/
>>> Sema/Sema.h?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/include/clang/Sema/Sema.h (original)
>>> +++ cfe/trunk/include/clang/Sema/Sema.h Thu Mar 23 20:14:25 2017
>>> @@ -1822,7 +1822,6 @@ public:
>>>    void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit);
>>>    void ActOnUninitializedDecl(Decl *dcl);
>>>    void ActOnInitializerError(Decl *Dcl);
>>> -  bool canInitializeWithParenthesizedList(QualType TargetType);
>>>
>>>    void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc);
>>>    void ActOnCXXForRangeDecl(Decl *D);
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaD
>>> ecl.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Mar 23 20:14:25 2017
>>> @@ -10102,18 +10102,6 @@ void Sema::AddInitializerToDecl(Decl *Re
>>>    // Perform the initialization.
>>>    ParenListExpr *CXXDirectInit = dyn_cast<ParenListExpr>(Init);
>>>    if (!VDecl->isInvalidDecl()) {
>>> -    // Handle errors like: int a({0})
>>> -    if (CXXDirectInit && CXXDirectInit->getNumExprs() == 1 &&
>>> -        !canInitializeWithParenthesizedList(VDecl->getType()))
>>> -      if (auto IList = dyn_cast<InitListExpr>(CXXDirectInit->getExpr(0)))
>>> {
>>> -        Diag(VDecl->getLocation(), diag::err_list_init_in_parens)
>>> -            << VDecl->getType() << CXXDirectInit->getSourceRange()
>>> -            << FixItHint::CreateRemoval(CXXDirectInit->getLocStart())
>>> -            << FixItHint::CreateRemoval(CXXDirectInit->getLocEnd());
>>> -        Init = IList;
>>> -        CXXDirectInit = nullptr;
>>> -      }
>>> -
>>>      InitializedEntity Entity = InitializedEntity::InitializeV
>>> ariable(VDecl);
>>>      InitializationKind Kind = InitializationKind::CreateForInit(
>>>          VDecl->getLocation(), DirectInit, Init);
>>> @@ -10413,18 +10401,6 @@ void Sema::ActOnInitializerError(Decl *D
>>>    // though.
>>>  }
>>>
>>> -/// Checks if an object of the given type can be initialized with
>>> parenthesized
>>> -/// init-list.
>>> -///
>>> -/// \param TargetType Type of object being initialized.
>>> -///
>>> -/// The function is used to detect wrong initializations, such as
>>> 'int({0})'.
>>> -///
>>> -bool Sema::canInitializeWithParenthesizedList(QualType TargetType) {
>>> -  return TargetType->isDependentType() || TargetType->isRecordType() ||
>>> -         TargetType->getContainedAutoType();
>>> -}
>>> -
>>>  void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
>>>    // If there is no declaration, there was an error parsing it. Just
>>> ignore it.
>>>    if (!RealDecl)
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaE
>>> xprCXX.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Mar 23 20:14:25 2017
>>> @@ -1228,17 +1228,6 @@ Sema::ActOnCXXTypeConstructExpr(ParsedTy
>>>    if (!TInfo)
>>>      TInfo = Context.getTrivialTypeSourceInfo(Ty, SourceLocation());
>>>
>>> -  // Handle errors like: int({0})
>>> -  if (exprs.size() == 1 && !canInitializeWithParenthesizedList(Ty) &&
>>> -      LParenLoc.isValid() && RParenLoc.isValid())
>>> -    if (auto IList = dyn_cast<InitListExpr>(exprs[0])) {
>>> -      Diag(TInfo->getTypeLoc().getLocStart(),
>>> diag::err_list_init_in_parens)
>>> -          << Ty << 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
>>> @@ -1295,46 +1284,51 @@ Sema::BuildCXXTypeConstructExpr(TypeSour
>>>    }
>>>
>>>    // C++ [expr.type.conv]p1:
>>> -  // If the expression list is a single expression, the type conversion
>>> -  // expression is equivalent (in definedness, and if defined in
>>> meaning) to the
>>> -  // corresponding cast expression.
>>> -  if (Exprs.size() == 1 && !ListInitialization) {
>>> +  // If the expression list is a parenthesized single expression, the
>>> type
>>> +  // conversion expression is equivalent (in definedness, and if
>>> defined in
>>> +  // meaning) to the corresponding cast expression.
>>> +  if (Exprs.size() == 1 && !ListInitialization &&
>>> +      !isa<InitListExpr>(Exprs[0])) {
>>>      Expr *Arg = Exprs[0];
>>>      return BuildCXXFunctionalCastExpr(TInfo, Ty, LParenLoc, Arg,
>>> RParenLoc);
>>>    }
>>>
>>> -  // C++14 [expr.type.conv]p2: The expression T(), where T is a
>>> -  //   simple-type-specifier or typename-specifier for a non-array
>>> complete
>>> -  //   object type or the (possibly cv-qualified) void type, creates a
>>> prvalue
>>> -  //   of the specified type, whose value is that produced by
>>> value-initializing
>>> -  //   an object of type T.
>>> +  //   For an expression of the form T(), T shall not be an array type.
>>>    QualType ElemTy = Ty;
>>>    if (Ty->isArrayType()) {
>>>      if (!ListInitialization)
>>> -      return ExprError(Diag(TyBeginLoc,
>>> -                            diag::err_value_init_for_array_type) <<
>>> FullRange);
>>> +      return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array
>>> _type)
>>> +                         << FullRange);
>>>      ElemTy = Context.getBaseElementType(Ty);
>>>    }
>>>
>>> -  if (!ListInitialization && Ty->isFunctionType())
>>> -    return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_funct
>>> ion_type)
>>> -                     << FullRange);
>>> -
>>> +  // There doesn't seem to be an explicit rule against this but sanity
>>> demands
>>> +  // we only construct objects with object types.
>>> +  if (Ty->isFunctionType())
>>> +    return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type)
>>> +                       << Ty << FullRange);
>>> +
>>> +  // C++17 [expr.type.conv]p2:
>>> +  //   If the type is cv void and the initializer is (), the expression
>>> is a
>>> +  //   prvalue of the specified type that performs no initialization.
>>>    if (!Ty->isVoidType() &&
>>>        RequireCompleteType(TyBeginLoc, ElemTy,
>>>                            diag::err_invalid_incomplete_type_use,
>>> FullRange))
>>>      return ExprError();
>>>
>>> +  //   Otherwise, the expression is a prvalue of the specified type
>>> whose
>>> +  //   result object is direct-initialized (11.6) with the initializer.
>>>    InitializationSequence InitSeq(*this, Entity, Kind, Exprs);
>>>    ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs);
>>>
>>> -  if (Result.isInvalid() || !ListInitialization)
>>> +  if (Result.isInvalid())
>>>      return Result;
>>>
>>>    Expr *Inner = Result.get();
>>>    if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null<CXXBindTempor
>>> aryExpr>(Inner))
>>>      Inner = BTE->getSubExpr();
>>> -  if (!isa<CXXTemporaryObjectExpr>(Inner)) {
>>> +  if (!isa<CXXTemporaryObjectExpr>(Inner) &&
>>> +      !isa<CXXScalarValueInitExpr>(Inner)) {
>>>      // If we created a CXXTemporaryObjectExpr, that node also
>>> represents the
>>>      // functional cast. Otherwise, create an explicit cast to represent
>>>      // the syntactic form of a functional-style cast that was used here.
>>> @@ -1590,20 +1584,8 @@ Sema::ActOnCXXNew(SourceLocation StartLo
>>>      return ExprError();
>>>
>>>    SourceRange DirectInitRange;
>>> -  if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr>(Initializer))
>>> {
>>> +  if (ParenListExpr *List = dyn_cast_or_null<ParenListExpr
>>> >(Initializer))
>>>      DirectInitRange = List->getSourceRange();
>>> -    // Handle errors like: new int a({0})
>>> -    if (List->getNumExprs() == 1 &&
>>> -        !canInitializeWithParenthesizedList(AllocType))
>>> -      if (auto IList = dyn_cast<InitListExpr>(List->getExpr(0))) {
>>> -        Diag(TInfo->getTypeLoc().getLocStart(),
>>> diag::err_list_init_in_parens)
>>> -            << AllocType << List->getSourceRange()
>>> -            << FixItHint::CreateRemoval(List->getLocStart())
>>> -            << FixItHint::CreateRemoval(List->getLocEnd());
>>> -        DirectInitRange = SourceRange();
>>> -        Initializer = IList;
>>> -      }
>>> -  }
>>>
>>>    return BuildCXXNew(SourceRange(StartLoc, D.getLocEnd()), UseGlobal,
>>>                       PlacementLParen,
>>>
>>> Modified: cfe/trunk/lib/Sema/SemaInit.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaI
>>> nit.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/lib/Sema/SemaInit.cpp (original)
>>> +++ cfe/trunk/lib/Sema/SemaInit.cpp Thu Mar 23 20:14:25 2017
>>> @@ -3112,6 +3112,7 @@ bool InitializationSequence::isAmbiguous
>>>
>>>    switch (getFailureKind()) {
>>>    case FK_TooManyInitsForReference:
>>> +  case FK_ParenthesizedListInitForReference:
>>>    case FK_ArrayNeedsInitList:
>>>    case FK_ArrayNeedsInitListOrStringLiteral:
>>>    case FK_ArrayNeedsInitListOrWideStringLiteral:
>>> @@ -3129,6 +3130,7 @@ bool InitializationSequence::isAmbiguous
>>>    case FK_ConversionFailed:
>>>    case FK_ConversionFromPropertyFailed:
>>>    case FK_TooManyInitsForScalar:
>>> +  case FK_ParenthesizedListInitForScalar:
>>>    case FK_ReferenceBindingToInitList:
>>>    case FK_InitListBadDestinationType:
>>>    case FK_DefaultInitOfConst:
>>> @@ -5179,6 +5181,12 @@ void InitializationSequence::InitializeF
>>>      // (Therefore, multiple arguments are not permitted.)
>>>      if (Args.size() != 1)
>>>        SetFailed(FK_TooManyInitsForReference);
>>> +    // C++17 [dcl.init.ref]p5:
>>> +    //   A reference [...] is initialized by an expression [...] as
>>> follows:
>>> +    // If the initializer is not an expression, presumably we should
>>> reject,
>>> +    // but the standard fails to actually say so.
>>> +    else if (isa<InitListExpr>(Args[0]))
>>> +      SetFailed(FK_ParenthesizedListInitForReference);
>>>      else
>>>        TryReferenceInitialization(S, Entity, Kind, Args[0], *this);
>>>      return;
>>> @@ -5344,11 +5352,16 @@ void InitializationSequence::InitializeF
>>>      return;
>>>    }
>>>
>>> +  assert(Args.size() >= 1 && "Zero-argument case handled above");
>>> +
>>> +  // The remaining cases all need a source type.
>>>    if (Args.size() > 1) {
>>>      SetFailed(FK_TooManyInitsForScalar);
>>>      return;
>>> +  } else if (isa<InitListExpr>(Args[0])) {
>>> +    SetFailed(FK_ParenthesizedListInitForScalar);
>>> +    return;
>>>    }
>>> -  assert(Args.size() == 1 && "Zero-argument case handled above");
>>>
>>>    //    - Otherwise, if the source type is a (possibly cv-qualified)
>>> class
>>>    //      type, conversion functions are considered.
>>> @@ -7389,6 +7402,10 @@ bool InitializationSequence::Diagnose(Se
>>>        S.Diag(Kind.getLocation(), diag::err_reference_has_multip
>>> le_inits)
>>>          << SourceRange(Args.front()->getLocStart(),
>>> Args.back()->getLocEnd());
>>>      break;
>>> +  case FK_ParenthesizedListInitForReference:
>>> +    S.Diag(Kind.getLocation(), diag::err_list_init_in_parens)
>>> +      << 1 << Entity.getType() << Args[0]->getSourceRange();
>>> +    break;
>>>
>>>    case FK_ArrayNeedsInitList:
>>>      S.Diag(Kind.getLocation(), diag::err_array_init_not_init_list) <<
>>> 0;
>>> @@ -7600,6 +7617,11 @@ bool InitializationSequence::Diagnose(Se
>>>      break;
>>>    }
>>>
>>> +  case FK_ParenthesizedListInitForScalar:
>>> +    S.Diag(Kind.getLocation(), diag::err_list_init_in_parens)
>>> +      << 0 << Entity.getType() << Args[0]->getSourceRange();
>>> +    break;
>>> +
>>>    case FK_ReferenceBindingToInitList:
>>>      S.Diag(Kind.getLocation(), diag::err_reference_bind_init_list)
>>>        << DestType.getNonReferenceType() << Args[0]->getSourceRange();
>>> @@ -7782,6 +7804,10 @@ void InitializationSequence::dump(raw_os
>>>        OS << "too many initializers for reference";
>>>        break;
>>>
>>> +    case FK_ParenthesizedListInitForReference:
>>> +      OS << "parenthesized list init for reference";
>>> +      break;
>>> +
>>>      case FK_ArrayNeedsInitList:
>>>        OS << "array requires initializer list";
>>>        break;
>>> @@ -7866,6 +7892,10 @@ void InitializationSequence::dump(raw_os
>>>        OS << "too many initializers for scalar";
>>>        break;
>>>
>>> +    case FK_ParenthesizedListInitForScalar:
>>> +      OS << "parenthesized list init for reference";
>>> +      break;
>>> +
>>>      case FK_ReferenceBindingToInitList:
>>>        OS << "referencing binding to initializer list";
>>>        break;
>>>
>>> Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c
>>> xx0x-initializer-constructor.cpp?rev=298676&r1=298675&r2=298
>>> 676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-constructor.cpp Thu Mar 23
>>> 20:14:25 2017
>>> @@ -173,8 +173,7 @@ namespace objects {
>>>      // invalid
>>>      H h1({1, 2}); // expected-error {{no matching constructor}}
>>>      (void) new H({1, 2}); // expected-error {{no matching constructor}}
>>> -    // FIXME: Bad diagnostic, mentions void type instead of init list.
>>> -    (void) H({1, 2}); // expected-error {{no matching conversion}}
>>> +    (void) H({1, 2}); // expected-error {{no matching constructor}}
>>>
>>>      // valid (by copy constructor).
>>>      H h2({1, nullptr});
>>>
>>> Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c
>>> xx0x-initializer-references.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-references.cpp Thu Mar 23
>>> 20:14:25 2017
>>> @@ -71,10 +71,22 @@ namespace reference {
>>>      static_assert(sizeof(h({1, 2})) == sizeof(two), "bad overload
>>> resolution");
>>>    }
>>>
>>> +  struct X {};
>>> +
>>>    void edge_cases() {
>>> -    int const &b({0}); // expected-error {{list-initializer for
>>> non-class type 'const int &' must not be parenthesized}}
>>> -    const int (&arr)[3] ({1, 2, 3}); // expected-error
>>> {{list-initializer for non-class type 'const int (&)[3]' must not be
>>> parenthesized}}
>>> +    int const &b({0}); // expected-error {{cannot initialize reference
>>> type 'const int &' with a parenthesized initializer list}}
>>> +    const int (&arr)[3] ({1, 2, 3}); // expected-error {{cannot
>>> initialize reference type 'const int (&)[3]' with a parenthesized
>>> initializer list}}
>>> +    const X &x({}); // expected-error {{cannot initialize reference
>>> type 'const reference::X &' with a parenthesized initializer list}}
>>> +  }
>>> +
>>> +  template<typename T> void dependent_edge_cases() {
>>> +    T b({}); // expected-error-re 3{{cannot initialize reference type
>>> {{.*}} with a parenthesized init}}
>>> +    T({}); // expected-error-re 3{{cannot initialize reference type
>>> {{.*}} with a parenthesized init}}
>>>    }
>>> +  template void dependent_edge_cases<X>(); // ok
>>> +  template void dependent_edge_cases<const int&>(); // expected-note
>>> {{instantiation of}}
>>> +  template void dependent_edge_cases<const int(&)[1]>(); //
>>> expected-note {{instantiation of}}
>>> +  template void dependent_edge_cases<const X&>(); // expected-note
>>> {{instantiation of}}
>>>  }
>>>
>>>  namespace PR12182 {
>>>
>>> Modified: cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/c
>>> xx0x-initializer-scalars.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/cxx0x-initializer-scalars.cpp Thu Mar 23
>>> 20:14:25 2017
>>> @@ -91,13 +91,13 @@ namespace integral {
>>>    }
>>>
>>>    void edge_cases() {
>>> -    int a({0}); // expected-error {{list-initializer for non-class type
>>> 'int' must not be parenthesized}}
>>> -    (void) int({0}); // expected-error {{list-initializer for non-class
>>> type 'int' must not be parenthesized}}
>>> -    new int({0});  // expected-error {{list-initializer for non-class
>>> type 'int' must not be parenthesized}}
>>> +    int a({0}); // expected-error {{cannot initialize non-class type
>>> 'int' with a parenthesized initializer list}}
>>> +    (void) int({0}); // expected-error {{cannot initialize non-class
>>> type 'int' with a parenthesized initializer list}}
>>> +    new int({0});  // expected-error {{cannot initialize non-class type
>>> 'int' with a parenthesized initializer list}}
>>>
>>> -    int *b({0});  // expected-error {{list-initializer for non-class
>>> type 'int *' must not be parenthesized}}
>>> +    int *b({0});  // expected-error {{cannot initialize non-class type
>>> 'int *' with a parenthesized initializer list}}
>>>      typedef int *intptr;
>>> -    int *c = intptr({0});  // expected-error {{list-initializer for
>>> non-class type 'intptr' (aka 'int *') must not be parenthesized}}
>>> +    int *c = intptr({0});  // expected-error {{cannot initialize
>>> non-class type 'intptr' (aka 'int *') with a parenthesized initializer
>>> list}}
>>>    }
>>>
>>>    template<typename T> void dependent_edge_cases() {
>>>
>>> Modified: cfe/trunk/test/SemaCXX/type-convert-construct.cpp
>>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/t
>>> ype-convert-construct.cpp?rev=298676&r1=298675&r2=298676&view=diff
>>> ============================================================
>>> ==================
>>> --- cfe/trunk/test/SemaCXX/type-convert-construct.cpp (original)
>>> +++ cfe/trunk/test/SemaCXX/type-convert-construct.cpp Thu Mar 23
>>> 20:14:25 2017
>>> @@ -8,7 +8,15 @@ void f() {
>>>    typedef int arr[];
>>>    int v3 = arr(); // expected-error {{array types cannot be
>>> value-initialized}}
>>>    typedef void fn_ty();
>>> -  fn_ty(); // expected-error {{function types cannot be
>>> value-initialized}}
>>> +  fn_ty(); // expected-error {{cannot create object of function type
>>> 'fn_ty'}}
>>> +  fn_ty(0); // expected-error {{functional-style cast from 'int' to
>>> 'fn_ty'}}
>>> +  fn_ty(0, 0); // expected-error {{cannot create object of function
>>> type 'fn_ty'}}
>>> +#if __cplusplus >= 201103L
>>> +  fn_ty{}; // expected-error {{cannot create object of function type
>>> 'fn_ty'}}
>>> +  fn_ty{0}; // expected-error {{cannot create object of function type
>>> 'fn_ty'}}
>>> +  fn_ty{0, 0}; // expected-error {{cannot create object of function
>>> type 'fn_ty'}}
>>> +  fn_ty({}); // expected-error {{cannot create object of function type
>>> 'fn_ty'}}
>>> +#endif
>>>    int v4 = int();
>>>    int v5 = int; // expected-error {{expected '(' for function-style
>>> cast or type construction}}
>>>    typedef int T;
>>>
>>>
>>> _______________________________________________
>>> cfe-commits mailing list
>>> cfe-commits at lists.llvm.org
>>> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170327/9f66c3a7/attachment-0001.html>


More information about the cfe-commits mailing list