diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
| -rw-r--r-- | lib/Sema/SemaInit.cpp | 372 | 
1 files changed, 210 insertions, 162 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index a65b41fd1cb6..62ab1e645089 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -92,8 +92,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,    if (const IncompleteArrayType *IAT = dyn_cast<IncompleteArrayType>(AT)) {      // C99 6.7.8p14. We have an array of character type with unknown size      // being initialized to a string literal. -    llvm::APSInt ConstVal(32); -    ConstVal = StrLength; +    llvm::APInt ConstVal(32, StrLength);      // Return a new array type (C99 6.7.8p22).      DeclT = S.Context.getConstantArrayType(IAT->getElementType(),                                             ConstVal, @@ -687,22 +686,21 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,    } else if (DeclType->isVectorType()) {      CheckVectorType(Entity, IList, DeclType, Index,                      StructuredList, StructuredIndex); -  } else if (DeclType->isAggregateType()) { -    if (DeclType->isRecordType()) { -      RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl(); -      CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(), -                            SubobjectIsDesignatorContext, Index, -                            StructuredList, StructuredIndex, -                            TopLevelObject); -    } else if (DeclType->isArrayType()) { -      llvm::APSInt Zero( -                      SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()), -                      false); -      CheckArrayType(Entity, IList, DeclType, Zero, -                     SubobjectIsDesignatorContext, Index, -                     StructuredList, StructuredIndex); -    } else -      llvm_unreachable("Aggregate that isn't a structure or array?!"); +  } else if (DeclType->isRecordType()) { +    assert(DeclType->isAggregateType() && +           "non-aggregate records should be handed in CheckSubElementType"); +    RecordDecl *RD = DeclType->getAs<RecordType>()->getDecl(); +    CheckStructUnionTypes(Entity, IList, DeclType, RD->field_begin(), +                          SubobjectIsDesignatorContext, Index, +                          StructuredList, StructuredIndex, +                          TopLevelObject); +  } else if (DeclType->isArrayType()) { +    llvm::APSInt Zero( +                    SemaRef.Context.getTypeSize(SemaRef.Context.getSizeType()), +                    false); +    CheckArrayType(Entity, IList, DeclType, Zero, +                   SubobjectIsDesignatorContext, Index, +                   StructuredList, StructuredIndex);    } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {      // This type is invalid, issue a diagnostic.      ++Index; @@ -710,19 +708,6 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,        SemaRef.Diag(IList->getLocStart(), diag::err_illegal_initializer_type)          << DeclType;      hadError = true; -  } else if (DeclType->isRecordType()) { -    // C++ [dcl.init]p14: -    //   [...] If the class is an aggregate (8.5.1), and the initializer -    //   is a brace-enclosed list, see 8.5.1. -    // -    // Note: 8.5.1 is handled below; here, we diagnose the case where -    // we have an initializer list and a destination type that is not -    // an aggregate. -    // FIXME: In C++0x, this is yet another form of initialization. -    if (!VerifyOnly) -      SemaRef.Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list) -        << DeclType << IList->getSourceRange(); -    hadError = true;    } else if (DeclType->isReferenceType()) {      CheckReferenceType(Entity, IList, DeclType, Index,                         StructuredList, StructuredIndex); @@ -747,18 +732,25 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,                                            unsigned &StructuredIndex) {    Expr *expr = IList->getInit(Index);    if (InitListExpr *SubInitList = dyn_cast<InitListExpr>(expr)) { -    unsigned newIndex = 0; -    unsigned newStructuredIndex = 0; -    InitListExpr *newStructuredList -      = getStructuredSubobjectInit(IList, Index, ElemType, -                                   StructuredList, StructuredIndex, -                                   SubInitList->getSourceRange()); -    CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex, -                          newStructuredList, newStructuredIndex); -    ++StructuredIndex; -    ++Index; -    return; -  } else if (ElemType->isScalarType()) { +    if (!ElemType->isRecordType() || ElemType->isAggregateType()) { +      unsigned newIndex = 0; +      unsigned newStructuredIndex = 0; +      InitListExpr *newStructuredList +        = getStructuredSubobjectInit(IList, Index, ElemType, +                                     StructuredList, StructuredIndex, +                                     SubInitList->getSourceRange()); +      CheckExplicitInitList(Entity, SubInitList, ElemType, newIndex, +                            newStructuredList, newStructuredIndex); +      ++StructuredIndex; +      ++Index; +      return; +    } +    assert(SemaRef.getLangOpts().CPlusPlus && +           "non-aggregate records are only possible in C++"); +    // C++ initialization is handled later. +  } + +  if (ElemType->isScalarType()) {      return CheckScalarType(Entity, IList, ElemType, Index,                             StructuredList, StructuredIndex);    } else if (ElemType->isReferenceType()) { @@ -1859,7 +1851,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,        }      } else {        // Recurse to check later designated subobjects. -      QualType FieldType = (*Field)->getType(); +      QualType FieldType = Field->getType();        unsigned newStructuredIndex = FieldIndex;        InitializedEntity MemberEntity = @@ -2708,84 +2700,39 @@ static void MaybeProduceObjCObject(Sema &S,    }  } -/// \brief When initializing from init list via constructor, deal with the -/// empty init list and std::initializer_list special cases. +/// \brief When initializing from init list via constructor, handle +/// initialization of an object of type std::initializer_list<T>.  /// -/// \return True if this was a special case, false otherwise. -static bool TryListConstructionSpecialCases(Sema &S, -                                            InitListExpr *List, -                                            CXXRecordDecl *DestRecordDecl, -                                            QualType DestType, -                                            InitializationSequence &Sequence) { -  // C++11 [dcl.init.list]p3: -  //   List-initialization of an object or reference of type T is defined as -  //   follows: -  //   - If T is an aggregate, aggregate initialization is performed. -  if (DestType->isAggregateType()) +/// \return true if we have handled initialization of an object of type +/// std::initializer_list<T>, false otherwise. +static bool TryInitializerListConstruction(Sema &S, +                                           InitListExpr *List, +                                           QualType DestType, +                                           InitializationSequence &Sequence) { +  QualType E; +  if (!S.isStdInitializerList(DestType, &E))      return false; -  //   - Otherwise, if the initializer list has no elements and T is a class -  //     type with a default constructor, the object is value-initialized. -  if (List->getNumInits() == 0) { -    if (CXXConstructorDecl *DefaultConstructor = -            S.LookupDefaultConstructor(DestRecordDecl)) { -      if (DefaultConstructor->isDeleted() || -          S.isFunctionConsideredUnavailable(DefaultConstructor)) { -        // Fake an overload resolution failure. -        OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); -        DeclAccessPair FoundDecl = DeclAccessPair::make(DefaultConstructor, -                                              DefaultConstructor->getAccess()); -        if (FunctionTemplateDecl *ConstructorTmpl = -                dyn_cast<FunctionTemplateDecl>(DefaultConstructor)) -          S.AddTemplateOverloadCandidate(ConstructorTmpl, FoundDecl, -                                         /*ExplicitArgs*/ 0, -                                         ArrayRef<Expr*>(), CandidateSet, -                                         /*SuppressUserConversions*/ false); -        else -          S.AddOverloadCandidate(DefaultConstructor, FoundDecl, -                                 ArrayRef<Expr*>(), CandidateSet, -                                 /*SuppressUserConversions*/ false); -        Sequence.SetOverloadFailure( -                       InitializationSequence::FK_ListConstructorOverloadFailed, -                       OR_Deleted); -      } else -        Sequence.AddConstructorInitializationStep(DefaultConstructor, -                                                DefaultConstructor->getAccess(), -                                                  DestType, -                                                  /*MultipleCandidates=*/false, -                                                  /*FromInitList=*/true, -                                                  /*AsInitList=*/false); +  // Check that each individual element can be copy-constructed. But since we +  // have no place to store further information, we'll recalculate everything +  // later. +  InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary( +      S.Context.getConstantArrayType(E, +          llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()), +                      List->getNumInits()), +          ArrayType::Normal, 0)); +  InitializedEntity Element = InitializedEntity::InitializeElement(S.Context, +      0, HiddenArray); +  for (unsigned i = 0, n = List->getNumInits(); i < n; ++i) { +    Element.setElementIndex(i); +    if (!S.CanPerformCopyInitialization(Element, List->getInit(i))) { +      Sequence.SetFailed( +          InitializationSequence::FK_InitListElementCopyFailure);        return true;      }    } - -  //   - Otherwise, if T is a specialization of std::initializer_list, [...] -  QualType E; -  if (S.isStdInitializerList(DestType, &E)) { -    // Check that each individual element can be copy-constructed. But since we -    // have no place to store further information, we'll recalculate everything -    // later. -    InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary( -        S.Context.getConstantArrayType(E, -            llvm::APInt(S.Context.getTypeSize(S.Context.getSizeType()), -                        List->getNumInits()), -            ArrayType::Normal, 0)); -    InitializedEntity Element = InitializedEntity::InitializeElement(S.Context, -        0, HiddenArray); -    for (unsigned i = 0, n = List->getNumInits(); i < n; ++i) { -      Element.setElementIndex(i); -      if (!S.CanPerformCopyInitialization(Element, List->getInit(i))) { -        Sequence.SetFailed( -            InitializationSequence::FK_InitListElementCopyFailure); -        return true; -      } -    } -    Sequence.AddStdInitializerListConstructionStep(DestType); -    return true; -  } - -  // Not a special case. -  return false; +  Sequence.AddStdInitializerListConstructionStep(DestType); +  return true;  }  static OverloadingResult @@ -2886,11 +2833,6 @@ static void TryConstructorInitialization(Sema &S,    CXXRecordDecl *DestRecordDecl      = cast<CXXRecordDecl>(DestRecordType->getDecl()); -  if (InitListSyntax && -      TryListConstructionSpecialCases(S, cast<InitListExpr>(Args[0]), -                                      DestRecordDecl, DestType, Sequence)) -    return; -    // Build the candidate set directly in the initialization sequence    // structure, so that it will persist if we fail.    OverloadCandidateSet &CandidateSet = Sequence.getFailedCandidateSet(); @@ -2917,15 +2859,21 @@ static void TryConstructorInitialization(Sema &S,    //     constructors of the class T and the argument list consists of the    //     initializer list as a single argument.    if (InitListSyntax) { +    InitListExpr *ILE = cast<InitListExpr>(Args[0]);      AsInitializerList = true; -    Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs, -                                        CandidateSet, ConStart, ConEnd, Best, -                                        CopyInitialization, AllowExplicit, -                                        /*OnlyListConstructor=*/true, -                                        InitListSyntax); + +    // If the initializer list has no elements and T has a default constructor, +    // the first phase is omitted. +    if (ILE->getNumInits() != 0 || +        (!DestRecordDecl->hasDeclaredDefaultConstructor() && +         !DestRecordDecl->needsImplicitDefaultConstructor())) +      Result = ResolveConstructorOverload(S, Kind.getLocation(), Args, NumArgs, +                                          CandidateSet, ConStart, ConEnd, Best, +                                          CopyInitialization, AllowExplicit, +                                          /*OnlyListConstructor=*/true, +                                          InitListSyntax);      // Time to unwrap the init list. -    InitListExpr *ILE = cast<InitListExpr>(Args[0]);      Args = ILE->getInits();      NumArgs = ILE->getNumInits();    } @@ -2933,7 +2881,7 @@ static void TryConstructorInitialization(Sema &S,    // C++11 [over.match.list]p1:    //   - If no viable initializer-list constructor is found, overload resolution    //     is performed again, where the candidate functions are all the -  //     constructors of the class T nad the argument list consists of the +  //     constructors of the class T and the argument list consists of the    //     elements of the initializer list.    if (Result == OR_No_Viable_Function) {      AsInitializerList = false; @@ -2951,13 +2899,13 @@ static void TryConstructorInitialization(Sema &S,      return;    } -  // C++0x [dcl.init]p6: +  // C++11 [dcl.init]p6:    //   If a program calls for the default initialization of an object    //   of a const-qualified type T, T shall be a class type with a    //   user-provided default constructor.    if (Kind.getKind() == InitializationKind::IK_Default &&        Entity.getType().isConstQualified() && -      cast<CXXConstructorDecl>(Best->Function)->isImplicit()) { +      !cast<CXXConstructorDecl>(Best->Function)->isUserProvided()) {      Sequence.SetFailed(InitializationSequence::FK_DefaultInitOfConst);      return;    } @@ -3018,6 +2966,12 @@ static void TryReferenceInitializationCore(Sema &S,                                             Qualifiers T2Quals,                                             InitializationSequence &Sequence); +static void TryValueInitialization(Sema &S, +                                   const InitializedEntity &Entity, +                                   const InitializationKind &Kind, +                                   InitializationSequence &Sequence, +                                   InitListExpr *InitList = 0); +  static void TryListInitialization(Sema &S,                                    const InitializedEntity &Entity,                                    const InitializationKind &Kind, @@ -3108,19 +3062,36 @@ static void TryListInitialization(Sema &S,      return;    }    if (DestType->isRecordType()) { -    if (S.RequireCompleteType(InitList->getLocStart(), DestType, S.PDiag())) { +    if (S.RequireCompleteType(InitList->getLocStart(), DestType, 0)) {        Sequence.setIncompleteTypeFailure(DestType);        return;      } +    // C++11 [dcl.init.list]p3: +    //   - If T is an aggregate, aggregate initialization is performed.      if (!DestType->isAggregateType()) {        if (S.getLangOpts().CPlusPlus0x) { +        //   - Otherwise, if the initializer list has no elements and T is a +        //     class type with a default constructor, the object is +        //     value-initialized. +        if (InitList->getNumInits() == 0) { +          CXXRecordDecl *RD = DestType->getAsCXXRecordDecl(); +          if (RD->hasDeclaredDefaultConstructor() || +              RD->needsImplicitDefaultConstructor()) { +            TryValueInitialization(S, Entity, Kind, Sequence, InitList); +            return; +          } +        } + +        //   - Otherwise, if T is a specialization of std::initializer_list<E>, +        //     an initializer_list object constructed [...] +        if (TryInitializerListConstruction(S, InitList, DestType, Sequence)) +          return; + +        //   - Otherwise, if T is a class type, constructors are considered.          Expr *Arg = InitList; -        // A direct-initializer is not list-syntax, i.e. there's no special -        // treatment of "A a({1, 2});". -        TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType,  -                                     Sequence, -                               Kind.getKind() != InitializationKind::IK_Direct); +        TryConstructorInitialization(S, Entity, Kind, &Arg, 1, DestType, +                                     Sequence, /*InitListSyntax*/true);        } else          Sequence.SetFailed(              InitializationSequence::FK_InitListBadDestinationType); @@ -3605,7 +3576,11 @@ static void TryStringLiteralInitialization(Sema &S,  static void TryValueInitialization(Sema &S,                                     const InitializedEntity &Entity,                                     const InitializationKind &Kind, -                                   InitializationSequence &Sequence) { +                                   InitializationSequence &Sequence, +                                   InitListExpr *InitList) { +  assert((!InitList || InitList->getNumInits() == 0) && +         "Shouldn't use value-init for non-empty init lists"); +    // C++98 [dcl.init]p5, C++11 [dcl.init]p7:    //    //   To value-initialize an object of type T means: @@ -3616,17 +3591,15 @@ static void TryValueInitialization(Sema &S,    if (const RecordType *RT = T->getAs<RecordType>()) {      if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) { -      // C++98: -      // -- if T is a class type (clause 9) with a user-declared -      //    constructor (12.1), then the default constructor for T is -      //    called (and the initialization is ill-formed if T has no -      //    accessible default constructor); +      bool NeedZeroInitialization = true;        if (!S.getLangOpts().CPlusPlus0x) { +        // C++98: +        // -- if T is a class type (clause 9) with a user-declared constructor +        //    (12.1), then the default constructor for T is called (and the +        //    initialization is ill-formed if T has no accessible default +        //    constructor);          if (ClassDecl->hasUserDeclaredConstructor()) -          // FIXME: we really want to refer to a single subobject of the array, -          // but Entity doesn't have a way to capture that (yet). -          return TryConstructorInitialization(S, Entity, Kind, 0, 0, -                                              T, Sequence); +          NeedZeroInitialization = false;        } else {          // C++11:          // -- if T is a class type (clause 9) with either no default constructor @@ -3634,19 +3607,28 @@ static void TryValueInitialization(Sema &S,          //    or deleted, then the object is default-initialized;          CXXConstructorDecl *CD = S.LookupDefaultConstructor(ClassDecl);          if (!CD || !CD->getCanonicalDecl()->isDefaulted() || CD->isDeleted()) -          return TryConstructorInitialization(S, Entity, Kind, 0, 0, -                                              T, Sequence); +          NeedZeroInitialization = false;        }        // -- if T is a (possibly cv-qualified) non-union class type without a        //    user-provided or deleted default constructor, then the object is        //    zero-initialized and, if T has a non-trivial default constructor,        //    default-initialized; -      if ((ClassDecl->getTagKind() == TTK_Class || -           ClassDecl->getTagKind() == TTK_Struct)) { +      // FIXME: The 'non-union' here is a defect (not yet assigned an issue +      // number). Update the quotation when the defect is resolved. +      if (NeedZeroInitialization)          Sequence.AddZeroInitializationStep(Entity.getType()); -        return TryConstructorInitialization(S, Entity, Kind, 0, 0, T, Sequence); -      } + +      // If this is list-value-initialization, pass the empty init list on when +      // building the constructor call. This affects the semantics of a few +      // things (such as whether an explicit default constructor can be called). +      Expr *InitListAsExpr = InitList; +      Expr **Args = InitList ? &InitListAsExpr : 0; +      unsigned NumArgs = InitList ? 1 : 0; +      bool InitListSyntax = InitList; + +      return TryConstructorInitialization(S, Entity, Kind, Args, NumArgs, T, +                                          Sequence, InitListSyntax);      }    } @@ -4101,8 +4083,8 @@ InitializationSequence::InitializationSequence(Sema &S,          AddArrayInitStep(DestType);        }      } -    // Note: as a GNU C++ extension, we allow initialization of a -    // class member from a parenthesized initializer list. +    // Note: as a GNU C++ extension, we allow list-initialization of a +    // class member of array type from a parenthesized initializer list.      else if (S.getLangOpts().CPlusPlus &&               Entity.getKind() == InitializedEntity::EK_Member &&               Initializer && isa<InitListExpr>(Initializer)) { @@ -4409,7 +4391,7 @@ static SourceLocation getInitializationLoc(const InitializedEntity &Entity,  /// \param T The type of the temporary object, which must either be  /// the type of the initializer expression or a superclass thereof.  /// -/// \param Enter The entity being initialized. +/// \param Entity The entity being initialized.  ///  /// \param CurInit The initializer expression.  /// @@ -4452,7 +4434,7 @@ static ExprResult CopyObject(Sema &S,    SourceLocation Loc = getInitializationLoc(Entity, CurInit.get());    // Make sure that the type we are copying is complete. -  if (S.RequireCompleteType(Loc, T, S.PDiag(diag::err_temp_copy_incomplete))) +  if (S.RequireCompleteType(Loc, T, diag::err_temp_copy_incomplete))      return move(CurInit);    // Perform overload resolution using the class's copy/move constructors. @@ -4516,7 +4498,7 @@ static ExprResult CopyObject(Sema &S,      for (unsigned I = 1, N = Constructor->getNumParams(); I != N; ++I) {        ParmVarDecl *Parm = Constructor->getParamDecl(I);        if (S.RequireCompleteType(Loc, Parm->getType(), -                                S.PDiag(diag::err_call_incomplete_argument))) +                                diag::err_call_incomplete_argument))          break;        // Build the default argument expression; we don't actually care @@ -4748,6 +4730,43 @@ PerformConstructorInitialization(Sema &S,    return move(CurInit);  } +/// Determine whether the specified InitializedEntity definitely has a lifetime +/// longer than the current full-expression. Conservatively returns false if +/// it's unclear. +static bool +InitializedEntityOutlivesFullExpression(const InitializedEntity &Entity) { +  const InitializedEntity *Top = &Entity; +  while (Top->getParent()) +    Top = Top->getParent(); + +  switch (Top->getKind()) { +  case InitializedEntity::EK_Variable: +  case InitializedEntity::EK_Result: +  case InitializedEntity::EK_Exception: +  case InitializedEntity::EK_Member: +  case InitializedEntity::EK_New: +  case InitializedEntity::EK_Base: +  case InitializedEntity::EK_Delegating: +    return true; + +  case InitializedEntity::EK_ArrayElement: +  case InitializedEntity::EK_VectorElement: +  case InitializedEntity::EK_BlockElement: +  case InitializedEntity::EK_ComplexElement: +    // Could not determine what the full initialization is. Assume it might not +    // outlive the full-expression. +    return false; + +  case InitializedEntity::EK_Parameter: +  case InitializedEntity::EK_Temporary: +  case InitializedEntity::EK_LambdaCapture: +    // The entity being initialized might not outlive the full-expression. +    return false; +  } + +  llvm_unreachable("unknown entity kind"); +} +  ExprResult  InitializationSequence::Perform(Sema &S,                                  const InitializedEntity &Entity, @@ -4816,6 +4835,29 @@ InitializationSequence::Perform(Sema &S,    if (Steps.empty())      return S.Owned((Expr *)0); +  if (S.getLangOpts().CPlusPlus0x && Entity.getType()->isReferenceType() && +      Args.size() == 1 && isa<InitListExpr>(Args.get()[0]) && +      Entity.getKind() != InitializedEntity::EK_Parameter) { +    // Produce a C++98 compatibility warning if we are initializing a reference +    // from an initializer list. For parameters, we produce a better warning +    // elsewhere. +    Expr *Init = Args.get()[0]; +    S.Diag(Init->getLocStart(), diag::warn_cxx98_compat_reference_list_init) +      << Init->getSourceRange(); +  } + +  // Diagnose cases where we initialize a pointer to an array temporary, and the +  // pointer obviously outlives the temporary. +  if (Args.size() == 1 && Args.get()[0]->getType()->isArrayType() && +      Entity.getType()->isPointerType() && +      InitializedEntityOutlivesFullExpression(Entity)) { +    Expr *Init = Args.get()[0]; +    Expr::LValueClassification Kind = Init->ClassifyLValue(S.Context); +    if (Kind == Expr::LV_ClassTemporary || Kind == Expr::LV_ArrayTemporary) +      S.Diag(Init->getLocStart(), diag::warn_temporary_array_to_pointer_decay) +        << Init->getSourceRange(); +  } +    QualType DestType = Entity.getType().getNonReferenceType();    // FIXME: Ugly hack around the fact that Entity.getType() is not    // the same as Entity.getDecl()->getType() in cases involving type merging, @@ -4842,7 +4884,6 @@ InitializationSequence::Perform(Sema &S,    case SK_QualificationConversionXValue:    case SK_QualificationConversionRValue:    case SK_ConversionSequence: -  case SK_ListConstructorCall:    case SK_ListInitialization:    case SK_UnwrapInitList:    case SK_RewrapInitList: @@ -4862,6 +4903,7 @@ InitializationSequence::Perform(Sema &S,    }    case SK_ConstructorInitialization: +  case SK_ListConstructorCall:    case SK_ZeroInitialization:      break;    } @@ -5152,7 +5194,10 @@ InitializationSequence::Perform(Sema &S,        InitializedEntity TempEntity = InitializedEntity::InitializeTemporary(                                          Entity.getType().getNonReferenceType());        bool UseTemporary = Entity.getType()->isReferenceType(); -      InitListExpr *InitList = cast<InitListExpr>(CurInit.get()); +      assert(Args.size() == 1 && "expected a single argument for list init"); +      InitListExpr *InitList = cast<InitListExpr>(Args.get()[0]); +      S.Diag(InitList->getExprLoc(), diag::warn_cxx98_compat_ctor_list_init) +        << InitList->getSourceRange();        MultiExprArg Arg(InitList->getInits(), InitList->getNumInits());        CurInit = PerformConstructorInitialization(S, UseTemporary ? TempEntity :                                                                     Entity, @@ -5198,7 +5243,8 @@ InitializationSequence::Perform(Sema &S,        step_iterator NextStep = Step;        ++NextStep;        if (NextStep != StepEnd && -          NextStep->Kind == SK_ConstructorInitialization) { +          (NextStep->Kind == SK_ConstructorInitialization || +           NextStep->Kind == SK_ListConstructorCall)) {          // The need for zero-initialization is recorded directly into          // the call to the object's constructor within the next step.          ConstructorInitRequiresZeroInit = true; @@ -5330,6 +5376,8 @@ InitializationSequence::Perform(Sema &S,        }        InitListExpr *ILE = cast<InitListExpr>(CurInit.take()); +      S.Diag(ILE->getExprLoc(), diag::warn_cxx98_compat_initializer_list_init) +        << ILE->getSourceRange();        unsigned NumInits = ILE->getNumInits();        SmallVector<Expr*, 16> Converted(NumInits);        InitializedEntity HiddenArray = InitializedEntity::InitializeTemporary( @@ -6130,8 +6178,8 @@ Sema::CanPerformCopyInitialization(const InitializedEntity &Entity,    Expr *InitE = Init.get();    assert(InitE && "No initialization expression"); -  InitializationKind Kind = InitializationKind::CreateCopy(SourceLocation(), -                                                           SourceLocation()); +  InitializationKind Kind +    = InitializationKind::CreateCopy(InitE->getLocStart(), SourceLocation());    InitializationSequence Seq(*this, Entity, Kind, &InitE, 1);    return !Seq.Failed();  }  | 
