diff options
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 151 |
1 files changed, 101 insertions, 50 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 480155df8990..6c680f29da4f 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -196,6 +196,25 @@ static bool DiagnoseUnusedComparison(Sema &S, const Expr *E) { return true; } +static bool DiagnoseNoDiscard(Sema &S, const WarnUnusedResultAttr *A, + SourceLocation Loc, SourceRange R1, + SourceRange R2, bool IsCtor) { + if (!A) + return false; + StringRef Msg = A->getMessage(); + + if (Msg.empty()) { + if (IsCtor) + return S.Diag(Loc, diag::warn_unused_constructor) << A << R1 << R2; + return S.Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + } + + if (IsCtor) + return S.Diag(Loc, diag::warn_unused_constructor_msg) << A << Msg << R1 + << R2; + return S.Diag(Loc, diag::warn_unused_result_msg) << A << Msg << R1 << R2; +} + void Sema::DiagnoseUnusedExprResult(const Stmt *S) { if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) return DiagnoseUnusedExprResult(Label->getSubStmt()); @@ -254,14 +273,19 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; E = WarnExpr; + if (const auto *Cast = dyn_cast<CastExpr>(E)) + if (Cast->getCastKind() == CK_NoOp || + Cast->getCastKind() == CK_ConstructorConversion) + E = Cast->getSubExpr()->IgnoreImpCasts(); + if (const CallExpr *CE = dyn_cast<CallExpr>(E)) { if (E->getType()->isVoidType()) return; - if (const Attr *A = CE->getUnusedResultAttr(Context)) { - Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + if (DiagnoseNoDiscard(*this, cast_or_null<WarnUnusedResultAttr>( + CE->getUnusedResultAttr(Context)), + Loc, R1, R2, /*isCtor=*/false)) return; - } // If the callee has attribute pure, const, or warn_unused_result, warn with // a more specific message to make it clear what is happening. If the call @@ -279,9 +303,24 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { return; } } + } else if (const auto *CE = dyn_cast<CXXConstructExpr>(E)) { + if (const CXXConstructorDecl *Ctor = CE->getConstructor()) { + const auto *A = Ctor->getAttr<WarnUnusedResultAttr>(); + A = A ? A : Ctor->getParent()->getAttr<WarnUnusedResultAttr>(); + if (DiagnoseNoDiscard(*this, A, Loc, R1, R2, /*isCtor=*/true)) + return; + } + } else if (const auto *ILE = dyn_cast<InitListExpr>(E)) { + if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) { + + if (DiagnoseNoDiscard(*this, TD->getAttr<WarnUnusedResultAttr>(), Loc, R1, + R2, /*isCtor=*/false)) + return; + } } else if (ShouldSuppress) return; + E = WarnExpr; if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(E)) { if (getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) { Diag(Loc, diag::err_arc_unused_init_message) << R1; @@ -289,10 +328,9 @@ void Sema::DiagnoseUnusedExprResult(const Stmt *S) { } const ObjCMethodDecl *MD = ME->getMethodDecl(); if (MD) { - if (const auto *A = MD->getAttr<WarnUnusedResultAttr>()) { - Diag(Loc, diag::warn_unused_result) << A << R1 << R2; + if (DiagnoseNoDiscard(*this, MD->getAttr<WarnUnusedResultAttr>(), Loc, R1, + R2, /*isCtor=*/false)) return; - } } } else if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E)) { const Expr *Source = POE->getSyntacticForm(); @@ -392,45 +430,44 @@ Sema::ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val) { // If we're not inside a switch, let the 'case' statement handling diagnose // this. Just clean up after the expression as best we can. - if (!getCurFunction()->SwitchStack.empty()) { - Expr *CondExpr = - getCurFunction()->SwitchStack.back().getPointer()->getCond(); - if (!CondExpr) - return ExprError(); - QualType CondType = CondExpr->getType(); - - auto CheckAndFinish = [&](Expr *E) { - if (CondType->isDependentType() || E->isTypeDependent()) - return ExprResult(E); - - if (getLangOpts().CPlusPlus11) { - // C++11 [stmt.switch]p2: the constant-expression shall be a converted - // constant expression of the promoted type of the switch condition. - llvm::APSInt TempVal; - return CheckConvertedConstantExpression(E, CondType, TempVal, - CCEK_CaseValue); - } + if (getCurFunction()->SwitchStack.empty()) + return ActOnFinishFullExpr(Val.get(), Val.get()->getExprLoc(), false, + getLangOpts().CPlusPlus11); - ExprResult ER = E; - if (!E->isValueDependent()) - ER = VerifyIntegerConstantExpression(E); - if (!ER.isInvalid()) - ER = DefaultLvalueConversion(ER.get()); - if (!ER.isInvalid()) - ER = ImpCastExprToType(ER.get(), CondType, CK_IntegralCast); - return ER; - }; + Expr *CondExpr = + getCurFunction()->SwitchStack.back().getPointer()->getCond(); + if (!CondExpr) + return ExprError(); + QualType CondType = CondExpr->getType(); - ExprResult Converted = CorrectDelayedTyposInExpr(Val, CheckAndFinish); - if (Converted.get() == Val.get()) - Converted = CheckAndFinish(Val.get()); - if (Converted.isInvalid()) - return ExprError(); - Val = Converted; - } + auto CheckAndFinish = [&](Expr *E) { + if (CondType->isDependentType() || E->isTypeDependent()) + return ExprResult(E); + + if (getLangOpts().CPlusPlus11) { + // C++11 [stmt.switch]p2: the constant-expression shall be a converted + // constant expression of the promoted type of the switch condition. + llvm::APSInt TempVal; + return CheckConvertedConstantExpression(E, CondType, TempVal, + CCEK_CaseValue); + } - return ActOnFinishFullExpr(Val.get(), Val.get()->getExprLoc(), false, - getLangOpts().CPlusPlus11); + ExprResult ER = E; + if (!E->isValueDependent()) + ER = VerifyIntegerConstantExpression(E); + if (!ER.isInvalid()) + ER = DefaultLvalueConversion(ER.get()); + if (!ER.isInvalid()) + ER = ImpCastExprToType(ER.get(), CondType, CK_IntegralCast); + if (!ER.isInvalid()) + ER = ActOnFinishFullExpr(ER.get(), ER.get()->getExprLoc(), false); + return ER; + }; + + ExprResult Converted = CorrectDelayedTyposInExpr(Val, CheckAndFinish); + if (Converted.get() == Val.get()) + Converted = CheckAndFinish(Val.get()); + return Converted; } StmtResult @@ -926,7 +963,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // condition is constant. llvm::APSInt ConstantCondValue; bool HasConstantCond = false; - if (!HasDependentValue && !TheDefaultStmt) { + if (!TheDefaultStmt) { Expr::EvalResult Result; HasConstantCond = CondExpr->EvaluateAsInt(Result, Context, Expr::SE_AllowSideEffects); @@ -2637,6 +2674,11 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, if (Kind == BFRK_Check) return StmtResult(); + // In OpenMP loop region loop control variable must be private. Perform + // analysis of first part (if any). + if (getLangOpts().OpenMP >= 50 && BeginDeclStmt.isUsable()) + ActOnOpenMPLoopInitialization(ForLoc, BeginDeclStmt.get()); + return new (Context) CXXForRangeStmt( InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.get()), cast_or_null<DeclStmt>(EndDeclStmt.get()), NotEqExpr.get(), @@ -3268,18 +3310,18 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } assert(!FnRetType.isNull()); - if (BlockScopeInfo *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) { - if (CurBlock->FunctionType->getAs<FunctionType>()->getNoReturnAttr()) { + if (auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) { + if (CurBlock->FunctionType->castAs<FunctionType>()->getNoReturnAttr()) { Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr); return StmtError(); } - } else if (CapturedRegionScopeInfo *CurRegion = - dyn_cast<CapturedRegionScopeInfo>(CurCap)) { + } else if (auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) { Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName(); return StmtError(); } else { assert(CurLambda && "unknown kind of captured scope"); - if (CurLambda->CallOperator->getType()->getAs<FunctionType>() + if (CurLambda->CallOperator->getType() + ->castAs<FunctionType>() ->getNoReturnAttr()) { Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr); return StmtError(); @@ -3463,6 +3505,14 @@ bool Sema::DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, return true; } + // CUDA: Kernel function must have 'void' return type. + if (getLangOpts().CUDA) + if (FD->hasAttr<CUDAGlobalAttr>() && !Deduced->isVoidType()) { + Diag(FD->getLocation(), diag::err_kern_type_not_void_return) + << FD->getType() << FD->getSourceRange(); + return true; + } + // If a function with a declared return type that contains a placeholder type // has multiple return statements, the return type is deduced for each return // statement. [...] if the type deduced is not the same in each deduction, @@ -4296,7 +4346,8 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, - ArrayRef<CapturedParamNameType> Params) { + ArrayRef<CapturedParamNameType> Params, + unsigned OpenMPCaptureLevel) { CapturedDecl *CD = nullptr; RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, Params.size()); @@ -4341,7 +4392,7 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CD->setContextParam(ParamNum, Param); } // Enter the capturing scope for this captured region. - PushCapturedRegionScope(CurScope, CD, RD, Kind); + PushCapturedRegionScope(CurScope, CD, RD, Kind, OpenMPCaptureLevel); if (CurScope) PushDeclContext(CurScope, CD); |