r350404 - Refactor the way we handle diagnosing unused expression results.
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 4 08:58:14 PST 2019
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 at -1 {{expression result unused}}
- // expected-error at -2 {{expected ';' after expression}}
- // expected-error at -3 {{expected expression}}
+ // expected-error at -1 {{expected ';' after expression}}
+ // expected-error at -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
More information about the cfe-commits
mailing list