Nice, this is finding bugs: https://bugs.chromium.org/p/chromium/issues/detail?id=919262
However, I noticed that for that case, the same warning is printed twice: ../../third_party/crashpad/crashpad/util/win/process_info.cc(227,36): error: expression result unused [-Werror,-Wunused-value] NTSTATUS_LOG(ERROR, status), "NtQueryInformationProcess"; ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ../../third_party/crashpad/crashpad/util/win/process_info.cc(227,36): error: expression result unused [-Werror,-Wunused-value] NTSTATUS_LOG(ERROR, status), "NtQueryInformationProcess"; Is that expected? Code is here: https://cs.chromium.org/chromium/src/third_party/crashpad/crashpad/util/win/process_info.cc?q=crashpad/util/win/process_info.cc&sq=package:chromium&g=0&l=227 https://cs.chromium.org/chromium/src/third_party/crashpad/crashpad/util/win/ntstatus_logging.h?type=cs&q=NTSTATUS_LOG&sq=package:chromium&g=0&l=63 On Fri, Jan 4, 2019 at 12:01 PM Aaron Ballman via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: aaronballman > Date: Fri Jan 4 08:58:14 2019 > New Revision: 350404 > > URL: http://llvm.org/viewvc/llvm-project?rev=350404&view=rev > Log: > 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. > > Modified: > cfe/trunk/include/clang/Parse/Parser.h > cfe/trunk/include/clang/Sema/Sema.h > cfe/trunk/lib/Parse/ParseObjc.cpp > cfe/trunk/lib/Parse/ParseOpenMP.cpp > cfe/trunk/lib/Parse/ParseStmt.cpp > cfe/trunk/lib/Sema/SemaCoroutine.cpp > cfe/trunk/lib/Sema/SemaDecl.cpp > cfe/trunk/lib/Sema/SemaDeclCXX.cpp > cfe/trunk/lib/Sema/SemaExpr.cpp > cfe/trunk/lib/Sema/SemaExprCXX.cpp > cfe/trunk/lib/Sema/SemaLambda.cpp > cfe/trunk/lib/Sema/SemaOpenMP.cpp > cfe/trunk/lib/Sema/SemaStmt.cpp > cfe/trunk/lib/Sema/TreeTransform.h > cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp > cfe/trunk/test/CodeCompletion/pragma-macro-token-caching.c > cfe/trunk/test/Parser/cxx1z-init-statement.cpp > cfe/trunk/test/Parser/switch-recovery.cpp > cfe/trunk/test/SemaCXX/cxx1z-init-statement.cpp > cfe/trunk/test/SemaCXX/for-range-examples.cpp > cfe/trunk/test/SemaCXX/warn-unused-result.cpp > > Modified: cfe/trunk/include/clang/Parse/Parser.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Parse/Parser.h (original) > +++ cfe/trunk/include/clang/Parse/Parser.h Fri Jan 4 08:58:14 2019 > @@ -360,6 +360,11 @@ class Parser : public CodeCompletionHand > /// 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; > > Modified: cfe/trunk/include/clang/Sema/Sema.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/include/clang/Sema/Sema.h (original) > +++ cfe/trunk/include/clang/Sema/Sema.h Fri Jan 4 08:58:14 2019 > @@ -1365,6 +1365,7 @@ public: > void PopCompoundScope(); > > sema::CompoundScopeInfo &getCurCompoundScope() const; > + bool isCurCompoundStmtAStmtExpr() const; > > bool hasAnyUnrecoverableErrorsInThisFunction() const; > > @@ -3685,16 +3686,17 @@ public: > return MakeFullExpr(Arg, Arg ? Arg->getExprLoc() : SourceLocation()); > } > FullExprArg MakeFullExpr(Expr *Arg, SourceLocation CC) { > - return FullExprArg(ActOnFinishFullExpr(Arg, CC).get()); > + return FullExprArg( > + ActOnFinishFullExpr(Arg, CC, /*DiscardedValue*/ false).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); > + StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue = true); > StmtResult ActOnExprStmtError(); > > StmtResult ActOnNullStmt(SourceLocation SemiLoc, > @@ -5340,13 +5342,12 @@ public: > CreateMaterializeTemporaryExpr(QualType T, Expr *Temporary, > bool BoundToLvalueReference); > > - ExprResult ActOnFinishFullExpr(Expr *Expr) { > - return ActOnFinishFullExpr(Expr, Expr ? Expr->getExprLoc() > - : SourceLocation()); > + ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue) { > + return ActOnFinishFullExpr( > + Expr, Expr ? Expr->getExprLoc() : SourceLocation(), > DiscardedValue); > } > ExprResult ActOnFinishFullExpr(Expr *Expr, SourceLocation CC, > - bool DiscardedValue = false, > - bool IsConstexpr = false); > + bool DiscardedValue, bool IsConstexpr = > false); > StmtResult ActOnFinishFullStmt(Stmt *Stmt); > > // Marks SS invalid if it represents an incomplete type. > > Modified: cfe/trunk/lib/Parse/ParseObjc.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseObjc.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseObjc.cpp (original) > +++ cfe/trunk/lib/Parse/ParseObjc.cpp Fri Jan 4 08:58:14 2019 > @@ -2741,7 +2741,7 @@ StmtResult Parser::ParseObjCAtStatement( > > // Otherwise, eat the semicolon. > ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); > - return Actions.ActOnExprStmt(Res); > + return Actions.ActOnExprStmt(Res, isExprValueDiscarded()); > } > > ExprResult Parser::ParseObjCAtExpression(SourceLocation AtLoc) { > > Modified: cfe/trunk/lib/Parse/ParseOpenMP.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseOpenMP.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseOpenMP.cpp (original) > +++ cfe/trunk/lib/Parse/ParseOpenMP.cpp Fri Jan 4 08:58:14 2019 > @@ -314,7 +314,7 @@ Parser::ParseOpenMPDeclareReductionDirec > Actions.ActOnOpenMPDeclareReductionCombinerStart(getCurScope(), D); > ExprResult CombinerResult = > Actions.ActOnFinishFullExpr(ParseAssignmentExpression().get(), > - D->getLocation(), > /*DiscardedValue=*/true); > + D->getLocation(), /*DiscardedValue*/ > false); > Actions.ActOnOpenMPDeclareReductionCombinerEnd(D, > CombinerResult.get()); > > if (CombinerResult.isInvalid() && Tok.isNot(tok::r_paren) && > @@ -356,7 +356,7 @@ Parser::ParseOpenMPDeclareReductionDirec > if (Actions.getLangOpts().CPlusPlus) { > InitializerResult = Actions.ActOnFinishFullExpr( > ParseAssignmentExpression().get(), D->getLocation(), > - /*DiscardedValue=*/true); > + /*DiscardedValue*/ false); > } else { > ConsumeToken(); > ParseOpenMPReductionInitializerForDecl(OmpPrivParm); > @@ -364,7 +364,7 @@ Parser::ParseOpenMPDeclareReductionDirec > } else { > InitializerResult = Actions.ActOnFinishFullExpr( > ParseAssignmentExpression().get(), D->getLocation(), > - /*DiscardedValue=*/true); > + /*DiscardedValue*/ false); > } > Actions.ActOnOpenMPDeclareReductionInitializerEnd( > D, InitializerResult.get(), OmpPrivParm); > @@ -1455,7 +1455,7 @@ ExprResult Parser::ParseOpenMPParensExpr > ExprResult LHS(ParseCastExpression( > /*isUnaryExpression=*/false, /*isAddressOfOperand=*/false, > NotTypeCast)); > ExprResult Val(ParseRHSOfBinaryExpression(LHS, prec::Conditional)); > - Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); > + Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ > false); > > // Parse ')'. > RLoc = Tok.getLocation(); > @@ -1711,7 +1711,8 @@ OMPClause *Parser::ParseOpenMPSingleExpr > SourceLocation ELoc = Tok.getLocation(); > ExprResult LHS(ParseCastExpression(false, false, NotTypeCast)); > Val = ParseRHSOfBinaryExpression(LHS, prec::Conditional); > - Val = Actions.ActOnFinishFullExpr(Val.get(), ELoc); > + Val = > + Actions.ActOnFinishFullExpr(Val.get(), ELoc, /*DiscardedValue*/ > false); > } > > // Parse ')'. > @@ -1996,7 +1997,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDi > Data.ColonLoc = Tok.getLocation(); > SourceLocation ELoc = ConsumeToken(); > ExprResult Tail = ParseAssignmentExpression(); > - Tail = Actions.ActOnFinishFullExpr(Tail.get(), ELoc); > + Tail = > + Actions.ActOnFinishFullExpr(Tail.get(), ELoc, /*DiscardedValue*/ > false); > if (Tail.isUsable()) > Data.TailExpr = Tail.get(); > else > > Modified: cfe/trunk/lib/Parse/ParseStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseStmt.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Parse/ParseStmt.cpp (original) > +++ cfe/trunk/lib/Parse/ParseStmt.cpp Fri Jan 4 08:58:14 2019 > @@ -439,7 +439,7 @@ StmtResult Parser::ParseExprStatement() > > // Otherwise, eat the semicolon. > ExpectAndConsumeSemi(diag::err_expected_semi_after_expr); > - return Actions.ActOnExprStmt(Expr); > + return Actions.ActOnExprStmt(Expr, isExprValueDiscarded()); > } > > /// ParseSEHTryBlockCommon > @@ -958,6 +958,16 @@ bool Parser::ConsumeNullStmt(StmtVector > 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 > @@ -1062,7 +1072,7 @@ StmtResult Parser::ParseCompoundStatemen > // 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); > + R = Actions.ActOnExprStmt(Res, isExprValueDiscarded()); > } > } > > @@ -1698,8 +1708,16 @@ StmtResult Parser::ParseForStatement(Sou > if (!Value.isInvalid()) { > if (ForEach) > FirstPart = Actions.ActOnForEachLValueExpr(Value.get()); > - else > - FirstPart = Actions.ActOnExprStmt(Value); > + 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); > + } > } > > if (Tok.is(tok::semi)) { > > Modified: cfe/trunk/lib/Sema/SemaCoroutine.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCoroutine.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaCoroutine.cpp (original) > +++ cfe/trunk/lib/Sema/SemaCoroutine.cpp Fri Jan 4 08:58:14 2019 > @@ -647,7 +647,7 @@ bool Sema::ActOnCoroutineBodyStart(Scope > return StmtError(); > Suspend = BuildResolvedCoawaitExpr(Loc, Suspend.get(), > /*IsImplicit*/ true); > - Suspend = ActOnFinishFullExpr(Suspend.get()); > + Suspend = ActOnFinishFullExpr(Suspend.get(), /*DiscardedValue*/ > false); > if (Suspend.isInvalid()) { > Diag(Loc, diag::note_coroutine_promise_suspend_implicitly_required) > << ((Name == "initial_suspend") ? 0 : 1); > @@ -868,7 +868,7 @@ StmtResult Sema::BuildCoreturnStmt(Sourc > if (PC.isInvalid()) > return StmtError(); > > - Expr *PCE = ActOnFinishFullExpr(PC.get()).get(); > + Expr *PCE = ActOnFinishFullExpr(PC.get(), /*DiscardedValue*/ > false).get(); > > Stmt *Res = new (Context) CoreturnStmt(Loc, E, PCE, IsImplicit); > return Res; > @@ -1237,7 +1237,7 @@ bool CoroutineStmtBuilder::makeNewAndDel > > ExprResult NewExpr = > S.ActOnCallExpr(S.getCurScope(), NewRef.get(), Loc, NewArgs, Loc); > - NewExpr = S.ActOnFinishFullExpr(NewExpr.get()); > + NewExpr = S.ActOnFinishFullExpr(NewExpr.get(), /*DiscardedValue*/ > false); > if (NewExpr.isInvalid()) > return false; > > @@ -1263,7 +1263,8 @@ bool CoroutineStmtBuilder::makeNewAndDel > > ExprResult DeleteExpr = > S.ActOnCallExpr(S.getCurScope(), DeleteRef.get(), Loc, DeleteArgs, > Loc); > - DeleteExpr = S.ActOnFinishFullExpr(DeleteExpr.get()); > + DeleteExpr = > + S.ActOnFinishFullExpr(DeleteExpr.get(), /*DiscardedValue*/ false); > if (DeleteExpr.isInvalid()) > return false; > > @@ -1348,7 +1349,8 @@ bool CoroutineStmtBuilder::makeOnExcepti > > ExprResult UnhandledException = buildPromiseCall(S, > Fn.CoroutinePromise, Loc, > "unhandled_exception", > None); > - UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), > Loc); > + UnhandledException = S.ActOnFinishFullExpr(UnhandledException.get(), > Loc, > + /*DiscardedValue*/ false); > if (UnhandledException.isInvalid()) > return false; > > @@ -1401,7 +1403,8 @@ bool CoroutineStmtBuilder::makeGroDeclAn > "get_return_object type must no longer be dependent"); > > if (FnRetType->isVoidType()) { > - ExprResult Res = S.ActOnFinishFullExpr(this->ReturnValue, Loc); > + ExprResult Res = > + S.ActOnFinishFullExpr(this->ReturnValue, Loc, /*DiscardedValue*/ > false); > if (Res.isInvalid()) > return false; > > @@ -1433,7 +1436,7 @@ bool CoroutineStmtBuilder::makeGroDeclAn > if (Res.isInvalid()) > return false; > > - Res = S.ActOnFinishFullExpr(Res.get()); > + Res = S.ActOnFinishFullExpr(Res.get(), /*DiscardedValue*/ false); > if (Res.isInvalid()) > return false; > > > Modified: cfe/trunk/lib/Sema/SemaDecl.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDecl.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri Jan 4 08:58:14 2019 > @@ -11204,9 +11204,9 @@ void Sema::AddInitializerToDecl(Decl *Re > // struct T { S a, b; } t = { Temp(), Temp() } > // > // we should destroy the first Temp before constructing the second. > - ExprResult Result = ActOnFinishFullExpr(Init, VDecl->getLocation(), > - false, > - VDecl->isConstexpr()); > + ExprResult Result = > + ActOnFinishFullExpr(Init, VDecl->getLocation(), > + /*DiscardedValue*/ false, VDecl->isConstexpr()); > if (Result.isInvalid()) { > VDecl->setInvalidDecl(); > return; > > Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Fri Jan 4 08:58:14 2019 > @@ -1205,7 +1205,7 @@ static bool checkTupleLikeDecomposition( > E = Seq.Perform(S, Entity, Kind, Init); > if (E.isInvalid()) > return true; > - E = S.ActOnFinishFullExpr(E.get(), Loc); > + E = S.ActOnFinishFullExpr(E.get(), Loc, /*DiscardedValue*/ false); > if (E.isInvalid()) > return true; > RefVD->setInit(E.get()); > @@ -3682,7 +3682,7 @@ void Sema::ActOnFinishCXXInClassMemberIn > // C++11 [class.base.init]p7: > // The initialization of each base and member constitutes a > // full-expression. > - Init = ActOnFinishFullExpr(Init.get(), InitLoc); > + Init = ActOnFinishFullExpr(Init.get(), InitLoc, /*DiscardedValue*/ > false); > if (Init.isInvalid()) { > FD->setInvalidDecl(); > return; > @@ -4040,7 +4040,8 @@ Sema::BuildMemberInitializer(ValueDecl * > // C++11 [class.base.init]p7: > // The initialization of each base and member constitutes a > // full-expression. > - MemberInit = ActOnFinishFullExpr(MemberInit.get(), > InitRange.getBegin()); > + MemberInit = ActOnFinishFullExpr(MemberInit.get(), > InitRange.getBegin(), > + /*DiscardedValue*/ false); > if (MemberInit.isInvalid()) > return true; > > @@ -4095,8 +4096,8 @@ Sema::BuildDelegatingInitializer(TypeSou > // C++11 [class.base.init]p7: > // The initialization of each base and member constitutes a > // full-expression. > - DelegationInit = ActOnFinishFullExpr(DelegationInit.get(), > - InitRange.getBegin()); > + DelegationInit = ActOnFinishFullExpr( > + DelegationInit.get(), InitRange.getBegin(), /*DiscardedValue*/ > false); > if (DelegationInit.isInvalid()) > return true; > > @@ -4225,7 +4226,8 @@ Sema::BuildBaseInitializer(QualType Base > // C++11 [class.base.init]p7: > // The initialization of each base and member constitutes a > // full-expression. > - BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin()); > + BaseInit = ActOnFinishFullExpr(BaseInit.get(), InitRange.getBegin(), > + /*DiscardedValue*/ false); > if (BaseInit.isInvalid()) > return true; > > > Modified: cfe/trunk/lib/Sema/SemaExpr.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExpr.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Jan 4 08:58:14 2019 > @@ -4736,8 +4736,9 @@ bool Sema::CheckCXXDefaultArgExpr(Source > if (Result.isInvalid()) > return true; > > - Result = ActOnFinishFullExpr(Result.getAs<Expr>(), > - Param->getOuterLocStart()); > + Result = > + ActOnFinishFullExpr(Result.getAs<Expr>(), > Param->getOuterLocStart(), > + /*DiscardedValue*/ false); > if (Result.isInvalid()) > return true; > > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Jan 4 08:58:14 2019 > @@ -7803,6 +7803,8 @@ ExprResult Sema::ActOnFinishFullExpr(Exp > FullExpr = IgnoredValueConversions(FullExpr.get()); > if (FullExpr.isInvalid()) > return ExprError(); > + > + DiagnoseUnusedExprResult(FullExpr.get()); > } > > FullExpr = CorrectDelayedTyposInExpr(FullExpr.get()); > > Modified: cfe/trunk/lib/Sema/SemaLambda.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaLambda.cpp (original) > +++ cfe/trunk/lib/Sema/SemaLambda.cpp Fri Jan 4 08:58:14 2019 > @@ -1724,7 +1724,7 @@ ExprResult Sema::BuildBlockForLambdaConv > /*NRVO=*/false), > CurrentLocation, Src); > if (!Init.isInvalid()) > - Init = ActOnFinishFullExpr(Init.get()); > + Init = ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); > > if (Init.isInvalid()) > return ExprError(); > > Modified: cfe/trunk/lib/Sema/SemaOpenMP.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOpenMP.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaOpenMP.cpp (original) > +++ cfe/trunk/lib/Sema/SemaOpenMP.cpp Fri Jan 4 08:58:14 2019 > @@ -5320,7 +5320,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > LastIteration.get(), UB.get()); > EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), > CondOp.get()); > - EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); > + EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ > false); > > // 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 > @@ -5349,7 +5349,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > LastIteration.get(), CombUB.get()); > CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, > CombUB.get(), > CombCondOp.get()); > - CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); > + CombEUB = > + SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ > false); > > const CapturedDecl *CD = > cast<CapturedStmt>(AStmt)->getCapturedDecl(); > // We expect to have at least 2 more parameters than the 'parallel' > @@ -5383,7 +5384,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > ? LB.get() > : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); > Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), > RHS); > - Init = SemaRef.ActOnFinishFullExpr(Init.get()); > + Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ > false); > > if (isOpenMPLoopBoundSharingDirective(DKind)) { > Expr *CombRHS = > @@ -5394,7 +5395,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); > CombInit = > SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), > CombRHS); > - CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); > + CombInit = > + SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ > false); > } > } > > @@ -5426,7 +5428,7 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > if (!Inc.isUsable()) > return 0; > Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), > Inc.get()); > - Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); > + Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); > if (!Inc.isUsable()) > return 0; > > @@ -5444,7 +5446,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > // LB = LB + ST > NextLB = > SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), > NextLB.get()); > - NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); > + NextLB = > + SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ > false); > if (!NextLB.isUsable()) > return 0; > // UB + ST > @@ -5454,7 +5457,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > // UB = UB + ST > NextUB = > SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), > NextUB.get()); > - NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); > + NextUB = > + SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ > false); > if (!NextUB.isUsable()) > return 0; > if (isOpenMPLoopBoundSharingDirective(DKind)) { > @@ -5465,7 +5469,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > // LB = LB + ST > CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, > CombLB.get(), > CombNextLB.get()); > - CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); > + CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), > + /*DiscardedValue*/ false); > if (!CombNextLB.isUsable()) > return 0; > // UB + ST > @@ -5476,7 +5481,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > // UB = UB + ST > CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, > CombUB.get(), > CombNextUB.get()); > - CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); > + CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), > + /*DiscardedValue*/ false); > if (!CombNextUB.isUsable()) > return 0; > } > @@ -5497,7 +5503,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > 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()); > + DistInc = > + SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ > false); > assert(DistInc.isUsable() && "distribute inc expr was not built"); > > // Build expression: UB = min(UB, prevUB) for #for in composite or > combined > @@ -5509,7 +5516,8 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), > UB.get()); > PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, > UB.get(), > CondOp.get()); > - PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); > + PrevEUB = > + SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ > false); > > // Build IV <= PrevUB to be used in parallel for is in combination > with > // a distribute directive with schedule(static, 1) > @@ -5613,8 +5621,10 @@ checkOpenMPLoop(OpenMPDirectiveKind DKin > Built.IterationVarRef = IV.get(); > Built.LastIteration = LastIteration.get(); > Built.NumIterations = NumIterations.get(); > - Built.CalcLastIteration = > - SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); > + Built.CalcLastIteration = SemaRef > + > .ActOnFinishFullExpr(CalcLastIteration.get(), > + /*DiscardedValue*/ > false) > + .get(); > Built.PreCond = PreCond.get(); > Built.PreInits = buildPreInits(C, Captures); > Built.Cond = Cond.get(); > @@ -10267,8 +10277,8 @@ OMPClause *Sema::ActOnOpenMPLastprivateC > PseudoDstExpr, PseudoSrcExpr); > if (AssignmentOp.isInvalid()) > continue; > - AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, > - /*DiscardedValue=*/true); > + AssignmentOp = > + ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ > false); > if (AssignmentOp.isInvalid()) > continue; > > @@ -11274,7 +11284,8 @@ static bool actOnOMPReductionKindClause( > BO_Assign, LHSDRE, ConditionalOp); > } > if (ReductionOp.isUsable()) > - ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); > + ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), > + /*DiscardedValue*/ false); > } > if (!ReductionOp.isUsable()) > continue; > @@ -11612,7 +11623,7 @@ OMPClause *Sema::ActOnOpenMPLinearClause > buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); > ExprResult CalcStep = > BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); > - CalcStep = ActOnFinishFullExpr(CalcStep.get()); > + CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ > false); > > // Warn about zero linear step (it would be probably better specified > as > // making corresponding variables 'const'). > @@ -11700,7 +11711,7 @@ static bool FinishOpenMPLinearClause(OMP > else > Update = *CurPrivate; > Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), > - /*DiscardedValue=*/true); > + /*DiscardedValue*/ false); > > // Build final: Var = InitExpr + NumIterations * Step > ExprResult Final; > @@ -11711,7 +11722,7 @@ static bool FinishOpenMPLinearClause(OMP > else > Final = *CurPrivate; > Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), > - /*DiscardedValue=*/true); > + /*DiscardedValue*/ false); > > if (!Update.isUsable() || !Final.isUsable()) { > Updates.push_back(nullptr); > @@ -11879,7 +11890,7 @@ OMPClause *Sema::ActOnOpenMPCopyinClause > if (AssignmentOp.isInvalid()) > continue; > AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), > DE->getExprLoc(), > - /*DiscardedValue=*/true); > + /*DiscardedValue*/ false); > if (AssignmentOp.isInvalid()) > continue; > > @@ -11987,8 +11998,8 @@ OMPClause *Sema::ActOnOpenMPCopyprivateC > DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, > PseudoSrcExpr); > if (AssignmentOp.isInvalid()) > continue; > - AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, > - /*DiscardedValue=*/true); > + AssignmentOp = > + ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ > false); > if (AssignmentOp.isInvalid()) > continue; > > > Modified: cfe/trunk/lib/Sema/SemaStmt.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/SemaStmt.cpp (original) > +++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri Jan 4 08:58:14 2019 > @@ -42,12 +42,11 @@ > using namespace clang; > using namespace sema; > > -StmtResult Sema::ActOnExprStmt(ExprResult FE) { > +StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) { > if (FE.isInvalid()) > return StmtError(); > > - FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), > - /*DiscardedValue*/ true); > + FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), > DiscardedValue); > if (FE.isInvalid()) > return StmtError(); > > @@ -348,6 +347,10 @@ sema::CompoundScopeInfo &Sema::getCurCom > 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(); > @@ -370,14 +373,6 @@ StmtResult Sema::ActOnCompoundStmt(Sourc > 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 > @@ -469,15 +464,12 @@ Sema::ActOnCaseStmt(SourceLocation CaseL > > /// 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; > @@ -571,9 +563,6 @@ StmtResult Sema::BuildIfStmt(SourceLocat > 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); > } > @@ -1301,8 +1290,6 @@ StmtResult Sema::ActOnWhileStmt(SourceLo > !Diags.isIgnored(diag::warn_comma_operator, > CondVal.second->getExprLoc())) > CommaVisitor(*this).Visit(CondVal.second); > > - DiagnoseUnusedExprResult(Body); > - > if (isa<NullStmt>(Body)) > getCurCompoundScope().setHasEmptyLoopBodies(); > > @@ -1322,7 +1309,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, > return StmtError(); > Cond = CondResult.get(); > > - CondResult = ActOnFinishFullExpr(Cond, DoLoc); > + CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false); > if (CondResult.isInvalid()) > return StmtError(); > Cond = CondResult.get(); > @@ -1332,8 +1319,6 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, > !Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc())) > CommaVisitor(*this).Visit(Cond); > > - DiagnoseUnusedExprResult(Body); > - > return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen); > } > > @@ -1778,11 +1763,6 @@ StmtResult Sema::ActOnForStmt(SourceLoca > CommaVisitor(*this).Visit(Second.get().second); > > Expr *Third = third.release().getAs<Expr>(); > - > - DiagnoseUnusedExprResult(First); > - DiagnoseUnusedExprResult(Third); > - DiagnoseUnusedExprResult(Body); > - > if (isa<NullStmt>(Body)) > getCurCompoundScope().setHasEmptyLoopBodies(); > > @@ -1802,7 +1782,7 @@ StmtResult Sema::ActOnForEachLValueExpr( > if (result.isInvalid()) return StmtError(); > E = result.get(); > > - ExprResult FullExpr = ActOnFinishFullExpr(E); > + ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); > if (FullExpr.isInvalid()) > return StmtError(); > return StmtResult(static_cast<Stmt*>(FullExpr.get())); > @@ -1956,7 +1936,8 @@ Sema::ActOnObjCForCollectionStmt(SourceL > if (CollectionExprResult.isInvalid()) > return StmtError(); > > - CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get()); > + CollectionExprResult = > + ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ > false); > if (CollectionExprResult.isInvalid()) > return StmtError(); > > @@ -2593,7 +2574,8 @@ StmtResult Sema::BuildCXXForRangeStmt(So > if (!NotEqExpr.isInvalid()) > NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get()); > if (!NotEqExpr.isInvalid()) > - NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get()); > + NotEqExpr = > + ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false); > if (NotEqExpr.isInvalid()) { > Diag(RangeLoc, diag::note_for_range_invalid_iterator) > << RangeLoc << 0 << BeginRangeRef.get()->getType(); > @@ -2616,7 +2598,7 @@ StmtResult Sema::BuildCXXForRangeStmt(So > // co_await during the initial parse. > IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get()); > if (!IncrExpr.isInvalid()) > - IncrExpr = ActOnFinishFullExpr(IncrExpr.get()); > + IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ > false); > if (IncrExpr.isInvalid()) { > Diag(RangeLoc, diag::note_for_range_invalid_iterator) > << RangeLoc << 2 << BeginRangeRef.get()->getType() ; > @@ -2871,7 +2853,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocati > return StmtError(); > } > > - ExprResult ExprRes = ActOnFinishFullExpr(E); > + ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false); > if (ExprRes.isInvalid()) > return StmtError(); > E = ExprRes.get(); > @@ -3221,7 +3203,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLoca > ExpressionEvaluationContext::DiscardedStatement && > (HasDeducedReturnType || CurCap->HasImplicitReturnType)) { > if (RetValExp) { > - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); > + ExprResult ER = > + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ > false); > if (ER.isInvalid()) > return StmtError(); > RetValExp = ER.get(); > @@ -3348,7 +3331,8 @@ Sema::ActOnCapScopeReturnStmt(SourceLoca > } > > if (RetValExp) { > - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); > + ExprResult ER = > + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ > false); > if (ER.isInvalid()) > return StmtError(); > RetValExp = ER.get(); > @@ -3578,7 +3562,8 @@ StmtResult Sema::BuildReturnStmt(SourceL > ExpressionEvaluationContext::DiscardedStatement && > FnRetType->getContainedAutoType()) { > if (RetValExp) { > - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); > + ExprResult ER = > + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ > false); > if (ER.isInvalid()) > return StmtError(); > RetValExp = ER.get(); > @@ -3672,7 +3657,8 @@ StmtResult Sema::BuildReturnStmt(SourceL > } > > if (RetValExp) { > - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); > + ExprResult ER = > + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ > false); > if (ER.isInvalid()) > return StmtError(); > RetValExp = ER.get(); > @@ -3751,7 +3737,8 @@ StmtResult Sema::BuildReturnStmt(SourceL > } > > if (RetValExp) { > - ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc); > + ExprResult ER = > + ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ > false); > if (ER.isInvalid()) > return StmtError(); > RetValExp = ER.get(); > @@ -3804,7 +3791,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(So > if (Result.isInvalid()) > return StmtError(); > > - Result = ActOnFinishFullExpr(Result.get()); > + Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false); > if (Result.isInvalid()) > return StmtError(); > Throw = Result.get(); > @@ -3876,7 +3863,7 @@ Sema::ActOnObjCAtSynchronizedOperand(Sou > } > > // The operand to @synchronized is a full-expression. > - return ActOnFinishFullExpr(operand); > + return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false); > } > > StmtResult > > Modified: cfe/trunk/lib/Sema/TreeTransform.h > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/lib/Sema/TreeTransform.h (original) > +++ cfe/trunk/lib/Sema/TreeTransform.h Fri Jan 4 08:58:14 2019 > @@ -328,7 +328,7 @@ public: > /// other mechanism. > /// > /// \returns the transformed statement. > - StmtResult TransformStmt(Stmt *S); > + StmtResult TransformStmt(Stmt *S, bool DiscardedValue = false); > > /// Transform the given statement. > /// > @@ -3269,8 +3269,8 @@ private: > bool DeducibleTSTContext); > }; > > -template<typename Derived> > -StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S) { > +template <typename Derived> > +StmtResult TreeTransform<Derived>::TransformStmt(Stmt *S, bool > DiscardedValue) { > if (!S) > return S; > > @@ -3294,7 +3294,7 @@ StmtResult TreeTransform<Derived>::Trans > if (E.isInvalid()) > return StmtError(); > > - return getSema().ActOnExprStmt(E); > + return getSema().ActOnExprStmt(E, DiscardedValue); > } > } > > @@ -4715,7 +4715,8 @@ TreeTransform<Derived>::TransformVariabl > } > if (SizeResult.isInvalid()) > return QualType(); > - SizeResult = SemaRef.ActOnFinishFullExpr(SizeResult.get()); > + SizeResult = > + SemaRef.ActOnFinishFullExpr(SizeResult.get(), /*DiscardedValue*/ > false); > if (SizeResult.isInvalid()) > return QualType(); > > @@ -6520,7 +6521,9 @@ TreeTransform<Derived>::TransformCompoun > bool SubStmtChanged = false; > SmallVector<Stmt*, 8> Statements; > for (auto *B : S->body()) { > - StmtResult Result = getDerived().TransformStmt(B); > + StmtResult Result = > + getDerived().TransformStmt(B, !IsStmtExpr || B != S->body_back()); > + > if (Result.isInvalid()) { > // Immediately fail if this was a DeclStmt, since it's very > // likely that this will cause problems for future statements. > > Modified: cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp (original) > +++ cfe/trunk/test/CXX/stmt.stmt/stmt.select/p3.cpp Fri Jan 4 08:58:14 > 2019 > @@ -1,5 +1,5 @@ > -// RUN: %clang_cc1 -fsyntax-only -verify %s > -// RUN: %clang_cc1 -fsyntax-only -std=c++1z -Wc++14-compat -verify %s > -DCPP17 > +// 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 > > int f(); > > @@ -71,7 +71,6 @@ void whileInitStatement() { > // last loop above. It would be nice to remove this. > void whileInitStatement2() { > while (; false) {} // expected-error {{expected expression}} > - // expected-warning@-1 {{expression result unused}} > - // expected-error@-2 {{expected ';' after expression}} > - // expected-error@-3 {{expected expression}} > + // expected-error@-1 {{expected ';' after expression}} > + // expected-error@-2 {{expected expression}} > } > > Modified: cfe/trunk/test/CodeCompletion/pragma-macro-token-caching.c > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeCompletion/pragma-macro-token-caching.c?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/CodeCompletion/pragma-macro-token-caching.c (original) > +++ cfe/trunk/test/CodeCompletion/pragma-macro-token-caching.c Fri Jan 4 > 08:58:14 2019 > @@ -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; > + param; // expected-warning {{expression result unused}} > } > > // RUN: %clang_cc1 -fsyntax-only -verify -code-completion-at=%s:16:1 %s | > FileCheck %s > > Modified: cfe/trunk/test/Parser/cxx1z-init-statement.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx1z-init-statement.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/Parser/cxx1z-init-statement.cpp (original) > +++ cfe/trunk/test/Parser/cxx1z-init-statement.cpp Fri Jan 4 08:58:14 2019 > @@ -13,9 +13,9 @@ int f() { > if (T(n) = 0; n) {} > > // init-statement expressions > - 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}} > + 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}} > > // condition declarations > if (T(n){g}) {} > @@ -35,7 +35,7 @@ int f() { > > // Likewise for 'switch' > switch (int n; n) {} > - switch (g; int g = 5) {} > + switch (g; int g = 5) {} // expected-warning {{expression result > unused}} > > if (int a, b; int c = a) { // expected-note 6{{previous}} > int a; // expected-error {{redefinition}} > > Modified: cfe/trunk/test/Parser/switch-recovery.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/switch-recovery.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/Parser/switch-recovery.cpp (original) > +++ cfe/trunk/test/Parser/switch-recovery.cpp Fri Jan 4 08:58:14 2019 > @@ -105,7 +105,7 @@ void test9(int x) { // expected-note {{' > 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 2 {{expression result unused}} > + expected-warning {{expression result unused}} > 9:: :y; // expected-error {{expected ';' after expression}} \ > expected-error {{expected unqualified-id}} \ > expected-warning {{expression result unused}} > > Modified: cfe/trunk/test/SemaCXX/cxx1z-init-statement.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx1z-init-statement.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/cxx1z-init-statement.cpp (original) > +++ cfe/trunk/test/SemaCXX/cxx1z-init-statement.cpp Fri Jan 4 08:58:14 > 2019 > @@ -1,5 +1,5 @@ > -// RUN: %clang_cc1 -std=c++1z -verify %s > -// RUN: %clang_cc1 -std=c++17 -verify %s > +// RUN: %clang_cc1 -std=c++1z -Wno-unused-value -verify %s > +// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -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}} expected-warning {{unused}} > + if (x, +x; int a = 0) // expected-note 2 {{previous definition is here}} > 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}} expected-warning {{unused}} > + switch (x, +x; int a = 0) { // expected-note {{previous definition is > here}} > case 0: > int a = 0; // expected-error {{redefinition of 'a'}} // > expected-note {{previous definition is here}} > case 1: > > Modified: cfe/trunk/test/SemaCXX/for-range-examples.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/for-range-examples.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/for-range-examples.cpp (original) > +++ cfe/trunk/test/SemaCXX/for-range-examples.cpp Fri Jan 4 08:58:14 2019 > @@ -244,7 +244,7 @@ void foo () > { > int b = 1, a[b]; > a[0] = 0; > - [&] { for (int c : a) 0; } (); > + [&] { for (int c : a) 0; } (); // expected-warning {{expression result > unused}} > } > > > > Modified: cfe/trunk/test/SemaCXX/warn-unused-result.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/warn-unused-result.cpp?rev=350404&r1=350403&r2=350404&view=diff > > ============================================================================== > --- cfe/trunk/test/SemaCXX/warn-unused-result.cpp (original) > +++ cfe/trunk/test/SemaCXX/warn-unused-result.cpp Fri Jan 4 08:58:14 2019 > @@ -33,6 +33,36 @@ 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)); > }; > @@ -206,3 +236,13 @@ 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 > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits