diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 149 |
1 files changed, 86 insertions, 63 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 9e30c9a396c0..480155df8990 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1,9 +1,8 @@ //===--- SemaStmt.cpp - Semantic Analysis for Statements ------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -11,6 +10,7 @@ // //===----------------------------------------------------------------------===// +#include "clang/Sema/Ownership.h" #include "clang/Sema/SemaInternal.h" #include "clang/AST/ASTContext.h" #include "clang/AST/ASTDiagnostic.h" @@ -347,10 +347,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const { return getCurFunction()->CompoundScopes.back(); } -bool Sema::isCurCompoundStmtAStmtExpr() const { - return getCurCompoundScope().IsStmtExpr; -} - StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef<Stmt *> Elts, bool isStmtExpr) { const unsigned NumElts = Elts.size(); @@ -943,7 +939,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, bool ShouldCheckConstantCond = HasConstantCond; // Sort all the scalar case values so we can easily detect duplicates. - std::stable_sort(CaseVals.begin(), CaseVals.end(), CmpCaseVals); + llvm::stable_sort(CaseVals, CmpCaseVals); if (!CaseVals.empty()) { for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) { @@ -991,7 +987,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, if (!CaseRanges.empty()) { // Sort all the case ranges by their low value so we can easily detect // overlaps between ranges. - std::stable_sort(CaseRanges.begin(), CaseRanges.end()); + llvm::stable_sort(CaseRanges); // Scan the ranges, computing the high values and removing empty ranges. std::vector<llvm::APSInt> HiVals; @@ -1045,9 +1041,8 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // Find the smallest value >= the lower bound. If I is in the // case range, then we have overlap. - CaseValsTy::iterator I = std::lower_bound(CaseVals.begin(), - CaseVals.end(), CRLo, - CaseCompareFunctor()); + CaseValsTy::iterator I = + llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor()); if (I != CaseVals.end() && I->first < CRHi) { OverlapVal = I->first; // Found overlap with scalar. OverlapStmt = I->second; @@ -1110,7 +1105,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, AdjustAPSInt(Val, CondWidth, CondIsSigned); EnumVals.push_back(std::make_pair(Val, EDI)); } - std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); + llvm::stable_sort(EnumVals, CmpEnumVals); auto EI = EnumVals.begin(), EIEnd = std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); @@ -1167,6 +1162,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, break; } + if (EI->second->hasAttr<UnusedAttr>()) + continue; + // Drop unneeded case values while (CI != CaseVals.end() && CI->first < EI->first) CI++; @@ -1261,7 +1259,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, } if (EnumVals.empty()) return; - std::stable_sort(EnumVals.begin(), EnumVals.end(), CmpEnumVals); + llvm::stable_sort(EnumVals, CmpEnumVals); EnumValsTy::iterator EIend = std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals); @@ -2229,9 +2227,11 @@ BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, return Sema::FRS_Success; case Sema::FRS_NoViableFunction: - SemaRef.Diag(BeginRange->getBeginLoc(), diag::err_for_range_invalid) - << BeginRange->getType() << BEFFound; - CandidateSet->NoteCandidates(SemaRef, OCD_AllCandidates, BeginRange); + CandidateSet->NoteCandidates( + PartialDiagnosticAt(BeginRange->getBeginLoc(), + SemaRef.PDiag(diag::err_for_range_invalid) + << BeginRange->getType() << BEFFound), + SemaRef, OCD_AllCandidates, BeginRange); LLVM_FALLTHROUGH; case Sema::FRS_DiagnosticIssued: @@ -2447,7 +2447,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, ExprResult SizeOfVLAExprR = ActOnUnaryExprOrTypeTraitExpr( EndVar->getLocation(), UETT_SizeOf, - /*isType=*/true, + /*IsType=*/true, CreateParsedType(VAT->desugar(), Context.getTrivialTypeSourceInfo( VAT->desugar(), RangeLoc)) .getAsOpaquePtr(), @@ -2457,7 +2457,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, ExprResult SizeOfEachElementExprR = ActOnUnaryExprOrTypeTraitExpr( EndVar->getLocation(), UETT_SizeOf, - /*isType=*/true, + /*IsType=*/true, CreateParsedType(VAT->desugar(), Context.getTrivialTypeSourceInfo( VAT->getElementType(), RangeLoc)) @@ -2528,9 +2528,12 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, // Otherwise, emit diagnostics if we haven't already. if (RangeStatus == FRS_NoViableFunction) { Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get(); - Diag(Range->getBeginLoc(), diag::err_for_range_invalid) - << RangeLoc << Range->getType() << BEFFailure; - CandidateSet.NoteCandidates(*this, OCD_AllCandidates, Range); + CandidateSet.NoteCandidates( + PartialDiagnosticAt(Range->getBeginLoc(), + PDiag(diag::err_for_range_invalid) + << RangeLoc << Range->getType() + << BEFFailure), + *this, OCD_AllCandidates, Range); } // Return an error if no fix was discovered. if (RangeStatus != FRS_Success) @@ -3387,10 +3390,10 @@ bool LocalTypedefNameReferencer::VisitRecordType(const RecordType *RT) { } TypeLoc Sema::getReturnTypeLoc(FunctionDecl *FD) const { - TypeLoc TL = FD->getTypeSourceInfo()->getTypeLoc().IgnoreParens(); - while (auto ATL = TL.getAs<AttributedTypeLoc>()) - TL = ATL.getModifiedLoc().IgnoreParens(); - return TL.castAs<FunctionProtoTypeLoc>().getReturnLoc(); + return FD->getTypeSourceInfo() + ->getTypeLoc() + .getAsAdjusted<FunctionProtoTypeLoc>() + .getReturnLoc(); } /// Deduce the return type for a function from a returned expression, per @@ -3500,7 +3503,12 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, StmtResult Sema::ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope) { - StmtResult R = BuildReturnStmt(ReturnLoc, RetValExp); + // Correct typos, in case the containing function returns 'auto' and + // RetValExp should determine the deduced type. + ExprResult RetVal = CorrectDelayedTyposInExpr(RetValExp); + if (RetVal.isInvalid()) + return StmtError(); + StmtResult R = BuildReturnStmt(ReturnLoc, RetVal.get()); if (R.isInvalid() || ExprEvalContexts.back().Context == ExpressionEvaluationContext::DiscardedStatement) return R; @@ -3684,7 +3692,8 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (FD) - Diag(ReturnLoc, DiagID) << FD->getIdentifier() << 0/*fn*/; + Diag(ReturnLoc, DiagID) + << FD->getIdentifier() << 0 /*fn*/ << FD->isConsteval(); else Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/; @@ -3998,12 +4007,10 @@ StmtResult Sema::ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef<Stmt *> Handlers) { // Don't report an error if 'try' is used in system headers. if (!getLangOpts().CXXExceptions && - !getSourceManager().isInSystemHeader(TryLoc) && - (!getLangOpts().OpenMPIsDevice || - !getLangOpts().OpenMPHostCXXExceptions || - isInOpenMPTargetExecutionDirective() || - isInOpenMPDeclareTargetContext())) - Diag(TryLoc, diag::err_exceptions_disabled) << "try"; + !getSourceManager().isInSystemHeader(TryLoc) && !getLangOpts().CUDA) { + // Delay error emission for the OpenMP device code. + targetDiag(TryLoc, diag::err_exceptions_disabled) << "try"; + } // Exceptions aren't allowed in CUDA device code. if (getLangOpts().CUDA) @@ -4216,30 +4223,46 @@ Sema::CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, return RD; } -static void -buildCapturedStmtCaptureList(SmallVectorImpl<CapturedStmt::Capture> &Captures, - SmallVectorImpl<Expr *> &CaptureInits, - ArrayRef<sema::Capture> Candidates) { - for (const sema::Capture &Cap : Candidates) { +static bool +buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI, + SmallVectorImpl<CapturedStmt::Capture> &Captures, + SmallVectorImpl<Expr *> &CaptureInits) { + for (const sema::Capture &Cap : RSI->Captures) { + if (Cap.isInvalid()) + continue; + + // Form the initializer for the capture. + ExprResult Init = S.BuildCaptureInit(Cap, Cap.getLocation(), + RSI->CapRegionKind == CR_OpenMP); + + // FIXME: Bail out now if the capture is not used and the initializer has + // no side-effects. + + // Create a field for this capture. + FieldDecl *Field = S.BuildCaptureField(RSI->TheRecordDecl, Cap); + + // Add the capture to our list of captures. if (Cap.isThisCapture()) { Captures.push_back(CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_This)); - CaptureInits.push_back(Cap.getInitExpr()); - continue; } else if (Cap.isVLATypeCapture()) { Captures.push_back( CapturedStmt::Capture(Cap.getLocation(), CapturedStmt::VCK_VLAType)); - CaptureInits.push_back(nullptr); - continue; - } + } else { + assert(Cap.isVariableCapture() && "unknown kind of capture"); - Captures.push_back(CapturedStmt::Capture(Cap.getLocation(), - Cap.isReferenceCapture() - ? CapturedStmt::VCK_ByRef - : CapturedStmt::VCK_ByCopy, - Cap.getVariable())); - CaptureInits.push_back(Cap.getInitExpr()); + if (S.getLangOpts().OpenMP && RSI->CapRegionKind == CR_OpenMP) + S.setOpenMPCaptureKind(Field, Cap.getVariable(), RSI->OpenMPLevel); + + Captures.push_back(CapturedStmt::Capture(Cap.getLocation(), + Cap.isReferenceCapture() + ? CapturedStmt::VCK_ByRef + : CapturedStmt::VCK_ByCopy, + Cap.getVariable())); + } + CaptureInits.push_back(Init.get()); } + return false; } void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, @@ -4332,25 +4355,31 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, void Sema::ActOnCapturedRegionError() { DiscardCleanupsInEvaluationContext(); PopExpressionEvaluationContext(); + PopDeclContext(); + PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo(); + CapturedRegionScopeInfo *RSI = cast<CapturedRegionScopeInfo>(ScopeRAII.get()); - CapturedRegionScopeInfo *RSI = getCurCapturedRegion(); RecordDecl *Record = RSI->TheRecordDecl; Record->setInvalidDecl(); SmallVector<Decl*, 4> Fields(Record->fields()); ActOnFields(/*Scope=*/nullptr, Record->getLocation(), Record, Fields, SourceLocation(), SourceLocation(), ParsedAttributesView()); - - PopDeclContext(); - PopFunctionScopeInfo(); } StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) { - CapturedRegionScopeInfo *RSI = getCurCapturedRegion(); + // Leave the captured scope before we start creating captures in the + // enclosing scope. + DiscardCleanupsInEvaluationContext(); + PopExpressionEvaluationContext(); + PopDeclContext(); + PoppedFunctionScopePtr ScopeRAII = PopFunctionScopeInfo(); + CapturedRegionScopeInfo *RSI = cast<CapturedRegionScopeInfo>(ScopeRAII.get()); SmallVector<CapturedStmt::Capture, 4> Captures; SmallVector<Expr *, 4> CaptureInits; - buildCapturedStmtCaptureList(Captures, CaptureInits, RSI->Captures); + if (buildCapturedStmtCaptureList(*this, RSI, Captures, CaptureInits)) + return StmtError(); CapturedDecl *CD = RSI->TheCapturedDecl; RecordDecl *RD = RSI->TheRecordDecl; @@ -4362,11 +4391,5 @@ StmtResult Sema::ActOnCapturedRegionEnd(Stmt *S) { CD->setBody(Res->getCapturedStmt()); RD->completeDefinition(); - DiscardCleanupsInEvaluationContext(); - PopExpressionEvaluationContext(); - - PopDeclContext(); - PopFunctionScopeInfo(); - return Res; } |