diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -7921,6 +7921,7 @@ Expr *E, llvm::DenseMap &RefsMinusAssignments) { DeclRefExpr *LHS = nullptr; bool IsCompoundAssign = false; + bool isIncrementDecrementUnaryOp = false; if (BinaryOperator *BO = dyn_cast(E)) { if (BO->getLHS()->getType()->isDependentType() || BO->getRHS()->getType()->isDependentType()) { @@ -7935,6 +7936,11 @@ if (COCE->getOperator() != OO_Equal) return; LHS = dyn_cast(COCE->getArg(0)); + } else if (UnaryOperator *UO = dyn_cast(E)) { + if (!UO->isIncrementDecrementOp()) + return; + isIncrementDecrementUnaryOp = true; + LHS = dyn_cast(UO->getSubExpr()); } if (!LHS) return; @@ -7942,8 +7948,10 @@ if (!VD) return; // Don't decrement RefsMinusAssignments if volatile variable with compound - // assignment (+=, ...) to avoid potential unused-but-set-variable warning. - if (IsCompoundAssign && VD->getType().isVolatileQualified()) + // assignment (+=, ...) or increment/decrement unary operator to avoid + // potential unused-but-set-variable warning. + if ((IsCompoundAssign || isIncrementDecrementUnaryOp) && + VD->getType().isVolatileQualified()) return; auto iter = RefsMinusAssignments.find(VD); if (iter == RefsMinusAssignments.end()) diff --git a/clang/test/Sema/warn-unused-but-set-variables.c b/clang/test/Sema/warn-unused-but-set-variables.c --- a/clang/test/Sema/warn-unused-but-set-variables.c +++ b/clang/test/Sema/warn-unused-but-set-variables.c @@ -73,3 +73,20 @@ __attribute__((__cleanup__(for_cleanup))) int x; x = 5; } + +void f4(void) { + int x1 = 0; // expected-warning{{variable 'x1' set but not used}} + x1++; + int x2 = 0; // expected-warning{{variable 'x2' set but not used}} + x2--; + int x3 = 0; // expected-warning{{variable 'x3' set but not used}} + ++x3; + int x4 = 0; // expected-warning{{variable 'x4' set but not used}} + --x4; + + volatile int v1 = 0; + ++v1; + typedef volatile int volint; + volint v2 = 0; + v2++; +} diff --git a/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp --- a/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp +++ b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp @@ -7,6 +7,7 @@ struct __attribute__((warn_unused)) SWarnUnused { int j; void operator +=(int); + void operator ++(); }; int f0() { @@ -62,3 +63,9 @@ SWarnUnused swu; swu += n; } + +template void f5() { + // Don't warn for overloaded pre/post operators in template code. + SWarnUnused swu; + ++swu; +}