diff options
author | Hans Wennborg <hans@hanshq.net> | 2019-02-13 10:47:50 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2019-02-13 10:47:50 +0000 |
commit | 61fc5f8f40a473b160a06bda016905d831eeff14 (patch) | |
tree | f23b36a55baca4dd784f500fa9736b2332c667a6 | |
parent | 8ffe5246a3a29bb151f1ad261a5d342f5d328eff (diff) |
Revert r350404
This caused https://bugs.llvm.org/show_bug.cgi?id=40642:
"After 350404, clang drops volatile load"
> Refactor the way we handle diagnosing unused expression results.
>
> Rather than sprinkle calls to DiagnoseUnusedExprResult() around in places
> where we want diagnostics, we now diagnose unused expression statements and
> full expressions in a more generic way when acting on the final expression
> statement. This results in more appropriate diagnostics for [[nodiscard]] where
> we were previously lacking them, such as when the body of a for loop is not a
> compound statement.
>
> This patch fixes PR39837.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/release_80@353935 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Parse/Parser.h | 5 | ||||
-rw-r--r-- | include/clang/Sema/Sema.h | 19 | ||||
-rw-r--r-- | lib/Parse/ParseObjc.cpp | 2 | ||||
-rw-r--r-- | lib/Parse/ParseOpenMP.cpp | 14 | ||||
-rw-r--r-- | lib/Parse/ParseStmt.cpp | 26 | ||||
-rw-r--r-- | lib/Sema/SemaCoroutine.cpp | 17 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 14 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaOpenMP.cpp | 55 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 65 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 15 | ||||
-rw-r--r-- | test/CXX/stmt.stmt/stmt.select/p3.cpp | 9 | ||||
-rw-r--r-- | test/CodeCompletion/pragma-macro-token-caching.c | 2 | ||||
-rw-r--r-- | test/Parser/cxx1z-init-statement.cpp | 8 | ||||
-rw-r--r-- | test/Parser/switch-recovery.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/cxx1z-init-statement.cpp | 8 | ||||
-rw-r--r-- | test/SemaCXX/for-range-examples.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/warn-unused-result.cpp | 40 |
21 files changed, 122 insertions, 196 deletions
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h index 438ff0e2ed..46e4431913 100644 --- a/include/clang/Parse/Parser.h +++ b/include/clang/Parse/Parser.h @@ -360,11 +360,6 @@ class Parser : public CodeCompletionHandler { /// just a regular sub-expression. SourceLocation ExprStatementTokLoc; - /// Tests whether an expression value is discarded based on token lookahead. - /// It will return true if the lexer is currently processing the }) - /// terminating a GNU statement expression and false otherwise. - bool isExprValueDiscarded(); - public: Parser(Preprocessor &PP, Sema &Actions, bool SkipFunctionBodies); ~Parser() override; diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index e5b7465820..ced5773f0c 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -1369,7 +1369,6 @@ public: void PopCompoundScope(); sema::CompoundScopeInfo &getCurCompoundScope() const; - bool isCurCompoundStmtAStmtExpr() const; bool hasAnyUnrecoverableErrorsInThisFunction() const; @@ -3690,17 +3689,16 @@ public: return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); } FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { - return FullExprArg( - ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).get()); + return FullExprArg(ActOnFinishFullExpr(Arg, CC).get()); } FullExprArg MakeFullDiscardedValueExpr(Expr *Arg) { ExprResult FE = - ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), - /*DiscardedValue*/ true); + ActOnFinishFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation(), + /*DiscardedValue*/ true); return FullExprArg(FE.get()); } - StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true); + StmtResult ActOnExprStmt(ExprResult Arg); StmtResult ActOnExprStmtError(); StmtResult ActOnNullStmt(SourceLocation SemiLoc, @@ -5346,12 +5344,13 @@ public: CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, bool BoundToLvalueReference); - ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) { - return ActOnFinishFullExpr( - Expr, Expr ? Expr->getExprLoc() : SourceLocation(), DiscardedValue); + ExprResult ActOnFinishFullExpr(Expr *Expr) { + return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() + : SourceLocation()); } ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, - bool DiscardedValue, bool IsConstexpr = false); + bool DiscardedValue = false, + bool IsConstexpr = false); StmtResult ActOnFinishFullStmt(Stmt *Stmt); // Marks SS invalid if it represents an incomplete type. diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index bd55f71793..c8d7bda3d6 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement(SourceLocation AtLoc) { // Otherwise, eat the semicolon. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Res, isExprValueDiscarded()); + return Actions.ActOnExprStmt(Res); } ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp index dd2a8aae9f..17c3fa3cf2 100644 --- a/lib/Parse/ParseOpenMP.cpp +++ b/lib/Parse/ParseOpenMP.cpp @@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); ExprResult CombinerResult = Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), - D->getLocation(), /*DiscardedValue*/ false); + D->getLocation(), /*DiscardedValue=*/true); Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, CombinerResult.get()); if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && @@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { if (Actions.getLangOpts().CPlusPlus) { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); } else { ConsumeToken(); ParseOpenMPReductionInitializerForDecl(OmpPrivParm); @@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirective(AccessSpecifier AS) { } else { InitializerResult = Actions.ActOnFinishFullExpr( ParseAssignmentExpression().get(), D->getLocation(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); } Actions.ActOnOpenMPDeclareReductionInitializerEnd( D, InitializerResult.get(), OmpPrivParm); @@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr(StringRef ClauseName, ExprResult LHS(ParseCastExpression( /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, NotTypeCast)); ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); - Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); // Parse ')'. RLoc = Tok.getLocation(); @@ -1711,8 +1711,7 @@ OMPClause *Parser::ParseOpenMPSingleExprWithArgClause(OpenMPClauseKind Kind, SourceLocation ELoc = Tok.getLocation(); ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); - Val = - Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ false); + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); } // Parse ')'. @@ -1997,8 +1996,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind, Data.ColonLoc = Tok.getLocation(); SourceLocation ELoc = ConsumeToken(); ExprResult Tail = ParseAssignmentExpression(); - Tail = - Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ false); + Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); if (Tail.isUsable()) Data.TailExpr = Tail.get(); else diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 2974e6a245..313793c3e8 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() { // Otherwise, eat the semicolon. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - return Actions.ActOnExprStmt(Expr, isExprValueDiscarded()); + return Actions.ActOnExprStmt(Expr); } /// ParseSEHTryBlockCommon @@ -958,16 +958,6 @@ bool Parser::ConsumeNullStmt(StmtVector &Stmts) { return true; } -bool Parser::isExprValueDiscarded() { - if (Actions.isCurCompoundStmtAStmtExpr()) { - // Look to see if the next two tokens close the statement expression; - // if so, this expression statement is the last statement in a - // statment expression. - return Tok.isNot(tok::r_brace) || NextToken().isNot(tok::r_paren); - } - return true; -} - /// ParseCompoundStatementBody - Parse a sequence of statements and invoke the /// ActOnCompoundStmt action. This expects the '{' to be the current token, and /// consume the '}' at the end of the block. It does not manipulate the scope @@ -1072,7 +1062,7 @@ StmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); - R = Actions.ActOnExprStmt(Res, isExprValueDiscarded()); + R = Actions.ActOnExprStmt(Res); } } @@ -1708,16 +1698,8 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) { if (!Value.isInvalid()) { if (ForEach) FirstPart = Actions.ActOnForEachLValueExpr(Value.get()); - else { - // We already know this is not an init-statement within a for loop, so - // if we are parsing a C++11 range-based for loop, we should treat this - // expression statement as being a discarded value expression because - // we will err below. This way we do not warn on an unused expression - // that was an error in the first place, like with: for (expr : expr); - bool IsRangeBasedFor = - getLangOpts().CPlusPlus11 && !ForEach && Tok.is(tok::colon); - FirstPart = Actions.ActOnExprStmt(Value, !IsRangeBasedFor); - } + else + FirstPart = Actions.ActOnExprStmt(Value); } if (Tok.is(tok::semi)) { diff --git a/lib/Sema/SemaCoroutine.cpp b/lib/Sema/SemaCoroutine.cpp index 181efa6d3d..e282bb62f0 100644 --- a/lib/Sema/SemaCoroutine.cpp +++ b/lib/Sema/SemaCoroutine.cpp @@ -646,7 +646,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope *SC, SourceLocation KWLoc, return StmtError(); Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), /*IsImplicit*/ true); - Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ false); + Suspend = ActOnFinishFullExpr(Suspend.get()); if (Suspend.isInvalid()) { Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) << ((Name == "initial_suspend") ? 0 : 1); @@ -867,7 +867,7 @@ StmtResult Sema::BuildCoreturnStmt(SourceLocation Loc, Expr *E, if (PC.isInvalid()) return StmtError(); - Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ false).get(); + Expr *PCE = ActOnFinishFullExpr(PC.get()).get(); Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit); return Res; @@ -1236,7 +1236,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { ExprResult NewExpr = S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc); - NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ false); + NewExpr = S.ActOnFinishFullExpr(NewExpr.get()); if (NewExpr.isInvalid()) return false; @@ -1262,8 +1262,7 @@ bool CoroutineStmtBuilder::makeNewAndDeleteExpr() { ExprResult DeleteExpr = S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, Loc); - DeleteExpr = - S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false); + DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get()); if (DeleteExpr.isInvalid()) return false; @@ -1348,8 +1347,7 @@ bool CoroutineStmtBuilder::makeOnException() { ExprResult UnhandledException = buildPromiseCall(S, Fn.CoroutinePromise, Loc, "unhandled_exception", None); - UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc, - /*DiscardedValue*/ false); + UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), Loc); if (UnhandledException.isInvalid()) return false; @@ -1402,8 +1400,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() { "get_return_object type must no longer be dependent"); if (FnRetType->isVoidType()) { - ExprResult Res = - S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ false); + ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc); if (Res.isInvalid()) return false; @@ -1435,7 +1432,7 @@ bool CoroutineStmtBuilder::makeGroDeclAndReturnStmt() { if (Res.isInvalid()) return false; - Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false); + Res = S.ActOnFinishFullExpr(Res.get()); if (Res.isInvalid()) return false; diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 23c99d45a7..7ddf2e88b7 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -11200,9 +11200,9 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) { // struct T { S a, b; } t = { Temp(), Temp() } // // we should destroy the first Temp before constructing the second. - ExprResult Result = - ActOnFinishFullExpr(Init, VDecl->getLocation(), - /*DiscardedValue*/ false, VDecl->isConstexpr()); + ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), + false, + VDecl->isConstexpr()); if (Result.isInvalid()) { VDecl->setInvalidDecl(); return; diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 8b3556f715..950a63aa45 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition(Sema &S, E = Seq.Perform(S, Entity, Kind, Init); if (E.isInvalid()) return true; - E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false); + E = S.ActOnFinishFullExpr(E.get(), Loc); if (E.isInvalid()) return true; RefVD->setInit(E.get()); @@ -3686,7 +3686,7 @@ void Sema::ActOnFinishCXXInClassMemberInitializer(Decl *D, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ false); + Init = ActOnFinishFullExpr(Init.get(), InitLoc); if (Init.isInvalid()) { FD->setInvalidDecl(); return; @@ -4044,8 +4044,7 @@ Sema::BuildMemberInitializer(ValueDecl *Member, Expr *Init, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin(), - /*DiscardedValue*/ false); + MemberInit = ActOnFinishFullExpr(MemberInit.get(), InitRange.getBegin()); if (MemberInit.isInvalid()) return true; @@ -4100,8 +4099,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - DelegationInit = ActOnFinishFullExpr( - DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ false); + DelegationInit = ActOnFinishFullExpr(DelegationInit.get(), + InitRange.getBegin()); if (DelegationInit.isInvalid()) return true; @@ -4230,8 +4229,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, // C++11 [class.base.init]p7: // The initialization of each base and member constitutes a // full-expression. - BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(), - /*DiscardedValue*/ false); + BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin()); if (BaseInit.isInvalid()) return true; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 2bcd47abe3..db0c62630a 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4723,9 +4723,8 @@ bool Sema::CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, if (Result.isInvalid()) return true; - Result = - ActOnFinishFullExpr(Result.getAs<Expr>(), Param->getOuterLocStart(), - /*DiscardedValue*/ false); + Result = ActOnFinishFullExpr(Result.getAs<Expr>(), + Param->getOuterLocStart()); if (Result.isInvalid()) return true; diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 8c89a3cee3..cce7a21654 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -7815,8 +7815,6 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE, SourceLocation CC, FullExpr = IgnoredValueConversions(FullExpr.get()); if (FullExpr.isInvalid()) return ExprError(); - - DiagnoseUnusedExprResult(FullExpr.get()); } FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index af233b96d6..4e002a853d 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, /*NRVO=*/false), CurrentLocation, Src); if (!Init.isInvalid()) - Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); + Init = ActOnFinishFullExpr(Init.get()); if (Init.isInvalid()) return ExprError(); diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 36048a38b9..aedec746af 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -5367,7 +5367,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get(), UB.get()); EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), CondOp.get()); - EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); + EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); // If we have a combined directive that combines 'distribute', 'for' or // 'simd' we need to be able to access the bounds of the schedule of the @@ -5396,8 +5396,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, LastIteration.get(), CombUB.get()); CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), CombCondOp.get()); - CombEUB = - SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); + CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); // We expect to have at least 2 more parameters than the 'parallel' @@ -5431,7 +5430,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, ? LB.get() : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); - Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); + Init = SemaRef.ActOnFinishFullExpr(Init.get()); if (isOpenMPLoopBoundSharingDirective(DKind)) { Expr *CombRHS = @@ -5442,8 +5441,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); CombInit = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); - CombInit = - SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); + CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); } } @@ -5475,7 +5473,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, if (!Inc.isUsable()) return 0; Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); - Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); + Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); if (!Inc.isUsable()) return 0; @@ -5493,8 +5491,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // LB = LB + ST NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); - NextLB = - SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); + NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); if (!NextLB.isUsable()) return 0; // UB + ST @@ -5504,8 +5501,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // UB = UB + ST NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); - NextUB = - SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); + NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); if (!NextUB.isUsable()) return 0; if (isOpenMPLoopBoundSharingDirective(DKind)) { @@ -5516,8 +5512,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // LB = LB + ST CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), CombNextLB.get()); - CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), - /*DiscardedValue*/ false); + CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); if (!CombNextLB.isUsable()) return 0; // UB + ST @@ -5528,8 +5523,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, // UB = UB + ST CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), CombNextUB.get()); - CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), - /*DiscardedValue*/ false); + CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); if (!CombNextUB.isUsable()) return 0; } @@ -5550,8 +5544,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, assert(DistInc.isUsable() && "distribute inc expr was not built"); DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), DistInc.get()); - DistInc = - SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); + DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); assert(DistInc.isUsable() && "distribute inc expr was not built"); // Build expression: UB = min(UB, prevUB) for #for in composite or combined @@ -5563,8 +5556,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), CondOp.get()); - PrevEUB = - SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); + PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); // Build IV <= PrevUB to be used in parallel for is in combination with // a distribute directive with schedule(static, 1) @@ -5680,10 +5672,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, Built.IterationVarRef = IV.get(); Built.LastIteration = LastIteration.get(); Built.NumIterations = NumIterations.get(); - Built.CalcLastIteration = SemaRef - .ActOnFinishFullExpr(CalcLastIteration.get(), - /*DiscardedValue*/ false) - .get(); + Built.CalcLastIteration = + SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); Built.PreCond = PreCond.get(); Built.PreInits = buildPreInits(C, Captures); Built.Cond = Cond.get(); @@ -10358,8 +10348,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) continue; - AssignmentOp = - ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); + AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; @@ -11357,8 +11347,7 @@ static bool actOnOMPReductionKindClause( BO_Assign, LHSDRE, ConditionalOp); } if (ReductionOp.isUsable()) - ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), - /*DiscardedValue*/ false); + ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); } if (!ReductionOp.isUsable()) continue; @@ -11688,7 +11677,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause( buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); ExprResult CalcStep = BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); - CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); + CalcStep = ActOnFinishFullExpr(CalcStep.get()); // Warn about zero linear step (it would be probably better specified as // making corresponding variables 'const'). @@ -11776,7 +11765,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, else Update = *CurPrivate; Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); // Build final: Var = InitExpr + NumIterations * Step ExprResult Final; @@ -11787,7 +11776,7 @@ static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, else Final = *CurPrivate; Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); if (!Update.isUsable() || !Final.isUsable()) { Updates.push_back(nullptr); @@ -11955,7 +11944,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, if (AssignmentOp.isInvalid()) continue; AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), - /*DiscardedValue*/ false); + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; @@ -12063,8 +12052,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); if (AssignmentOp.isInvalid()) continue; - AssignmentOp = - ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); + AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, + /*DiscardedValue=*/true); if (AssignmentOp.isInvalid()) continue; diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index 9e30c9a396..dacf8d0cf4 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -42,11 +42,12 @@ using namespace clang; using namespace sema; -StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) { +StmtResult Sema::ActOnExprStmt(ExprResult FE) { if (FE.isInvalid()) return StmtError(); - FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue); + FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), + /*DiscardedValue*/ true); if (FE.isInvalid()) return StmtError(); @@ -347,10 +348,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(); @@ -373,6 +370,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R, Diag(D->getLocation(), diag::ext_mixed_decls_code); } } + // Warn about unused expressions in statements. + for (unsigned i = 0; i != NumElts; ++i) { + // Ignore statements that are last in a statement expression. + if (isStmtExpr && i == NumElts - 1) + continue; + + DiagnoseUnusedExprResult(Elts[i]); + } // Check for suspicious empty body (null statement) in `for' and `while' // statements. Don't do anything for template instantiations, this just adds @@ -464,12 +469,15 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal, /// ActOnCaseStmtBody - This installs a statement as the body of a case. void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) { + DiagnoseUnusedExprResult(SubStmt); cast<CaseStmt>(S)->setSubStmt(SubStmt); } StmtResult Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope) { + DiagnoseUnusedExprResult(SubStmt); + if (getCurFunction()->SwitchStack.empty()) { Diag(DefaultLoc, diag::err_default_not_in_switch); return SubStmt; @@ -563,6 +571,9 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr, if (IsConstexpr || isa<ObjCAvailabilityCheckExpr>(Cond.get().second)) setFunctionHasBranchProtectedScope(); + DiagnoseUnusedExprResult(thenStmt); + DiagnoseUnusedExprResult(elseStmt); + return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first, Cond.get().second, thenStmt, ElseLoc, elseStmt); } @@ -1290,6 +1301,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond, !Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc())) CommaVisitor(*this).Visit(CondVal.second); + DiagnoseUnusedExprResult(Body); + if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); @@ -1309,7 +1322,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, return StmtError(); Cond = CondResult.get(); - CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false); + CondResult = ActOnFinishFullExpr(Cond, DoLoc); if (CondResult.isInvalid()) return StmtError(); Cond = CondResult.get(); @@ -1319,6 +1332,8 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc())) CommaVisitor(*this).Visit(Cond); + DiagnoseUnusedExprResult(Body); + return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen); } @@ -1763,6 +1778,11 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, CommaVisitor(*this).Visit(Second.get().second); Expr *Third = third.release().getAs<Expr>(); + + DiagnoseUnusedExprResult(First); + DiagnoseUnusedExprResult(Third); + DiagnoseUnusedExprResult(Body); + if (isa<NullStmt>(Body)) getCurCompoundScope().setHasEmptyLoopBodies(); @@ -1782,7 +1802,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) { if (result.isInvalid()) return StmtError(); E = result.get(); - ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); + ExprResult FullExpr = ActOnFinishFullExpr(E); if (FullExpr.isInvalid()) return StmtError(); return StmtResult(static_cast<Stmt*>(FullExpr.get())); @@ -1936,8 +1956,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc, if (CollectionExprResult.isInvalid()) return StmtError(); - CollectionExprResult = - ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false); + CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get()); if (CollectionExprResult.isInvalid()) return StmtError(); @@ -2574,8 +2593,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, if (!NotEqExpr.isInvalid()) NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get()); if (!NotEqExpr.isInvalid()) - NotEqExpr = - ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false); + NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get()); if (NotEqExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 0 << BeginRangeRef.get()->getType(); @@ -2598,7 +2616,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, // co_await during the initial parse. IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); if (!IncrExpr.isInvalid()) - IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false); + IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); if (IncrExpr.isInvalid()) { Diag(RangeLoc, diag::note_for_range_invalid_iterator) << RangeLoc << 2 << BeginRangeRef.get()->getType() ; @@ -2853,7 +2871,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, return StmtError(); } - ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); + ExprResult ExprRes = ActOnFinishFullExpr(E); if (ExprRes.isInvalid()) return StmtError(); E = ExprRes.get(); @@ -3203,8 +3221,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && (HasDeducedReturnType || CurCap->HasImplicitReturnType)) { if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3331,8 +3348,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3562,8 +3578,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { ExpressionEvaluationContext::DiscardedStatement && FnRetType->getContainedAutoType()) { if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3657,8 +3672,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3737,8 +3751,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { } if (RetValExp) { - ExprResult ER = - ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false); + ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); if (ER.isInvalid()) return StmtError(); RetValExp = ER.get(); @@ -3791,7 +3804,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) { if (Result.isInvalid()) return StmtError(); - Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); + Result = ActOnFinishFullExpr(Result.get()); if (Result.isInvalid()) return StmtError(); Throw = Result.get(); @@ -3863,7 +3876,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) { } // The operand to @synchronized is a full-expression. - return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); + return ActOnFinishFullExpr(operand); } StmtResult diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index df14768cbe..9de4e8d654 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -328,7 +328,7 @@ public: /// other mechanism. /// /// \returns the transformed statement. - StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false); + StmtResult TransformStmt(Stmt *S); /// Transform the given statement. /// @@ -3269,8 +3269,8 @@ private: bool DeducibleTSTContext); }; -template <typename Derived> -StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) { +template<typename Derived> +StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { if (!S) return S; @@ -3294,7 +3294,7 @@ StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool DiscardedValue) { if (E.isInvalid()) return StmtError(); - return getSema().ActOnExprStmt(E, DiscardedValue); + return getSema().ActOnExprStmt(E); } } @@ -4715,8 +4715,7 @@ TreeTransform<Derived>::TransformVariableArrayType(TypeLocBuilder &TLB, } if (SizeResult.isInvalid()) return QualType(); - SizeResult = - SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ false); + SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get()); if (SizeResult.isInvalid()) return QualType(); @@ -6521,9 +6520,7 @@ TreeTransform<Derived>::TransformCompoundStmt(CompoundStmt *S, bool SubStmtChanged = false; SmallVector<Stmt*, 8> Statements; for (auto *B : S->body()) { - StmtResult Result = - getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back()); - + StmtResult Result = getDerived().TransformStmt(B); if (Result.isInvalid()) { // Immediately fail if this was a DeclStmt, since it's very // likely that this will cause problems for future statements. diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp index 4804cc559d..7a6a408ec9 100644 --- a/test/CXX/stmt.stmt/stmt.select/p3.cpp +++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -verify %s -// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++1z -Wc++14-compat -verify %s -DCPP17 +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s -DCPP17 int f(); @@ -71,6 +71,7 @@ void whileInitStatement() { // last loop above. It would be nice to remove this. void whileInitStatement2() { while (; false) {} // expected-error {{expected expression}} - // expected-error@-1 {{expected ';' after expression}} - // expected-error@-2 {{expected expression}} + // expected-warning@-1 {{expression result unused}} + // expected-error@-2 {{expected ';' after expression}} + // expected-error@-3 {{expected expression}} } diff --git a/test/CodeCompletion/pragma-macro-token-caching.c b/test/CodeCompletion/pragma-macro-token-caching.c index 59b6621b56..432706e85c 100644 --- a/test/CodeCompletion/pragma-macro-token-caching.c +++ b/test/CodeCompletion/pragma-macro-token-caching.c @@ -12,7 +12,7 @@ void completeParam(int param) { void completeParamPragmaError(int param) { Outer(__extension__({ _Pragma(2) })); // expected-error {{_Pragma takes a parenthesized string literal}} - param; // expected-warning {{expression result unused}} + param; } // RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | FileCheck %s diff --git a/test/Parser/cxx1z-init-statement.cpp b/test/Parser/cxx1z-init-statement.cpp index ade60dc762..3d119ef8e7 100644 --- a/test/Parser/cxx1z-init-statement.cpp +++ b/test/Parser/cxx1z-init-statement.cpp @@ -13,9 +13,9 @@ int f() { if (T(n) = 0; n) {} // init-statement expressions - if (T{f()}; f()) {} // expected-warning {{expression result unused}} - if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}} - if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} expected-warning {{expression result unused}} + if (T{f()}; f()) {} + if (T{f()}, g, h; f()) {} // expected-warning 2{{unused}} + if (T(f()), g, h + 1; f()) {} // expected-warning 2{{unused}} // condition declarations if (T(n){g}) {} @@ -35,7 +35,7 @@ int f() { // Likewise for 'switch' switch (int n; n) {} - switch (g; int g = 5) {} // expected-warning {{expression result unused}} + switch (g; int g = 5) {} if (int a, b; int c = a) { // expected-note 6{{previous}} int a; // expected-error {{redefinition}} diff --git a/test/Parser/switch-recovery.cpp b/test/Parser/switch-recovery.cpp index eacd017ab2..a3a0178cd1 100644 --- a/test/Parser/switch-recovery.cpp +++ b/test/Parser/switch-recovery.cpp @@ -105,7 +105,7 @@ void test9(int x) { // expected-note {{'x' declared here}} expected-error {{expected expression}} 8:: x; // expected-error {{expected ';' after expression}} \ expected-error {{no member named 'x' in the global namespace; did you mean simply 'x'?}} \ - expected-warning {{expression result unused}} + expected-warning 2 {{expression result unused}} 9:: :y; // expected-error {{expected ';' after expression}} \ expected-error {{expected unqualified-id}} \ expected-warning {{expression result unused}} diff --git a/test/SemaCXX/cxx1z-init-statement.cpp b/test/SemaCXX/cxx1z-init-statement.cpp index eea2589ab7..d37acd08ce 100644 --- a/test/SemaCXX/cxx1z-init-statement.cpp +++ b/test/SemaCXX/cxx1z-init-statement.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -std=c++1z -Wno-unused-value -verify %s -// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -verify %s +// RUN: %clang_cc1 -std=c++1z -verify %s +// RUN: %clang_cc1 -std=c++17 -verify %s void testIf() { int x = 0; @@ -12,7 +12,7 @@ void testIf() { int x = 0; // expected-error {{redefinition of 'x'}} if (x; int a = 0) ++a; - if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} + if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} expected-warning {{unused}} int a = 0; // expected-error {{redefinition of 'a'}} else int a = 0; // expected-error {{redefinition of 'a'}} @@ -48,7 +48,7 @@ void testSwitch() { ++a; } - switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} + switch (x, +x; int a = 0) { // expected-note {{previous definition is here}} expected-warning {{unused}} case 0: int a = 0; // expected-error {{redefinition of 'a'}} // expected-note {{previous definition is here}} case 1: diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp index 5424b7a8ee..477789b56c 100644 --- a/test/SemaCXX/for-range-examples.cpp +++ b/test/SemaCXX/for-range-examples.cpp @@ -244,7 +244,7 @@ void foo () { int b = 1, a[b]; a[0] = 0; - [&] { for (int c : a) 0; } (); // expected-warning {{expression result unused}} + [&] { for (int c : a) 0; } (); } diff --git a/test/SemaCXX/warn-unused-result.cpp b/test/SemaCXX/warn-unused-result.cpp index f1de4618a7..88f5ab1e85 100644 --- a/test/SemaCXX/warn-unused-result.cpp +++ b/test/SemaCXX/warn-unused-result.cpp @@ -33,36 +33,6 @@ void test() { const S &s4 = g1(); } -void testSubstmts(int i) { - switch (i) { - case 0: - f(); // expected-warning {{ignoring return value}} - default: - f(); // expected-warning {{ignoring return value}} - } - - if (i) - f(); // expected-warning {{ignoring return value}} - else - f(); // expected-warning {{ignoring return value}} - - while (i) - f(); // expected-warning {{ignoring return value}} - - do - f(); // expected-warning {{ignoring return value}} - while (i); - - for (f(); // expected-warning {{ignoring return value}} - ; - f() // expected-warning {{ignoring return value}} - ) - f(); // expected-warning {{ignoring return value}} - - f(), // expected-warning {{ignoring return value}} - (void)f(); -} - struct X { int foo() __attribute__((warn_unused_result)); }; @@ -236,13 +206,3 @@ void f() { (void)++p; } } // namespace - -namespace PR39837 { -[[clang::warn_unused_result]] int f(int); - -void g() { - int a[2]; - for (int b : a) - f(b); // expected-warning {{ignoring return value}} -} -} // namespace PR39837 |