diff options
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r-- | lib/Sema/SemaInit.cpp | 240 |
1 files changed, 156 insertions, 84 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 5882da0..ca3fd6d 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -92,13 +92,31 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT, const ConstantArrayType *CAT = cast<ConstantArrayType>(AT); - // C99 6.7.8p14. We have an array of character type with known size. However, + // We have an array of character type with known size. However, // the size may be smaller or larger than the string we are initializing. // FIXME: Avoid truncation for 64-bit length strings. - if (StrLength-1 > CAT->getSize().getZExtValue()) - S.Diag(Str->getSourceRange().getBegin(), - diag::warn_initializer_string_for_char_array_too_long) - << Str->getSourceRange(); + if (S.getLangOptions().CPlusPlus) { + if (StringLiteral *SL = dyn_cast<StringLiteral>(Str)) { + // For Pascal strings it's OK to strip off the terminating null character, + // so the example below is valid: + // + // unsigned char a[2] = "\pa"; + if (SL->isPascal()) + StrLength--; + } + + // [dcl.init.string]p2 + if (StrLength > CAT->getSize().getZExtValue()) + S.Diag(Str->getSourceRange().getBegin(), + diag::err_initializer_string_for_char_array_too_long) + << Str->getSourceRange(); + } else { + // C99 6.7.8p14. + if (StrLength-1 > CAT->getSize().getZExtValue()) + S.Diag(Str->getSourceRange().getBegin(), + diag::warn_initializer_string_for_char_array_too_long) + << Str->getSourceRange(); + } // Set the type to the actual size that we are initializing. If we have // something like: @@ -386,15 +404,29 @@ InitListChecker::FillInValueInitializations(const InitializedEntity &Entity, if (hadError) { // Do nothing } else if (Init < NumInits) { - ILE->setInit(Init, ElementInit.takeAs<Expr>()); - } else if (InitSeq.getKind() + // For arrays, just set the expression used for value-initialization + // of the "holes" in the array. + if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) + ILE->setArrayFiller(ElementInit.takeAs<Expr>()); + else + ILE->setInit(Init, ElementInit.takeAs<Expr>()); + } else { + // For arrays, just set the expression used for value-initialization + // of the rest of elements and exit. + if (ElementEntity.getKind() == InitializedEntity::EK_ArrayElement) { + ILE->setArrayFiller(ElementInit.takeAs<Expr>()); + return; + } + + if (InitSeq.getKind() == InitializationSequence::ConstructorInitialization) { - // Value-initialization requires a constructor call, so - // extend the initializer list to include the constructor - // call and make a note that we'll need to take another pass - // through the initializer list. - ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>()); - RequiresSecondPass = true; + // Value-initialization requires a constructor call, so + // extend the initializer list to include the constructor + // call and make a note that we'll need to take another pass + // through the initializer list. + ILE->updateInit(SemaRef.Context, Init, ElementInit.takeAs<Expr>()); + RequiresSecondPass = true; + } } } else if (InitListExpr *InnerILE = dyn_cast<InitListExpr>(ILE->getInit(Init))) @@ -713,15 +745,23 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity, // compatible structure or union type. In the latter case, the // initial value of the object, including unnamed members, is // that of the expression. + ExprResult ExprRes = SemaRef.Owned(expr); if ((ElemType->isRecordType() || ElemType->isVectorType()) && - SemaRef.CheckSingleAssignmentConstraints(ElemType, expr) + SemaRef.CheckSingleAssignmentConstraints(ElemType, ExprRes) == Sema::Compatible) { - SemaRef.DefaultFunctionArrayLvalueConversion(expr); - UpdateStructuredListElement(StructuredList, StructuredIndex, expr); + if (ExprRes.isInvalid()) + hadError = true; + else { + ExprRes = SemaRef.DefaultFunctionArrayLvalueConversion(ExprRes.take()); + if (ExprRes.isInvalid()) + hadError = true; + } + UpdateStructuredListElement(StructuredList, StructuredIndex, + ExprRes.takeAs<Expr>()); ++Index; return; } - + ExprRes.release(); // Fall through for subaggregate initialization } @@ -1755,11 +1795,15 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, // Pre-allocate storage for the structured initializer list. unsigned NumElements = 0; unsigned NumInits = 0; - if (!StructuredList) + bool GotNumInits = false; + if (!StructuredList) { NumInits = IList->getNumInits(); - else if (Index < IList->getNumInits()) { - if (InitListExpr *SubList = dyn_cast<InitListExpr>(IList->getInit(Index))) + GotNumInits = true; + } else if (Index < IList->getNumInits()) { + if (InitListExpr *SubList = dyn_cast<InitListExpr>(IList->getInit(Index))) { NumInits = SubList->getNumInits(); + GotNumInits = true; + } } if (const ArrayType *AType @@ -1768,7 +1812,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, NumElements = CAType->getSize().getZExtValue(); // Simple heuristic so that we don't allocate a very large // initializer with many empty entries at the end. - if (NumInits && NumElements > NumInits) + if (GotNumInits && NumElements > NumInits) NumElements = 0; } } else if (const VectorType *VType = CurrentObjectType->getAs<VectorType>()) @@ -1936,6 +1980,9 @@ ExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, Loc, GNUSyntax, Init.takeAs<Expr>()); if (getLangOptions().CPlusPlus) + Diag(DIE->getLocStart(), diag::ext_designated_init_cxx) + << DIE->getSourceRange(); + else if (!getLangOptions().C99) Diag(DIE->getLocStart(), diag::ext_designated_init) << DIE->getSourceRange(); @@ -1998,6 +2045,7 @@ DeclarationName InitializedEntity::getName() const { case EK_New: case EK_Temporary: case EK_Base: + case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: case EK_BlockElement: @@ -2020,6 +2068,7 @@ DeclaratorDecl *InitializedEntity::getDecl() const { case EK_New: case EK_Temporary: case EK_Base: + case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: case EK_BlockElement: @@ -2042,6 +2091,7 @@ bool InitializedEntity::allowsNRVO() const { case EK_New: case EK_Temporary: case EK_Base: + case EK_Delegating: case EK_ArrayElement: case EK_VectorElement: case EK_BlockElement: @@ -2101,6 +2151,7 @@ bool InitializationSequence::isAmbiguous() const { case FK_ReferenceInitDropsQualifiers: case FK_ReferenceInitFailed: case FK_ConversionFailed: + case FK_ConversionFromPropertyFailed: case FK_TooManyInitsForScalar: case FK_ReferenceBindingToInitList: case FK_InitListBadDestinationType: @@ -3126,8 +3177,14 @@ InitializationSequence::InitializationSequence(Sema &S, } for (unsigned I = 0; I != NumArgs; ++I) - if (Args[I]->getObjectKind() == OK_ObjCProperty) - S.ConvertPropertyForRValue(Args[I]); + if (Args[I]->getObjectKind() == OK_ObjCProperty) { + ExprResult Result = S.ConvertPropertyForRValue(Args[I]); + if (Result.isInvalid()) { + SetFailed(FK_ConversionFromPropertyFailed); + return; + } + Args[I] = Result.take(); + } QualType SourceType; Expr *Initializer = 0; @@ -3289,6 +3346,7 @@ getAssignmentAction(const InitializedEntity &Entity) { case InitializedEntity::EK_New: case InitializedEntity::EK_Exception: case InitializedEntity::EK_Base: + case InitializedEntity::EK_Delegating: return Sema::AA_Initializing; case InitializedEntity::EK_Parameter: @@ -3325,6 +3383,7 @@ static bool shouldBindAsTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_New: case InitializedEntity::EK_Variable: case InitializedEntity::EK_Base: + case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_Exception: case InitializedEntity::EK_BlockElement: @@ -3346,6 +3405,7 @@ static bool shouldDestroyTemporary(const InitializedEntity &Entity) { case InitializedEntity::EK_Result: case InitializedEntity::EK_New: case InitializedEntity::EK_Base: + case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_BlockElement: return false; @@ -3430,6 +3490,7 @@ static ExprResult CopyObject(Sema &S, case InitializedEntity::EK_Temporary: case InitializedEntity::EK_New: case InitializedEntity::EK_Base: + case InitializedEntity::EK_Delegating: case InitializedEntity::EK_VectorElement: case InitializedEntity::EK_BlockElement: Loc = CurInitExpr->getLocStart(); @@ -3686,14 +3747,15 @@ InitializationSequence::Perform(Sema &S, case SK_ObjCObjectConversion: case SK_ArrayInit: { assert(Args.size() == 1); - Expr *CurInitExpr = Args.get()[0]; - if (!CurInitExpr) return ExprError(); + CurInit = Args.get()[0]; + if (!CurInit.get()) return ExprError(); // Read from a property when initializing something with it. - if (CurInitExpr->getObjectKind() == OK_ObjCProperty) - S.ConvertPropertyForRValue(CurInitExpr); - - CurInit = ExprResult(CurInitExpr); + if (CurInit.get()->getObjectKind() == OK_ObjCProperty) { + CurInit = S.ConvertPropertyForRValue(CurInit.take()); + if (CurInit.isInvalid()) + return ExprError(); + } break; } @@ -3710,14 +3772,13 @@ InitializationSequence::Perform(Sema &S, if (CurInit.isInvalid()) return ExprError(); - Expr *CurInitExpr = CurInit.get(); - QualType SourceType = CurInitExpr? CurInitExpr->getType() : QualType(); + QualType SourceType = CurInit.get() ? CurInit.get()->getType() : QualType(); switch (Step->Kind) { case SK_ResolveAddressOfOverloadedFunction: // Overload resolution determined which function invoke; update the // initializer to reflect that choice. - S.CheckAddressOfMemberAccess(CurInitExpr, Step->Function.FoundDecl); + S.CheckAddressOfMemberAccess(CurInit.get(), Step->Function.FoundDecl); S.DiagnoseUseOfDecl(Step->Function.FoundDecl, Kind.getLocation()); CurInit = S.FixOverloadedFunctionReference(move(CurInit), Step->Function.FoundDecl, @@ -3735,8 +3796,8 @@ InitializationSequence::Perform(Sema &S, // Casts to inaccessible base classes are allowed with C-style casts. bool IgnoreBaseAccess = Kind.isCStyleOrFunctionalCast(); if (S.CheckDerivedToBaseConversion(SourceType, Step->Type, - CurInitExpr->getLocStart(), - CurInitExpr->getSourceRange(), + CurInit.get()->getLocStart(), + CurInit.get()->getSourceRange(), &BasePath, IgnoreBaseAccess)) return ExprError(); @@ -3745,7 +3806,7 @@ InitializationSequence::Perform(Sema &S, if (const PointerType *Pointer = T->getAs<PointerType>()) T = Pointer->getPointeeType(); if (const RecordType *RecordTy = T->getAs<RecordType>()) - S.MarkVTableUsed(CurInitExpr->getLocStart(), + S.MarkVTableUsed(CurInit.get()->getLocStart(), cast<CXXRecordDecl>(RecordTy->getDecl())); } @@ -3764,21 +3825,21 @@ InitializationSequence::Perform(Sema &S, } case SK_BindReference: - if (FieldDecl *BitField = CurInitExpr->getBitField()) { + if (FieldDecl *BitField = CurInit.get()->getBitField()) { // References cannot bind to bit fields (C++ [dcl.init.ref]p5). S.Diag(Kind.getLocation(), diag::err_reference_bind_to_bitfield) << Entity.getType().isVolatileQualified() << BitField->getDeclName() - << CurInitExpr->getSourceRange(); + << CurInit.get()->getSourceRange(); S.Diag(BitField->getLocation(), diag::note_bitfield_decl); return ExprError(); } - if (CurInitExpr->refersToVectorElement()) { + if (CurInit.get()->refersToVectorElement()) { // References cannot bind to vector elements. S.Diag(Kind.getLocation(), diag::err_reference_bind_to_vector_element) << Entity.getType().isVolatileQualified() - << CurInitExpr->getSourceRange(); + << CurInit.get()->getSourceRange(); PrintInitLocationNote(S, Entity); return ExprError(); } @@ -3786,7 +3847,7 @@ InitializationSequence::Perform(Sema &S, // Reference binding does not have any corresponding ASTs. // Check exception specifications - if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType)) + if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType)) return ExprError(); break; @@ -3795,7 +3856,7 @@ InitializationSequence::Perform(Sema &S, // Reference binding does not have any corresponding ASTs. // Check exception specifications - if (S.CheckExceptionSpecCompatibility(CurInitExpr, DestType)) + if (S.CheckExceptionSpecCompatibility(CurInit.get(), DestType)) return ExprError(); break; @@ -3817,13 +3878,14 @@ InitializationSequence::Perform(Sema &S, if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) { // Build a call to the selected constructor. ASTOwningVector<Expr*> ConstructorArgs(S); - SourceLocation Loc = CurInitExpr->getLocStart(); + SourceLocation Loc = CurInit.get()->getLocStart(); CurInit.release(); // Ownership transferred into MultiExprArg, below. // Determine the arguments required to actually perform the constructor // call. + Expr *Arg = CurInit.get(); if (S.CompleteConstructorCall(Constructor, - MultiExprArg(&CurInitExpr, 1), + MultiExprArg(&Arg, 1), Loc, ConstructorArgs)) return ExprError(); @@ -3851,23 +3913,22 @@ InitializationSequence::Perform(Sema &S, // Build a call to the conversion function. CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn); IsLvalue = Conversion->getResultType()->isLValueReferenceType(); - S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, 0, + S.CheckMemberOperatorAccess(Kind.getLocation(), CurInit.get(), 0, FoundFn); S.DiagnoseUseOfDecl(FoundFn, Kind.getLocation()); // FIXME: Should we move this initialization into a separate // derived-to-base conversion? I believe the answer is "no", because // we don't want to turn off access control here for c-style casts. - if (S.PerformObjectArgumentInitialization(CurInitExpr, /*Qualifier=*/0, - FoundFn, Conversion)) + ExprResult CurInitExprRes = + S.PerformObjectArgumentInitialization(CurInit.take(), /*Qualifier=*/0, + FoundFn, Conversion); + if(CurInitExprRes.isInvalid()) return ExprError(); - - // Do a little dance to make sure that CurInit has the proper - // pointer. - CurInit.release(); + CurInit = move(CurInitExprRes); // Build the actual call to the conversion function. - CurInit = S.BuildCXXMemberCallExpr(CurInitExpr, FoundFn, Conversion); + CurInit = S.BuildCXXMemberCallExpr(CurInit.get(), FoundFn, Conversion); if (CurInit.isInvalid() || !CurInit.get()) return ExprError(); @@ -3881,23 +3942,21 @@ InitializationSequence::Perform(Sema &S, if (RequiresCopy || shouldBindAsTemporary(Entity)) CurInit = S.MaybeBindToTemporary(CurInit.takeAs<Expr>()); else if (CreatedObject && shouldDestroyTemporary(Entity)) { - CurInitExpr = static_cast<Expr *>(CurInit.get()); - QualType T = CurInitExpr->getType(); + QualType T = CurInit.get()->getType(); if (const RecordType *Record = T->getAs<RecordType>()) { CXXDestructorDecl *Destructor = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl())); - S.CheckDestructorAccess(CurInitExpr->getLocStart(), Destructor, + S.CheckDestructorAccess(CurInit.get()->getLocStart(), Destructor, S.PDiag(diag::err_access_dtor_temp) << T); - S.MarkDeclarationReferenced(CurInitExpr->getLocStart(), Destructor); - S.DiagnoseUseOfDecl(Destructor, CurInitExpr->getLocStart()); + S.MarkDeclarationReferenced(CurInit.get()->getLocStart(), Destructor); + S.DiagnoseUseOfDecl(Destructor, CurInit.get()->getLocStart()); } } - CurInitExpr = CurInit.takeAs<Expr>(); // FIXME: xvalues CurInit = S.Owned(ImplicitCastExpr::Create(S.Context, - CurInitExpr->getType(), - CastKind, CurInitExpr, 0, + CurInit.get()->getType(), + CastKind, CurInit.get(), 0, IsLvalue ? VK_LValue : VK_RValue)); if (RequiresCopy) @@ -3917,25 +3976,23 @@ InitializationSequence::Perform(Sema &S, (Step->Kind == SK_QualificationConversionXValue ? VK_XValue : VK_RValue); - S.ImpCastExprToType(CurInitExpr, Step->Type, CK_NoOp, VK); - CurInit.release(); - CurInit = S.Owned(CurInitExpr); + CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_NoOp, VK); break; } case SK_ConversionSequence: { - if (S.PerformImplicitConversion(CurInitExpr, Step->Type, *Step->ICS, - getAssignmentAction(Entity), - Kind.isCStyleOrFunctionalCast())) + ExprResult CurInitExprRes = + S.PerformImplicitConversion(CurInit.get(), Step->Type, *Step->ICS, + getAssignmentAction(Entity), + Kind.isCStyleOrFunctionalCast()); + if (CurInitExprRes.isInvalid()) return ExprError(); - - CurInit.release(); - CurInit = S.Owned(CurInitExpr); + CurInit = move(CurInitExprRes); break; } case SK_ListInitialization: { - InitListExpr *InitList = cast<InitListExpr>(CurInitExpr); + InitListExpr *InitList = cast<InitListExpr>(CurInit.get()); QualType Ty = Step->Type; if (S.CheckInitList(Entity, InitList, ResultType? *ResultType : Ty)) return ExprError(); @@ -4004,6 +4061,9 @@ InitializationSequence::Perform(Sema &S, CXXConstructExpr::CK_VirtualBase : CXXConstructExpr::CK_NonVirtualBase; } + if (Entity.getKind() == InitializedEntity::EK_Delegating) { + ConstructKind = CXXConstructExpr::CK_Delegating; + } // Only get the parenthesis range if it is a direct construction. SourceRange parenRange = @@ -4068,54 +4128,57 @@ InitializationSequence::Perform(Sema &S, } case SK_CAssignment: { - QualType SourceType = CurInitExpr->getType(); + QualType SourceType = CurInit.get()->getType(); + ExprResult Result = move(CurInit); Sema::AssignConvertType ConvTy = - S.CheckSingleAssignmentConstraints(Step->Type, CurInitExpr); + S.CheckSingleAssignmentConstraints(Step->Type, Result); + if (Result.isInvalid()) + return ExprError(); + CurInit = move(Result); // If this is a call, allow conversion to a transparent union. + ExprResult CurInitExprRes = move(CurInit); if (ConvTy != Sema::Compatible && Entity.getKind() == InitializedEntity::EK_Parameter && - S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExpr) + S.CheckTransparentUnionArgumentConstraints(Step->Type, CurInitExprRes) == Sema::Compatible) ConvTy = Sema::Compatible; + if (CurInitExprRes.isInvalid()) + return ExprError(); + CurInit = move(CurInitExprRes); bool Complained; if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(), Step->Type, SourceType, - CurInitExpr, + CurInit.get(), getAssignmentAction(Entity), &Complained)) { PrintInitLocationNote(S, Entity); return ExprError(); } else if (Complained) PrintInitLocationNote(S, Entity); - - CurInit.release(); - CurInit = S.Owned(CurInitExpr); break; } case SK_StringInit: { QualType Ty = Step->Type; - CheckStringInit(CurInitExpr, ResultType ? *ResultType : Ty, + CheckStringInit(CurInit.get(), ResultType ? *ResultType : Ty, S.Context.getAsArrayType(Ty), S); break; } case SK_ObjCObjectConversion: - S.ImpCastExprToType(CurInitExpr, Step->Type, + CurInit = S.ImpCastExprToType(CurInit.take(), Step->Type, CK_ObjCObjectLValueCast, - S.CastCategory(CurInitExpr)); - CurInit.release(); - CurInit = S.Owned(CurInitExpr); + S.CastCategory(CurInit.get())); break; case SK_ArrayInit: // Okay: we checked everything before creating this step. Note that // this is a GNU extension. S.Diag(Kind.getLocation(), diag::ext_array_init_copy) - << Step->Type << CurInitExpr->getType() - << CurInitExpr->getSourceRange(); + << Step->Type << CurInit.get()->getType() + << CurInit.get()->getSourceRange(); // If the destination type is an incomplete array type, update the // type accordingly. @@ -4123,7 +4186,7 @@ InitializationSequence::Perform(Sema &S, if (const IncompleteArrayType *IncompleteDest = S.Context.getAsIncompleteArrayType(Step->Type)) { if (const ConstantArrayType *ConstantSource - = S.Context.getAsConstantArrayType(CurInitExpr->getType())) { + = S.Context.getAsConstantArrayType(CurInit.get()->getType())) { *ResultType = S.Context.getConstantArrayType( IncompleteDest->getElementType(), ConstantSource->getSize(), @@ -4283,6 +4346,11 @@ bool InitializationSequence::Diagnose(Sema &S, << Args[0]->getSourceRange(); break; } + + case FK_ConversionFromPropertyFailed: + // No-op. This error has already been reported. + break; + case FK_TooManyInitsForScalar: { SourceRange R; @@ -4482,6 +4550,10 @@ void InitializationSequence::dump(llvm::raw_ostream &OS) const { OS << "conversion failed"; break; + case FK_ConversionFromPropertyFailed: + OS << "conversion from property failed"; + break; + case FK_TooManyInitsForScalar: OS << "too many initializers for scalar"; break; |