diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2013-06-10 20:45:12 +0000 |
commit | 6a0372513edbc473b538d2f724efac50405d6fef (patch) | |
tree | 8f7776b7310bebaf415ac5b69e46e9f928c37144 /lib/Sema/SemaExprCXX.cpp | |
parent | 809500fc2c13c8173a16b052304d983864e4a1e1 (diff) | |
download | src-test2-6a0372513edbc473b538d2f724efac50405d6fef.tar.gz src-test2-6a0372513edbc473b538d2f724efac50405d6fef.zip |
Notes
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 145 |
1 files changed, 79 insertions, 66 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 3f2cb026730d..27032a911147 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -684,7 +684,8 @@ ExprResult Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *E, MarkFunctionReferenced(E->getExprLoc(), Destructor); CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_exception) << Ty); - DiagnoseUseOfDecl(Destructor, E->getExprLoc()); + if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) + return ExprError(); return Owned(E); } @@ -728,9 +729,21 @@ Sema::CXXThisScopeRAII::~CXXThisScopeRAII() { } } +static Expr *captureThis(ASTContext &Context, RecordDecl *RD, + QualType ThisTy, SourceLocation Loc) { + FieldDecl *Field + = FieldDecl::Create(Context, RD, Loc, Loc, 0, ThisTy, + Context.getTrivialTypeSourceInfo(ThisTy, Loc), + 0, false, ICIS_NoInit); + Field->setImplicit(true); + Field->setAccess(AS_private); + RD->addDecl(Field); + return new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit*/true); +} + void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { // We don't need to capture this in an unevaluated context. - if (ExprEvalContexts.back().Context == Unevaluated && !Explicit) + if (isUnevaluatedContext() && !Explicit) return; // Otherwise, check that we can capture 'this'. @@ -746,6 +759,7 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { if (CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByref || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_LambdaByval || CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_Block || + CSI->ImpCaptureStyle == CapturingScopeInfo::ImpCap_CapturedRegion || Explicit) { // This closure can capture 'this'; continue looking upwards. NumClosures++; @@ -767,18 +781,13 @@ void Sema::CheckCXXThisCapture(SourceLocation Loc, bool Explicit) { CapturingScopeInfo *CSI = cast<CapturingScopeInfo>(FunctionScopes[idx]); Expr *ThisExpr = 0; QualType ThisTy = getCurrentThisType(); - if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) { + if (LambdaScopeInfo *LSI = dyn_cast<LambdaScopeInfo>(CSI)) // For lambda expressions, build a field and an initializing expression. - CXXRecordDecl *Lambda = LSI->Lambda; - FieldDecl *Field - = FieldDecl::Create(Context, Lambda, Loc, Loc, 0, ThisTy, - Context.getTrivialTypeSourceInfo(ThisTy, Loc), - 0, false, ICIS_NoInit); - Field->setImplicit(true); - Field->setAccess(AS_private); - Lambda->addDecl(Field); - ThisExpr = new (Context) CXXThisExpr(Loc, ThisTy, /*isImplicit=*/true); - } + ThisExpr = captureThis(Context, LSI->Lambda, ThisTy, Loc); + else if (CapturedRegionScopeInfo *RSI + = dyn_cast<CapturedRegionScopeInfo>(FunctionScopes[idx])) + ThisExpr = captureThis(Context, RSI->TheRecordDecl, ThisTy, Loc); + bool isNested = NumClosures > 1; CSI->addThisCapture(isNested, Loc, ThisTy, ThisExpr); } @@ -831,23 +840,20 @@ Sema::ActOnCXXTypeConstructExpr(ParsedType TypeRep, ExprResult Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, SourceLocation LParenLoc, - MultiExprArg exprs, + MultiExprArg Exprs, SourceLocation RParenLoc) { QualType Ty = TInfo->getType(); SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc(); - if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(exprs)) { + if (Ty->isDependentType() || CallExpr::hasAnyTypeDependentArguments(Exprs)) { return Owned(CXXUnresolvedConstructExpr::Create(Context, TInfo, LParenLoc, - exprs, + Exprs, RParenLoc)); } - unsigned NumExprs = exprs.size(); - Expr **Exprs = exprs.data(); - bool ListInitialization = LParenLoc.isInvalid(); - assert((!ListInitialization || (NumExprs == 1 && isa<InitListExpr>(Exprs[0]))) + assert((!ListInitialization || (Exprs.size() == 1 && isa<InitListExpr>(Exprs[0]))) && "List initialization must have initializer list as expression."); SourceRange FullRange = SourceRange(TyBeginLoc, ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc); @@ -856,7 +862,7 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, // 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 (NumExprs == 1 && !ListInitialization) { + if (Exprs.size() == 1 && !ListInitialization) { Expr *Arg = Exprs[0]; return BuildCXXFunctionalCastExpr(TInfo, LParenLoc, Arg, RParenLoc); } @@ -879,15 +885,13 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, return ExprError(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); - InitializationKind Kind - = NumExprs ? ListInitialization - ? InitializationKind::CreateDirectList(TyBeginLoc) - : InitializationKind::CreateDirect(TyBeginLoc, - LParenLoc, RParenLoc) - : InitializationKind::CreateValue(TyBeginLoc, - LParenLoc, RParenLoc); - InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, exprs); + InitializationKind Kind = + Exprs.size() ? ListInitialization + ? InitializationKind::CreateDirectList(TyBeginLoc) + : InitializationKind::CreateDirect(TyBeginLoc, LParenLoc, RParenLoc) + : InitializationKind::CreateValue(TyBeginLoc, LParenLoc, RParenLoc); + InitializationSequence InitSeq(*this, Entity, Kind, Exprs); + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Exprs); if (!Result.isInvalid() && ListInitialization && isa<InitListExpr>(Result.get())) { @@ -983,7 +987,7 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer) { - bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto; + bool TypeContainsAuto = D.getDeclSpec().containsPlaceholderType(); Expr *ArraySize = 0; // If the specified type is an array, unwrap it and save the expression. @@ -1110,9 +1114,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, HaveCompleteInit = true; // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for. - AutoType *AT = 0; - if (TypeMayContainAuto && - (AT = AllocType->getContainedAutoType()) && !AT->isDeduced()) { + if (TypeMayContainAuto && AllocType->isUndeducedType()) { if (initStyle == CXXNewExpr::NoInit || NumInits == 0) return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg) << AllocType << TypeRange); @@ -1127,16 +1129,14 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, << AllocType << TypeRange); } Expr *Deduce = Inits[0]; - TypeSourceInfo *DeducedType = 0; + QualType DeducedType; if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) == DAR_Failed) return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure) << AllocType << Deduce->getType() << TypeRange << Deduce->getSourceRange()); - if (!DeducedType) + if (DeducedType.isNull()) return ExprError(); - - AllocTypeInfo = DeducedType; - AllocType = AllocTypeInfo->getType(); + AllocType = DeducedType; } // Per C++0x [expr.new]p5, the type being constructed may be a @@ -1170,6 +1170,11 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, QualType ResultType = Context.getPointerType(AllocType); + if (ArraySize && ArraySize->getType()->isNonOverloadPlaceholderType()) { + ExprResult result = CheckPlaceholderExpr(ArraySize); + if (result.isInvalid()) return ExprError(); + ArraySize = result.take(); + } // C++98 5.3.4p6: "The expression in a direct-new-declarator shall have // integral or enumeration type with a non-negative value." // C++11 [expr.new]p6: The expression [...] shall be of integral or unscoped @@ -1405,7 +1410,7 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, InitializedEntity Entity = InitializedEntity::InitializeNew(StartLoc, InitType); - InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits); + InitializationSequence InitSeq(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, MultiExprArg(Inits, NumInits)); if (FullInit.isInvalid()) @@ -1422,11 +1427,13 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, // Mark the new and delete operators as referenced. if (OperatorNew) { - DiagnoseUseOfDecl(OperatorNew, StartLoc); + if (DiagnoseUseOfDecl(OperatorNew, StartLoc)) + return ExprError(); MarkFunctionReferenced(StartLoc, OperatorNew); } if (OperatorDelete) { - DiagnoseUseOfDecl(OperatorDelete, StartLoc); + if (DiagnoseUseOfDecl(OperatorDelete, StartLoc)) + return ExprError(); MarkFunctionReferenced(StartLoc, OperatorDelete); } @@ -1442,7 +1449,8 @@ Sema::BuildCXXNew(SourceRange Range, bool UseGlobal, CheckDestructorAccess(StartLoc, dtor, PDiag(diag::err_access_dtor) << BaseAllocType); - DiagnoseUseOfDecl(dtor, StartLoc); + if (DiagnoseUseOfDecl(dtor, StartLoc)) + return ExprError(); } } } @@ -2200,7 +2208,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, if (CXXDestructorDecl *Dtor = LookupDestructor(PointeeRD)) { MarkFunctionReferenced(StartLoc, const_cast<CXXDestructorDecl*>(Dtor)); - DiagnoseUseOfDecl(Dtor, StartLoc); + if (DiagnoseUseOfDecl(Dtor, StartLoc)) + return ExprError(); } // C++ [expr.delete]p3: @@ -2266,6 +2275,9 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, ExprResult Sema::CheckConditionVariable(VarDecl *ConditionVar, SourceLocation StmtLoc, bool ConvertToBoolean) { + if (ConditionVar->isInvalidDecl()) + return ExprError(); + QualType T = ConditionVar->getType(); // C++ [stmt.select]p2: @@ -3119,7 +3131,7 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, UnaryTypeTrait UTT, case UTT_IsPOD: return T.isPODType(Self.Context); case UTT_IsLiteral: - return T->isLiteralType(); + return T->isLiteralType(Self.Context); case UTT_IsEmpty: if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) return !RD->isUnion() && RD->isEmpty(); @@ -3486,8 +3498,7 @@ static bool evaluateTypeTrait(Sema &S, TypeTrait Kind, SourceLocation KWLoc, InitializedEntity To(InitializedEntity::InitializeTemporary(Args[0])); InitializationKind InitKind(InitializationKind::CreateDirect(KWLoc, KWLoc, RParenLoc)); - InitializationSequence Init(S, To, InitKind, - ArgExprs.begin(), ArgExprs.size()); + InitializationSequence Init(S, To, InitKind, ArgExprs); if (Init.Failed()) return false; @@ -3645,7 +3656,7 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, BinaryTypeTrait BTT, EnterExpressionEvaluationContext Unevaluated(Self, Sema::Unevaluated); Sema::SFINAETrap SFINAE(Self, /*AccessCheckingSFINAE=*/true); Sema::ContextRAII TUContext(Self, Self.Context.getTranslationUnitDecl()); - InitializationSequence Init(Self, To, Kind, &FromPtr, 1); + InitializationSequence Init(Self, To, Kind, FromPtr); if (Init.Failed()) return false; @@ -4045,7 +4056,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, QualType T = Self.Context.getLValueReferenceType(ToType); InitializedEntity Entity = InitializedEntity::InitializeTemporary(T); - InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); + InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq.isDirectReferenceBinding()) { ToType = T; HaveConversion = true; @@ -4053,7 +4064,7 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, } if (InitSeq.isAmbiguous()) - return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); + return InitSeq.Diagnose(Self, Entity, Kind, From); } // -- If E2 is an rvalue, or if the conversion above cannot be done: @@ -4073,14 +4084,14 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, if (FRec == TRec || FDerivedFromT) { if (TTy.isAtLeastAsQualifiedAs(FTy)) { InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); - InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); + InitializationSequence InitSeq(Self, Entity, Kind, From); if (InitSeq) { HaveConversion = true; return false; } if (InitSeq.isAmbiguous()) - return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); + return InitSeq.Diagnose(Self, Entity, Kind, From); } } @@ -4098,11 +4109,11 @@ static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, TTy = TTy.getUnqualifiedType(); InitializedEntity Entity = InitializedEntity::InitializeTemporary(TTy); - InitializationSequence InitSeq(Self, Entity, Kind, &From, 1); + InitializationSequence InitSeq(Self, Entity, Kind, From); HaveConversion = !InitSeq.Failed(); ToType = TTy; if (InitSeq.isAmbiguous()) - return InitSeq.Diagnose(Self, Entity, Kind, &From, 1); + return InitSeq.Diagnose(Self, Entity, Kind, From); return false; } @@ -4116,7 +4127,7 @@ static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS SourceLocation QuestionLoc) { Expr *Args[2] = { LHS.get(), RHS.get() }; OverloadCandidateSet CandidateSet(QuestionLoc); - Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, 2, + Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args, CandidateSet); OverloadCandidateSet::iterator Best; @@ -4175,7 +4186,7 @@ static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T) { InitializationKind Kind = InitializationKind::CreateCopy(E.get()->getLocStart(), SourceLocation()); Expr *Arg = E.take(); - InitializationSequence InitSeq(Self, Entity, Kind, &Arg, 1); + InitializationSequence InitSeq(Self, Entity, Kind, Arg); ExprResult Result = InitSeq.Perform(Self, Entity, Kind, Arg); if (Result.isInvalid()) return true; @@ -4624,8 +4635,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, = InitializedEntity::InitializeTemporary(Composite1); InitializationKind Kind = InitializationKind::CreateCopy(Loc, SourceLocation()); - InitializationSequence E1ToC1(*this, Entity1, Kind, &E1, 1); - InitializationSequence E2ToC1(*this, Entity1, Kind, &E2, 1); + InitializationSequence E1ToC1(*this, Entity1, Kind, E1); + InitializationSequence E2ToC1(*this, Entity1, Kind, E2); if (E1ToC1 && E2ToC1) { // Conversion to Composite1 is viable. @@ -4634,8 +4645,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, // Composite2 is also viable. InitializedEntity Entity2 = InitializedEntity::InitializeTemporary(Composite2); - InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1); - InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1); + InitializationSequence E1ToC2(*this, Entity2, Kind, E1); + InitializationSequence E2ToC2(*this, Entity2, Kind, E2); if (E1ToC2 && E2ToC2) { // Both Composite1 and Composite2 are viable and are different; // this is an ambiguity. @@ -4663,8 +4674,8 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc, // Check whether Composite2 is viable. InitializedEntity Entity2 = InitializedEntity::InitializeTemporary(Composite2); - InitializationSequence E1ToC2(*this, Entity2, Kind, &E1, 1); - InitializationSequence E2ToC2(*this, Entity2, Kind, &E2, 1); + InitializationSequence E1ToC2(*this, Entity2, Kind, E1); + InitializationSequence E2ToC2(*this, Entity2, Kind, E2); if (!E1ToC2 || !E2ToC2) return QualType(); @@ -4813,7 +4824,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) { CheckDestructorAccess(E->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << E->getType()); - DiagnoseUseOfDecl(Destructor, E->getExprLoc()); + if (DiagnoseUseOfDecl(Destructor, E->getExprLoc())) + return ExprError(); // If destructor is trivial, we can avoid the extra copy. if (Destructor->isTrivial()) @@ -4968,7 +4980,8 @@ ExprResult Sema::ActOnDecltypeExpression(Expr *E) { CheckDestructorAccess(Bind->getExprLoc(), Destructor, PDiag(diag::err_access_dtor_temp) << Bind->getType()); - DiagnoseUseOfDecl(Destructor, Bind->getExprLoc()); + if (DiagnoseUseOfDecl(Destructor, Bind->getExprLoc())) + return ExprError(); // We need a cleanup, but we don't need to remember the temporary. ExprNeedsCleanups = true; @@ -5086,7 +5099,7 @@ ExprResult Sema::DiagnoseDtorReference(SourceLocation NameLoc, return ActOnCallExpr(/*Scope*/ 0, MemExpr, /*LPLoc*/ ExpectedLParenLoc, - MultiExprArg(), + None, /*RPLoc*/ ExpectedLParenLoc); } @@ -5434,7 +5447,7 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl, ResultType = ResultType.getNonLValueExprType(Context); CXXMemberCallExpr *CE = - new (Context) CXXMemberCallExpr(Context, ME, MultiExprArg(), ResultType, VK, + new (Context) CXXMemberCallExpr(Context, ME, None, ResultType, VK, Exp.get()->getLocEnd()); return CE; } |