Only consider built-in compound assignment operators for -Wunused-but-set-*
authorStephan Bergmann <sbergman@redhat.com>
Mon, 14 Jun 2021 05:57:22 +0000 (07:57 +0200)
committerStephan Bergmann <sbergman@redhat.com>
Mon, 14 Jun 2021 06:04:03 +0000 (08:04 +0200)
At least LibreOffice has, for mainly historic reasons that would be hard to
change now, a class Any with an overloaded operator >>= that semantically does
not assign to the LHS but rather extracts into the (by-reference) RHS.  Which
thus caused false positive -Wunused-but-set-parameter and
-Wunused-but-set-variable after those have been introduced recently.

This change is more conservative about the assumed semantics of overloaded
operators, excluding compound assignment operators but keeping plain operator =
ones.  At least for LibreOffice, that strikes a good balance of not producing
false positives but still finding lots of true ones.

(The change to the BinaryOperator case in MaybeDecrementCount is necessary
because e.g. the template f4 test code in warn-unused-but-set-variables-cpp.cpp
turns the += into a BinaryOperator.)

Differential Revision: https://reviews.llvm.org/D103949

clang/lib/Sema/SemaExprCXX.cpp
clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp

index 20925f9..a57c5ad 100644 (file)
@@ -7808,11 +7808,15 @@ static void MaybeDecrementCount(
     Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
   DeclRefExpr *LHS = nullptr;
   if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
-    if (!BO->isAssignmentOp())
+    if (BO->getLHS()->getType()->isDependentType() ||
+        BO->getRHS()->getType()->isDependentType()) {
+      if (BO->getOpcode() != BO_Assign)
+        return;
+    } else if (!BO->isAssignmentOp())
       return;
     LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
   } else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
-    if (!COCE->isAssignmentOp())
+    if (COCE->getOperator() != OO_Equal)
       return;
     LHS = dyn_cast<DeclRefExpr>(COCE->getArg(0));
   }
index aa59840..400e9d7 100644 (file)
@@ -6,6 +6,7 @@ struct S {
 
 struct __attribute__((warn_unused)) SWarnUnused {
   int j;
+  void operator +=(int);
 };
 
 int f0() {
@@ -48,3 +49,16 @@ void f2() {
   char a[x];
   char b[y];
 }
+
+void f3(int n) {
+  // Don't warn for overloaded compound assignment operators.
+  SWarnUnused swu;
+  swu += n;
+}
+
+template<typename T> void f4(T n) {
+  // Don't warn for (potentially) overloaded compound assignment operators in
+  // template code.
+  SWarnUnused swu;
+  swu += n;
+}