Skip to content

Commit bdf69f6

Browse files
committed
[Clang] Fix an unused-but-set-variable warning with volatile variable
For the following code, void test() { volatile int j = 0; for (int i = 0; i < 1000; i++) j += 1; return; } If compiled with clang -g -Wall -Werror -S -emit-llvm test.c we will see the following error: test.c:2:6: error: variable 'j' set but not used [-Werror,-Wunused-but-set-variable] volatile int j = 0; ^ This is not quite right since 'j' is indeed used due to '+=' operator. gcc doesn't emit error either in this case. Also if we change 'j += 1' to 'j++', the warning will disappear with latest clang. Note that clang will issue the warning if the volatile declaration involves only simple assignment (var = ...). To fix the issue, in function MaybeDecrementCount(), if the operator is a compound assignment (i.e., +=, -=, etc.) and the variable is volatile, the count for RefsMinusAssignments will be decremented, similar to 'j++' case. Differential Revision: https://reviews.llvm.org/D121715
1 parent cc5b086 commit bdf69f6

File tree

2 files changed

+21
-0
lines changed

2 files changed

+21
-0
lines changed

clang/lib/Sema/SemaExprCXX.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7925,13 +7925,16 @@ ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
79257925
static void MaybeDecrementCount(
79267926
Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
79277927
DeclRefExpr *LHS = nullptr;
7928+
bool IsCompoundAssign = false;
79287929
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
79297930
if (BO->getLHS()->getType()->isDependentType() ||
79307931
BO->getRHS()->getType()->isDependentType()) {
79317932
if (BO->getOpcode() != BO_Assign)
79327933
return;
79337934
} else if (!BO->isAssignmentOp())
79347935
return;
7936+
else
7937+
IsCompoundAssign = BO->isCompoundAssignmentOp();
79357938
LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
79367939
} else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
79377940
if (COCE->getOperator() != OO_Equal)
@@ -7943,6 +7946,10 @@ static void MaybeDecrementCount(
79437946
VarDecl *VD = dyn_cast<VarDecl>(LHS->getDecl());
79447947
if (!VD)
79457948
return;
7949+
// Don't decrement RefsMinusAssignments if volatile variable with compound
7950+
// assignment (+=, ...) to avoid potential unused-but-set-variable warning.
7951+
if (IsCompoundAssign && VD->getType().isVolatileQualified())
7952+
return;
79467953
auto iter = RefsMinusAssignments.find(VD);
79477954
if (iter == RefsMinusAssignments.end())
79487955
return;

clang/test/Sema/warn-unused-but-set-variables.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,24 @@ int f0(void) {
2323
int a;
2424
w = (a = 0);
2525

26+
int j = 0; // expected-warning{{variable 'j' set but not used}}
27+
for (int i = 0; i < 1000; i++)
28+
j += 1;
29+
2630
// Following gcc, warn for a volatile variable.
2731
volatile int b; // expected-warning{{variable 'b' set but not used}}
2832
b = 0;
2933

34+
// volatile variable k is used, no warning.
35+
volatile int k = 0;
36+
for (int i = 0; i < 1000; i++)
37+
k += 1;
38+
39+
// typedef of volatile type, no warning.
40+
typedef volatile int volint;
41+
volint l = 0;
42+
l += 1;
43+
3044
int x;
3145
x = 0;
3246
return x;

0 commit comments

Comments
 (0)