Skip to content

Commit

Permalink
[Clang] -Wunused-but-set-variable warning - handle also pre/post unar…
Browse files Browse the repository at this point in the history
…y operators

Clang fails to diagnose:
```
void test() {
    int j = 0;
    for (int i = 0; i < 1000; i++)
            j++;
    return;
}
```

Reason: Missing support for UnaryOperator.

We should not warn with volatile variables... so add check for it.

Reviewed By: efriedma

Differential Revision: https://reviews.llvm.org/D122271
  • Loading branch information
davidbolvansky committed Mar 23, 2022
1 parent 7fdb50c commit 460fc44
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 2 deletions.
12 changes: 10 additions & 2 deletions clang/lib/Sema/SemaExprCXX.cpp
Expand Up @@ -7921,6 +7921,7 @@ static void MaybeDecrementCount(
Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
DeclRefExpr *LHS = nullptr;
bool IsCompoundAssign = false;
bool isIncrementDecrementUnaryOp = false;
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
if (BO->getLHS()->getType()->isDependentType() ||
BO->getRHS()->getType()->isDependentType()) {
Expand All @@ -7935,15 +7936,22 @@ static void MaybeDecrementCount(
if (COCE->getOperator() != OO_Equal)
return;
LHS = dyn_cast<DeclRefExpr>(COCE->getArg(0));
} else if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) {
if (!UO->isIncrementDecrementOp())
return;
isIncrementDecrementUnaryOp = true;
LHS = dyn_cast<DeclRefExpr>(UO->getSubExpr());
}
if (!LHS)
return;
VarDecl *VD = dyn_cast<VarDecl>(LHS->getDecl());
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())
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Sema/warn-unused-but-set-variables.c
Expand Up @@ -73,3 +73,20 @@ void f3(void) {
__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++;
}
7 changes: 7 additions & 0 deletions clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
Expand Up @@ -7,6 +7,7 @@ struct S {
struct __attribute__((warn_unused)) SWarnUnused {
int j;
void operator +=(int);
void operator ++();
};

int f0() {
Expand Down Expand Up @@ -62,3 +63,9 @@ template<typename T> void f4(T n) {
SWarnUnused swu;
swu += n;
}

template <typename T> void f5() {
// Don't warn for overloaded pre/post operators in template code.
SWarnUnused swu;
++swu;
}

0 comments on commit 460fc44

Please sign in to comment.