summaryrefslogtreecommitdiff
path: root/lib/Sema/SemaStmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema/SemaStmt.cpp')
-rw-r--r--lib/Sema/SemaStmt.cpp65
1 files changed, 39 insertions, 26 deletions
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 9e30c9a396c0..dacf8d0cf4e7 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -42,11 +42,12 @@
using namespace clang;
using namespace sema;
-StmtResult Sema::ActOnExprStmt(ExprResult FE, bool DiscardedValue) {
+StmtResult Sema::ActOnExprStmt(ExprResult FE) {
if (FE.isInvalid())
return StmtError();
- FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(), DiscardedValue);
+ FE = ActOnFinishFullExpr(FE.get(), FE.get()->getExprLoc(),
+ /*DiscardedValue*/ true);
if (FE.isInvalid())
return StmtError();
@@ -347,10 +348,6 @@ sema::CompoundScopeInfo &Sema::getCurCompoundScope() const {
return getCurFunction()->CompoundScopes.back();
}
-bool Sema::isCurCompoundStmtAStmtExpr() const {
- return getCurCompoundScope().IsStmtExpr;
-}
-
StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
ArrayRef<Stmt *> Elts, bool isStmtExpr) {
const unsigned NumElts = Elts.size();
@@ -373,6 +370,14 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
Diag(D->getLocation(), diag::ext_mixed_decls_code);
}
}
+ // Warn about unused expressions in statements.
+ for (unsigned i = 0; i != NumElts; ++i) {
+ // Ignore statements that are last in a statement expression.
+ if (isStmtExpr && i == NumElts - 1)
+ continue;
+
+ DiagnoseUnusedExprResult(Elts[i]);
+ }
// Check for suspicious empty body (null statement) in `for' and `while'
// statements. Don't do anything for template instantiations, this just adds
@@ -464,12 +469,15 @@ Sema::ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHSVal,
/// ActOnCaseStmtBody - This installs a statement as the body of a case.
void Sema::ActOnCaseStmtBody(Stmt *S, Stmt *SubStmt) {
+ DiagnoseUnusedExprResult(SubStmt);
cast<CaseStmt>(S)->setSubStmt(SubStmt);
}
StmtResult
Sema::ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc,
Stmt *SubStmt, Scope *CurScope) {
+ DiagnoseUnusedExprResult(SubStmt);
+
if (getCurFunction()->SwitchStack.empty()) {
Diag(DefaultLoc, diag::err_default_not_in_switch);
return SubStmt;
@@ -563,6 +571,9 @@ StmtResult Sema::BuildIfStmt(SourceLocation IfLoc, bool IsConstexpr,
if (IsConstexpr || isa<ObjCAvailabilityCheckExpr>(Cond.get().second))
setFunctionHasBranchProtectedScope();
+ DiagnoseUnusedExprResult(thenStmt);
+ DiagnoseUnusedExprResult(elseStmt);
+
return IfStmt::Create(Context, IfLoc, IsConstexpr, InitStmt, Cond.get().first,
Cond.get().second, thenStmt, ElseLoc, elseStmt);
}
@@ -1290,6 +1301,8 @@ StmtResult Sema::ActOnWhileStmt(SourceLocation WhileLoc, ConditionResult Cond,
!Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
CommaVisitor(*this).Visit(CondVal.second);
+ DiagnoseUnusedExprResult(Body);
+
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
@@ -1309,7 +1322,7 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
return StmtError();
Cond = CondResult.get();
- CondResult = ActOnFinishFullExpr(Cond, DoLoc, /*DiscardedValue*/ false);
+ CondResult = ActOnFinishFullExpr(Cond, DoLoc);
if (CondResult.isInvalid())
return StmtError();
Cond = CondResult.get();
@@ -1319,6 +1332,8 @@ Sema::ActOnDoStmt(SourceLocation DoLoc, Stmt *Body,
!Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))
CommaVisitor(*this).Visit(Cond);
+ DiagnoseUnusedExprResult(Body);
+
return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
}
@@ -1763,6 +1778,11 @@ StmtResult Sema::ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc,
CommaVisitor(*this).Visit(Second.get().second);
Expr *Third = third.release().getAs<Expr>();
+
+ DiagnoseUnusedExprResult(First);
+ DiagnoseUnusedExprResult(Third);
+ DiagnoseUnusedExprResult(Body);
+
if (isa<NullStmt>(Body))
getCurCompoundScope().setHasEmptyLoopBodies();
@@ -1782,7 +1802,7 @@ StmtResult Sema::ActOnForEachLValueExpr(Expr *E) {
if (result.isInvalid()) return StmtError();
E = result.get();
- ExprResult FullExpr = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
+ ExprResult FullExpr = ActOnFinishFullExpr(E);
if (FullExpr.isInvalid())
return StmtError();
return StmtResult(static_cast<Stmt*>(FullExpr.get()));
@@ -1936,8 +1956,7 @@ Sema::ActOnObjCForCollectionStmt(SourceLocation ForLoc,
if (CollectionExprResult.isInvalid())
return StmtError();
- CollectionExprResult =
- ActOnFinishFullExpr(CollectionExprResult.get(), /*DiscardedValue*/ false);
+ CollectionExprResult = ActOnFinishFullExpr(CollectionExprResult.get());
if (CollectionExprResult.isInvalid())
return StmtError();
@@ -2574,8 +2593,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
if (!NotEqExpr.isInvalid())
NotEqExpr = CheckBooleanCondition(ColonLoc, NotEqExpr.get());
if (!NotEqExpr.isInvalid())
- NotEqExpr =
- ActOnFinishFullExpr(NotEqExpr.get(), /*DiscardedValue*/ false);
+ NotEqExpr = ActOnFinishFullExpr(NotEqExpr.get());
if (NotEqExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 0 << BeginRangeRef.get()->getType();
@@ -2598,7 +2616,7 @@ StmtResult Sema::BuildCXXForRangeStmt(SourceLocation ForLoc,
// co_await during the initial parse.
IncrExpr = ActOnCoawaitExpr(S, CoawaitLoc, IncrExpr.get());
if (!IncrExpr.isInvalid())
- IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), /*DiscardedValue*/ false);
+ IncrExpr = ActOnFinishFullExpr(IncrExpr.get());
if (IncrExpr.isInvalid()) {
Diag(RangeLoc, diag::note_for_range_invalid_iterator)
<< RangeLoc << 2 << BeginRangeRef.get()->getType() ;
@@ -2853,7 +2871,7 @@ Sema::ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc,
return StmtError();
}
- ExprResult ExprRes = ActOnFinishFullExpr(E, /*DiscardedValue*/ false);
+ ExprResult ExprRes = ActOnFinishFullExpr(E);
if (ExprRes.isInvalid())
return StmtError();
E = ExprRes.get();
@@ -3203,8 +3221,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExpressionEvaluationContext::DiscardedStatement &&
(HasDeducedReturnType || CurCap->HasImplicitReturnType)) {
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3331,8 +3348,7 @@ Sema::ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3562,8 +3578,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
ExpressionEvaluationContext::DiscardedStatement &&
FnRetType->getContainedAutoType()) {
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3657,8 +3672,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3737,8 +3751,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
if (RetValExp) {
- ExprResult ER =
- ActOnFinishFullExpr(RetValExp, ReturnLoc, /*DiscardedValue*/ false);
+ ExprResult ER = ActOnFinishFullExpr(RetValExp, ReturnLoc);
if (ER.isInvalid())
return StmtError();
RetValExp = ER.get();
@@ -3791,7 +3804,7 @@ StmtResult Sema::BuildObjCAtThrowStmt(SourceLocation AtLoc, Expr *Throw) {
if (Result.isInvalid())
return StmtError();
- Result = ActOnFinishFullExpr(Result.get(), /*DiscardedValue*/ false);
+ Result = ActOnFinishFullExpr(Result.get());
if (Result.isInvalid())
return StmtError();
Throw = Result.get();
@@ -3863,7 +3876,7 @@ Sema::ActOnObjCAtSynchronizedOperand(SourceLocation atLoc, Expr *operand) {
}
// The operand to @synchronized is a full-expression.
- return ActOnFinishFullExpr(operand, /*DiscardedValue*/ false);
+ return ActOnFinishFullExpr(operand);
}
StmtResult