diff options
Diffstat (limited to 'contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp')
-rw-r--r-- | contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp | 191 |
1 files changed, 113 insertions, 78 deletions
diff --git a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp index c4f6fd8..e1b1a47 100644 --- a/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp +++ b/contrib/llvm/tools/clang/lib/Sema/SemaStmt.cpp @@ -195,7 +195,7 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (isUnevaluatedContext()) return; - SourceLocation ExprLoc = E->IgnoreParens()->getExprLoc(); + SourceLocation ExprLoc = E->IgnoreParenImpCasts()->getExprLoc(); // In most cases, we don't want to warn if the expression is written in a // macro body, or if the macro comes from a system header. If the offending // expression is a call to a function with the warn_unused_result attribute, @@ -218,6 +218,15 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (isa<StmtExpr>(E) && Loc.isMacroID()) return; + // Check if this is the UNREFERENCED_PARAMETER from the Microsoft headers. + // That macro is frequently used to suppress "unused parameter" warnings, + // but its implementation makes clang's -Wunused-value fire. Prevent this. + if (isa<ParenExpr>(E->IgnoreImpCasts()) && Loc.isMacroID()) { + SourceLocation SpellLoc = Loc; + if (findMacroSpelling(SpellLoc, "UNREFERENCED_PARAMETER")) + return; + } + // Okay, we have an unused result. Depending on what the base expression is, // we might want to make a more specific diagnostic. Check for one of these // cases now. @@ -483,13 +492,6 @@ StmtResult Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar, Stmt *thenStmt, SourceLocation ElseLoc, Stmt *elseStmt) { - // If the condition was invalid, discard the if statement. We could recover - // better by replacing it with a valid expr, but don't do that yet. - if (!CondVal.get() && !CondVar) { - getCurFunction()->setHasDroppedStmt(); - return StmtError(); - } - ExprResult CondResult(CondVal.release()); VarDecl *ConditionVar = nullptr; @@ -497,22 +499,23 @@ Sema::ActOnIfStmt(SourceLocation IfLoc, FullExprArg CondVal, Decl *CondVar, ConditionVar = cast<VarDecl>(CondVar); CondResult = CheckConditionVariable(ConditionVar, IfLoc, true); CondResult = ActOnFinishFullExpr(CondResult.get(), IfLoc); - if (CondResult.isInvalid()) - return StmtError(); } Expr *ConditionExpr = CondResult.getAs<Expr>(); - if (!ConditionExpr) - return StmtError(); + if (ConditionExpr) { + DiagnoseUnusedExprResult(thenStmt); - DiagnoseUnusedExprResult(thenStmt); + if (!elseStmt) { + DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt, + diag::warn_empty_if_body); + } - if (!elseStmt) { - DiagnoseEmptyStmtBody(ConditionExpr->getLocEnd(), thenStmt, - diag::warn_empty_if_body); + DiagnoseUnusedExprResult(elseStmt); + } else { + // Create a dummy Expr for the condition for error recovery + ConditionExpr = new (Context) OpaqueValueExpr(SourceLocation(), + Context.BoolTy, VK_RValue); } - DiagnoseUnusedExprResult(elseStmt); - return new (Context) IfStmt(Context, IfLoc, ConditionVar, ConditionExpr, thenStmt, ElseLoc, elseStmt); } @@ -698,8 +701,6 @@ static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S, EnumValsTy::iterator &EI, EnumValsTy::iterator &EIEnd, const llvm::APSInt &Val) { - bool FlagType = ED->hasAttr<FlagEnumAttr>(); - if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) { if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) { @@ -711,7 +712,7 @@ static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S, } } - if (FlagType) { + if (ED->hasAttr<FlagEnumAttr>()) { return !S.IsValueInFlagEnum(ED, Val, false); } else { while (EI != EIEnd && EI->first < Val) @@ -1349,7 +1350,7 @@ namespace { }; // end class DeclExtractor - // DeclMatcher checks to see if the decls are used in a non-evauluated + // DeclMatcher checks to see if the decls are used in a non-evaluated // context. class DeclMatcher : public EvaluatedExprVisitor<DeclMatcher> { llvm::SmallPtrSetImpl<VarDecl*> &Decls; @@ -1705,11 +1706,10 @@ Sema::CheckObjCForCollectionOperand(SourceLocation forLoc, Expr *collection) { // If we have a forward-declared type, we can't do this check. // Under ARC, it is an error not to have a forward-declared class. if (iface && - RequireCompleteType(forLoc, QualType(objectType, 0), - getLangOpts().ObjCAutoRefCount - ? diag::err_arc_collection_forward - : 0, - collection)) { + (getLangOpts().ObjCAutoRefCount + ? RequireCompleteType(forLoc, QualType(objectType, 0), + diag::err_arc_collection_forward, collection) + : !isCompleteType(forLoc, QualType(objectType, 0)))) { // Otherwise, if we have any useful type information, check that // the type declares the appropriate method. } else if (iface || !objectType->qual_empty()) { @@ -1867,13 +1867,19 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, } namespace { +// An enum to represent whether something is dealing with a call to begin() +// or a call to end() in a range-based for loop. +enum BeginEndFunction { + BEF_begin, + BEF_end +}; /// Produce a note indicating which begin/end function was implicitly called /// by a C++11 for-range statement. This is often not obvious from the code, /// nor from the diagnostics produced when analysing the implicit expressions /// required in a for-range statement. void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E, - Sema::BeginEndFunction BEF) { + BeginEndFunction BEF) { CallExpr *CE = dyn_cast<CallExpr>(E); if (!CE) return; @@ -1931,10 +1937,11 @@ static bool ObjCEnumerationCollection(Expr *Collection) { /// /// The body of the loop is not available yet, since it cannot be analysed until /// we have determined the type of the for-range-declaration. -StmtResult -Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, - Stmt *First, SourceLocation ColonLoc, Expr *Range, - SourceLocation RParenLoc, BuildForRangeKind Kind) { +StmtResult Sema::ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, + SourceLocation CoawaitLoc, Stmt *First, + SourceLocation ColonLoc, Expr *Range, + SourceLocation RParenLoc, + BuildForRangeKind Kind) { if (!First) return StmtError(); @@ -1956,6 +1963,13 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, return StmtError(); } + // Coroutines: 'for co_await' implicitly co_awaits its range. + if (CoawaitLoc.isValid()) { + ExprResult Coawait = ActOnCoawaitExpr(S, CoawaitLoc, Range); + if (Coawait.isInvalid()) return StmtError(); + Range = Coawait.get(); + } + // Build auto && __range = range-init SourceLocation RangeLoc = Range->getLocStart(); VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc, @@ -1977,7 +1991,7 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, return StmtError(); } - return BuildCXXForRangeStmt(ForLoc, ColonLoc, RangeDecl.get(), + return BuildCXXForRangeStmt(ForLoc, CoawaitLoc, ColonLoc, RangeDecl.get(), /*BeginEndDecl=*/nullptr, /*Cond=*/nullptr, /*Inc=*/nullptr, DS, RParenLoc, Kind); } @@ -1991,7 +2005,7 @@ Sema::ActOnCXXForRangeStmt(SourceLocation ForLoc, /// BeginExpr and EndExpr are set and FRS_Success is returned on success; /// CandidateSet and BEF are set and some non-success value is returned on /// failure. -static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S, +static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, QualType RangeType, VarDecl *BeginVar, @@ -2000,7 +2014,7 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S, OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr, ExprResult *EndExpr, - Sema::BeginEndFunction *BEF) { + BeginEndFunction *BEF) { DeclarationNameInfo BeginNameInfo( &SemaRef.PP.getIdentifierTable().get("begin"), ColonLoc); DeclarationNameInfo EndNameInfo(&SemaRef.PP.getIdentifierTable().get("end"), @@ -2021,7 +2035,7 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S, if (BeginMemberLookup.empty() != EndMemberLookup.empty()) { SourceLocation RangeLoc = BeginVar->getLocation(); - *BEF = BeginMemberLookup.empty() ? Sema::BEF_end : Sema::BEF_begin; + *BEF = BeginMemberLookup.empty() ? BEF_end : BEF_begin; SemaRef.Diag(RangeLoc, diag::err_for_range_member_begin_end_mismatch) << RangeLoc << BeginRange->getType() << *BEF; @@ -2035,29 +2049,35 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S, } - *BEF = Sema::BEF_begin; + *BEF = BEF_begin; Sema::ForRangeStatus RangeStatus = - SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, BeginVar, - Sema::BEF_begin, BeginNameInfo, + SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, BeginNameInfo, BeginMemberLookup, CandidateSet, BeginRange, BeginExpr); - if (RangeStatus != Sema::FRS_Success) + if (RangeStatus != Sema::FRS_Success) { + if (RangeStatus == Sema::FRS_DiagnosticIssued) + SemaRef.Diag(BeginRange->getLocStart(), diag::note_in_for_range) + << ColonLoc << BEF_begin << BeginRange->getType(); return RangeStatus; + } if (FinishForRangeVarDecl(SemaRef, BeginVar, BeginExpr->get(), ColonLoc, diag::err_for_range_iter_deduction_failure)) { NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF); return Sema::FRS_DiagnosticIssued; } - *BEF = Sema::BEF_end; + *BEF = BEF_end; RangeStatus = - SemaRef.BuildForRangeBeginEndCall(S, ColonLoc, ColonLoc, EndVar, - Sema::BEF_end, EndNameInfo, + SemaRef.BuildForRangeBeginEndCall(ColonLoc, ColonLoc, EndNameInfo, EndMemberLookup, CandidateSet, EndRange, EndExpr); - if (RangeStatus != Sema::FRS_Success) + if (RangeStatus != Sema::FRS_Success) { + if (RangeStatus == Sema::FRS_DiagnosticIssued) + SemaRef.Diag(EndRange->getLocStart(), diag::note_in_for_range) + << ColonLoc << BEF_end << EndRange->getType(); return RangeStatus; + } if (FinishForRangeVarDecl(SemaRef, EndVar, EndExpr->get(), ColonLoc, diag::err_for_range_iter_deduction_failure)) { NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF); @@ -2071,6 +2091,7 @@ static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Scope *S, /// and emit no diagnostics. static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, SourceLocation ForLoc, + SourceLocation CoawaitLoc, Stmt *LoopVarDecl, SourceLocation ColonLoc, Expr *Range, @@ -2086,10 +2107,9 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, if (AdjustedRange.isInvalid()) return StmtResult(); - StmtResult SR = - SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc, - AdjustedRange.get(), RParenLoc, - Sema::BFRK_Check); + StmtResult SR = SemaRef.ActOnCXXForRangeStmt( + S, ForLoc, CoawaitLoc, LoopVarDecl, ColonLoc, AdjustedRange.get(), + RParenLoc, Sema::BFRK_Check); if (SR.isInvalid()) return StmtResult(); } @@ -2099,8 +2119,8 @@ static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, // case there are any other (non-fatal) problems with it. SemaRef.Diag(RangeLoc, diag::err_for_range_dereference) << Range->getType() << FixItHint::CreateInsertion(RangeLoc, "*"); - return SemaRef.ActOnCXXForRangeStmt(ForLoc, LoopVarDecl, ColonLoc, - AdjustedRange.get(), RParenLoc, + return SemaRef.ActOnCXXForRangeStmt(S, ForLoc, CoawaitLoc, LoopVarDecl, + ColonLoc, AdjustedRange.get(), RParenLoc, Sema::BFRK_Rebuild); } @@ -2122,10 +2142,20 @@ struct InvalidateOnErrorScope { /// BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement. StmtResult -Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, +Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, + SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *BeginEnd, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, BuildForRangeKind Kind) { + // FIXME: This should not be used during template instantiation. We should + // pick up the set of unqualified lookup results for the != and + operators + // in the initial parse. + // + // Testcase (accepts-invalid): + // template<typename T> void f() { for (auto x : T()) {} } + // namespace N { struct X { X begin(); X end(); int operator*(); }; } + // bool operator!=(N::X, N::X); void operator++(N::X); + // void g() { f<N::X>(); } Scope *S = getCurScope(); DeclStmt *RangeDS = cast<DeclStmt>(RangeDecl); @@ -2225,9 +2255,9 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, } else { OverloadCandidateSet CandidateSet(RangeLoc, OverloadCandidateSet::CSK_Normal); - Sema::BeginEndFunction BEFFailure; + BeginEndFunction BEFFailure; ForRangeStatus RangeStatus = - BuildNonArrayForRange(*this, S, BeginRangeRef.get(), + BuildNonArrayForRange(*this, BeginRangeRef.get(), EndRangeRef.get(), RangeType, BeginVar, EndVar, ColonLoc, &CandidateSet, &BeginExpr, &EndExpr, &BEFFailure); @@ -2252,6 +2282,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, // If building the range failed, try dereferencing the range expression // unless a diagnostic was issued or the end function is problematic. StmtResult SR = RebuildForRangeWithDereference(*this, S, ForLoc, + CoawaitLoc, LoopVarDecl, ColonLoc, Range, RangeLoc, RParenLoc); @@ -2322,7 +2353,10 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, return StmtError(); IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get()); - IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); + if (!IncrExpr.isInvalid() && CoawaitLoc.isValid()) + IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); + if (!IncrExpr.isInvalid()) + IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); if (IncrExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 2 << BeginRangeRef.get()->getType() ; @@ -2361,7 +2395,8 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, return new (Context) CXXForRangeStmt( RangeDS, cast_or_null<DeclStmt>(BeginEndDecl.get()), NotEqExpr.get(), - IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, ColonLoc, RParenLoc); + IncrExpr.get(), LoopVarDS, /*Body=*/nullptr, ForLoc, CoawaitLoc, + ColonLoc, RParenLoc); } /// FinishObjCForCollectionStmt - Attach the body to a objective-C foreach @@ -2919,6 +2954,9 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { if (CurCap->HasImplicitReturnType || NRVOCandidate) FunctionScopes.back()->Returns.push_back(Result); + if (FunctionScopes.back()->FirstReturnLoc.isInvalid()) + FunctionScopes.back()->FirstReturnLoc = ReturnLoc; + return Result; } @@ -2989,14 +3027,9 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, // statement with a non-type-dependent operand. assert(AT->isDeduced() && "should have deduced to dependent type"); return false; - } else if (RetExpr) { - // If the deduction is for a return statement and the initializer is - // a braced-init-list, the program is ill-formed. - if (isa<InitListExpr>(RetExpr)) { - Diag(RetExpr->getExprLoc(), diag::err_auto_fn_return_init_list); - return true; - } + } + if (RetExpr) { // Otherwise, [...] deduce a value for U using the rules of template // argument deduction. DeduceAutoResult DAR = DeduceAutoType(OrigResultType, RetExpr, Deduced); @@ -3035,8 +3068,11 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, // the program is ill-formed. if (AT->isDeduced() && !FD->isInvalidDecl()) { AutoType *NewAT = Deduced->getContainedAutoType(); - if (!FD->isDependentContext() && - !Context.hasSameType(AT->getDeducedType(), NewAT->getDeducedType())) { + CanQualType OldDeducedType = Context.getCanonicalFunctionResultType( + AT->getDeducedType()); + CanQualType NewDeducedType = Context.getCanonicalFunctionResultType( + NewAT->getDeducedType()); + if (!FD->isDependentContext() && OldDeducedType != NewDeducedType) { const LambdaScopeInfo *LambdaSI = getCurLambda(); if (LambdaSI && LambdaSI->HasImplicitReturnType) { Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible) @@ -3179,7 +3215,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } // return (some void expression); is legal in C++. else if (D != diag::ext_return_has_void_expr || - !getLangOpts().CPlusPlus) { + !getLangOpts().CPlusPlus) { NamedDecl *CurDecl = getCurFunctionOrMethodDecl(); int FunctionKind = 0; @@ -3287,6 +3323,9 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { if (Result->getNRVOCandidate()) FunctionScopes.back()->Returns.push_back(Result); + if (FunctionScopes.back()->FirstReturnLoc.isInvalid()) + FunctionScopes.back()->FirstReturnLoc = ReturnLoc; + return Result; } @@ -3512,16 +3551,14 @@ public: CXXCatchStmt *getFoundHandler() const { return FoundHandler; } CanQualType getFoundHandlerType() const { return FoundHandlerType; } - static bool FindPublicBasesOfType(const CXXBaseSpecifier *S, CXXBasePath &, - void *User) { - auto &PBOT = *reinterpret_cast<CatchTypePublicBases *>(User); + bool operator()(const CXXBaseSpecifier *S, CXXBasePath &) { if (S->getAccessSpecifier() == AccessSpecifier::AS_public) { - CatchHandlerType Check(S->getType(), PBOT.CheckAgainstPointer); - auto M = PBOT.TypesToCheck; + CatchHandlerType Check(S->getType(), CheckAgainstPointer); + auto M = TypesToCheck; auto I = M.find(Check); if (I != M.end()) { - PBOT.FoundHandler = I->second; - PBOT.FoundHandlerType = PBOT.Ctx.getCanonicalType(S->getType()); + FoundHandler = I->second; + FoundHandlerType = Ctx.getCanonicalType(S->getType()); return true; } } @@ -3589,8 +3626,7 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, CXXBasePaths Paths; Paths.setOrigin(RD); CatchTypePublicBases CTPB(Context, HandledTypes, HandlerCHT.isPointer()); - if (RD->lookupInBases(CatchTypePublicBases::FindPublicBasesOfType, &CTPB, - Paths)) { + if (RD->lookupInBases(CTPB, Paths)) { const CXXCatchStmt *Problem = CTPB.getFoundHandler(); if (!Paths.isAmbiguous(CTPB.getFoundHandlerType())) { Diag(H->getExceptionDecl()->getTypeSpecStartLoc(), @@ -3766,11 +3802,10 @@ static void buildCapturedStmtCaptureList( continue; } - assert(Cap->isReferenceCapture() && - "non-reference capture not yet implemented"); - Captures.push_back(CapturedStmt::Capture(Cap->getLocation(), - CapturedStmt::VCK_ByRef, + Cap->isReferenceCapture() + ? CapturedStmt::VCK_ByRef + : CapturedStmt::VCK_ByCopy, Cap->getVariable())); CaptureInits.push_back(Cap->getInitExpr()); } |