On Sun, Jan 6, 2019 at 10:58 AM Nico Weber <tha...@chromium.org> wrote: > > On Sat, Jan 5, 2019 at 10:16 AM Aaron Ballman <aa...@aaronballman.com> wrote: >> >> On Fri, Jan 4, 2019 at 8:41 PM Richard Smith <rich...@metafoo.co.uk> wrote: >> > >> > On Fri, 4 Jan 2019 at 17:33, Nico Weber via cfe-commits >> > <cfe-commits@lists.llvm.org> wrote: >> >> >> >> 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? >> >> Yes and no. It's not unexpected, but it's not super helpful either. As >> Richard points out below, this happens because of template >> instantiation. >> >> > The first diagnostic appears when parsing the template, the second one >> > appears when instantiating it. In the complete diagnostic output: >> > >> > ../../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"; >> > ^~~~~~~~~~~~~~~~~~~~~~~~~~~ >> > ../../third_party/crashpad/crashpad/util/win/process_info.cc(531,17): >> > note: in instantiation of function template specialization >> > 'crashpad::GetProcessBasicInformation<crashpad::process_types::internal::Traits32>' >> > requested here >> > bool result = >> > GetProcessBasicInformation<process_types::internal::Traits32>( >> > ^ >> > >> > It'd be nice to suppress the diagnostic during instantiation if it >> > appeared during the initial parse (generally, not with something specific >> > to this warning). >> >> Agreed, though I don't have the time to work on that currently. >> Hopefully the behavior here isn't too onerous for Chromium (or other >> projects)? > > > It wasn't a problem for us, no. The warning found a bug, we fixed the bug, > everyone's happy. Just thought I'd mention the diag looks strange; thanks for > the explanation (and the warning improvement) :-)
I'm glad to hear the refactoring is catching more issues, that's great! I'm also glad the template instantiation stuff isn't causing too much of a problem for you. ~Aaron > >> >> >> ~Aaron >> >> > >> >> 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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits