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 @@ -7808,11 +7808,15 @@ Expr *E, llvm::DenseMap &RefsMinusAssignments) { DeclRefExpr *LHS = nullptr; if (BinaryOperator *BO = dyn_cast(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(BO->getLHS()); } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) { - if (!COCE->isAssignmentOp()) + if (COCE->getOperator() != OO_Equal) return; LHS = dyn_cast(COCE->getArg(0)); } diff --git a/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp --- a/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp +++ b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp @@ -6,6 +6,7 @@ struct __attribute__((warn_unused)) SWarnUnused { int j; + void operator +=(int); }; int f0() { @@ -48,3 +49,16 @@ char a[x]; char b[y]; } + +void f3(int n) { + // Don't warn for overloaded compound assignment operators. + SWarnUnused swu; + swu += n; +} + +template void f4(T n) { + // Don't warn for (potentially) overloaded compound assignment operators in + // template code. + SWarnUnused swu; + swu += n; +}