diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2030,6 +2030,7 @@ "Found a negative number of references to a VarDecl"); if (iter->getSecond() != 0) return; + unsigned DiagID = isa(VD) ? diag::warn_unused_but_set_parameter : diag::warn_unused_but_set_variable; Diag(VD->getLocation(), DiagID) << VD; 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 @@ -7922,6 +7922,7 @@ static void MaybeDecrementCount( Expr *E, llvm::DenseMap &RefsMinusAssignments) { DeclRefExpr *LHS = nullptr; + bool IsComponentAssign = false; if (BinaryOperator *BO = dyn_cast(E)) { if (BO->getLHS()->getType()->isDependentType() || BO->getRHS()->getType()->isDependentType()) { @@ -7929,6 +7930,8 @@ return; } else if (!BO->isAssignmentOp()) return; + else + IsComponentAssign = BO->isCompoundAssignmentOp(); LHS = dyn_cast(BO->getLHS()); } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) { if (COCE->getOperator() != OO_Equal) @@ -7940,6 +7943,10 @@ VarDecl *VD = dyn_cast(LHS->getDecl()); if (!VD) return; + // Don't decrement RefsMinusAssignments if volatile variable with component + // assignment (+=, ...) to avoid potential unused-but-set-variable warning. + if (IsComponentAssign && 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 --- a/clang/test/Sema/warn-unused-but-set-variables.c +++ b/clang/test/Sema/warn-unused-but-set-variables.c @@ -23,10 +23,19 @@ 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; + int x; x = 0; return x;