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(); } |