[clang] bdf69f6 - [Clang] Fix an unused-but-set-variable warning with volatile variable
Yonghong Song via cfe-commits
cfe-commits at lists.llvm.org
Mon Mar 21 14:59:15 PDT 2022
Author: Yonghong Song
Date: 2022-03-21T14:59:03-07:00
New Revision: bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b
URL: https://github.com/llvm/llvm-project/commit/bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b
DIFF: https://github.com/llvm/llvm-project/commit/bdf69f63df2cf4c9e3cd1af5cfcd503bc8e2869b.diff
LOG: [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
Added:
Modified:
clang/lib/Sema/SemaExprCXX.cpp
clang/test/Sema/warn-unused-but-set-variables.c
Removed:
################################################################################
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index ee4bff5c14b89..c923dddb9f285 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7925,6 +7925,7 @@ ExprResult Sema::ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation,
static void MaybeDecrementCount(
Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
DeclRefExpr *LHS = nullptr;
+ bool IsCompoundAssign = false;
if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
if (BO->getLHS()->getType()->isDependentType() ||
BO->getRHS()->getType()->isDependentType()) {
@@ -7932,6 +7933,8 @@ static void MaybeDecrementCount(
return;
} else if (!BO->isAssignmentOp())
return;
+ else
+ IsCompoundAssign = BO->isCompoundAssignmentOp();
LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
} else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
if (COCE->getOperator() != OO_Equal)
@@ -7943,6 +7946,10 @@ static void MaybeDecrementCount(
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())
+ return;
auto iter = RefsMinusAssignments.find(VD);
if (iter == RefsMinusAssignments.end())
return;
diff --git a/clang/test/Sema/warn-unused-but-set-variables.c b/clang/test/Sema/warn-unused-but-set-variables.c
index a8d2ceaa428c9..6e5b7d671711b 100644
--- a/clang/test/Sema/warn-unused-but-set-variables.c
+++ b/clang/test/Sema/warn-unused-but-set-variables.c
@@ -23,10 +23,24 @@ int f0(void) {
int a;
w = (a = 0);
+ int j = 0; // expected-warning{{variable 'j' set but not used}}
+ for (int i = 0; i < 1000; i++)
+ j += 1;
+
// Following gcc, warn for a volatile variable.
volatile int b; // expected-warning{{variable 'b' set but not used}}
b = 0;
+ // volatile variable k is used, no warning.
+ volatile int k = 0;
+ for (int i = 0; i < 1000; i++)
+ k += 1;
+
+ // typedef of volatile type, no warning.
+ typedef volatile int volint;
+ volint l = 0;
+ l += 1;
+
int x;
x = 0;
return x;
More information about the cfe-commits
mailing list