Author: Michael Benfield
Date: 2021-05-17T11:02:26-07:00
New Revision: 14dfb3831c425c7f22540a2160424224008c257e

URL: 
https://github.com/llvm/llvm-project/commit/14dfb3831c425c7f22540a2160424224008c257e
DIFF: 
https://github.com/llvm/llvm-project/commit/14dfb3831c425c7f22540a2160424224008c257e.diff

LOG: [Clang] -Wunused-but-set-parameter and -Wunused-but-set-variable

These are intended to mimic warnings available in gcc.

Reviewed By: aeubanks

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

Added: 
    clang/test/Sema/warn-unused-but-set-parameters.c
    clang/test/Sema/warn-unused-but-set-variables.c
    clang/test/SemaCXX/warn-unused-but-set-parameters-cpp.cpp
    clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp

Modified: 
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/include/clang/Sema/Sema.h
    clang/lib/Sema/SemaDecl.cpp
    clang/lib/Sema/SemaExpr.cpp
    clang/lib/Sema/SemaExprCXX.cpp
    clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
    clang/test/CodeGen/2007-10-30-Volatile.c
    clang/test/CodeGen/X86/x86_32-xsave.c
    clang/test/CodeGen/X86/x86_64-xsave.c
    clang/test/CodeGen/builtins-arm.c
    clang/test/CodeGen/builtins-riscv.c
    clang/test/FixIt/fixit.cpp
    clang/test/Misc/warning-wall.c
    clang/test/Sema/shift.c
    clang/test/Sema/vector-gcc-compat.c
    clang/test/Sema/vector-gcc-compat.cpp
    clang/test/SemaCXX/goto.cpp
    clang/test/SemaCXX/shift.cpp
    clang/test/SemaCXX/sizeless-1.cpp
    clang/test/SemaObjC/foreach.m

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td 
b/clang/include/clang/Basic/DiagnosticGroups.td
index f6a4fbb1e04c..35088f845da4 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -725,6 +725,7 @@ def UnusedMemberFunction : 
DiagGroup<"unused-member-function",
 def UnusedLabel : DiagGroup<"unused-label">;
 def UnusedLambdaCapture : DiagGroup<"unused-lambda-capture">;
 def UnusedParameter : DiagGroup<"unused-parameter">;
+def UnusedButSetParameter : DiagGroup<"unused-but-set-parameter">;
 def UnusedResult : DiagGroup<"unused-result">;
 def PotentiallyEvaluatedExpression : 
DiagGroup<"potentially-evaluated-expression">;
 def UnevaluatedExpression : DiagGroup<"unevaluated-expression",
@@ -734,6 +735,7 @@ def UnusedValue : DiagGroup<"unused-value", 
[UnusedComparison, UnusedResult,
 def UnusedConstVariable : DiagGroup<"unused-const-variable">;
 def UnusedVariable : DiagGroup<"unused-variable",
                                [UnusedConstVariable]>;
+def UnusedButSetVariable : DiagGroup<"unused-but-set-variable">;
 def UnusedLocalTypedef : DiagGroup<"unused-local-typedef">;
 def UnusedPropertyIvar :  DiagGroup<"unused-property-ivar">;
 def UnusedGetterReturnValue : DiagGroup<"unused-getter-return-value">;
@@ -875,7 +877,7 @@ def Unused : DiagGroup<"unused",
                         // UnusedMemberFunction, (clean-up llvm before 
enabling)
                         UnusedPrivateField, UnusedLambdaCapture,
                         UnusedLocalTypedef, UnusedValue, UnusedVariable,
-                        UnusedPropertyIvar]>,
+                        UnusedButSetVariable, UnusedPropertyIvar]>,
                         DiagCategory<"Unused Entity Issue">;
 
 // Format settings.
@@ -927,6 +929,7 @@ def Extra : DiagGroup<"extra", [
     MissingMethodReturnType,
     SignCompare,
     UnusedParameter,
+    UnusedButSetParameter,
     NullPointerArithmetic,
     EmptyInitStatement,
     StringConcatation,

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 9dd9b1b5118b..982606e4f6ca 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -310,8 +310,12 @@ def note_riscv_repeated_interrupt_attribute : Note<
   "repeated RISC-V 'interrupt' attribute is here">;
 def warn_unused_parameter : Warning<"unused parameter %0">,
   InGroup<UnusedParameter>, DefaultIgnore;
+def warn_unused_but_set_parameter : Warning<"parameter %0 set but not used">,
+  InGroup<UnusedButSetParameter>, DefaultIgnore;
 def warn_unused_variable : Warning<"unused variable %0">,
   InGroup<UnusedVariable>, DefaultIgnore;
+def warn_unused_but_set_variable : Warning<"variable %0 set but not used">,
+  InGroup<UnusedButSetVariable>, DefaultIgnore;
 def warn_unused_local_typedef : Warning<
   "unused %select{typedef|type alias}0 %1">,
   InGroup<UnusedLocalTypedef>, DefaultIgnore;

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b6143d1d3178..160760577c5b 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1514,6 +1514,11 @@ class Sema final {
 
   bool WarnedStackExhausted = false;
 
+  /// Increment when we find a reference; decrement when we find an ignored
+  /// assignment.  Ultimately the value is 0 if every reference is an ignored
+  /// assignment.
+  llvm::DenseMap<const VarDecl *, int> RefsMinusAssignments;
+
 public:
   Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
        TranslationUnitKind TUKind = TU_Complete,
@@ -4858,6 +4863,10 @@ class Sema final {
   void DiagnoseUnusedNestedTypedefs(const RecordDecl *D);
   void DiagnoseUnusedDecl(const NamedDecl *ND);
 
+  /// If VD is set but not otherwise used, diagnose, for a parameter or a
+  /// variable.
+  void DiagnoseUnusedButSetDecl(const VarDecl *VD);
+
   /// Emit \p DiagID if statement located on \p StmtLoc has a suspicious null
   /// statement as a \p Body, and it is located on the same line.
   ///

diff  --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index db267089be96..9f5be890ca21 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -1906,6 +1906,37 @@ void Sema::DiagnoseUnusedDecl(const NamedDecl *D) {
   Diag(D->getLocation(), DiagID) << D << Hint;
 }
 
+void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD) {
+  // If it's not referenced, it can't be set.
+  if (!VD->isReferenced() || !VD->getDeclName() || VD->hasAttr<UnusedAttr>())
+    return;
+
+  const auto *Ty = VD->getType().getTypePtr()->getBaseElementTypeUnsafe();
+  if (const TagType *TT = Ty->getAs<TagType>()) {
+    const TagDecl *Tag = TT->getDecl();
+    if (Tag->hasAttr<UnusedAttr>())
+      return;
+    // In C++, don't warn for record types that don't have WarnUnusedAttr, to
+    // mimic gcc's behavior.
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Tag)) {
+      if (!RD->hasAttr<WarnUnusedAttr>())
+        return;
+    }
+  }
+
+  auto iter = RefsMinusAssignments.find(VD);
+  if (iter == RefsMinusAssignments.end())
+    return;
+
+  assert(iter->getSecond() >= 0 &&
+         "Found a negative number of references to a VarDecl");
+  if (iter->getSecond() != 0)
+    return;
+  unsigned DiagID = isa<ParmVarDecl>(VD) ? diag::warn_unused_but_set_parameter
+                                         : diag::warn_unused_but_set_variable;
+  Diag(VD->getLocation(), DiagID) << VD;
+}
+
 static void CheckPoppedLabel(LabelDecl *L, Sema &S) {
   // Verify that we have no forward references left.  If so, there was a goto
   // or address of a label taken, but no definition of it.  Label fwd
@@ -1940,6 +1971,11 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
         DiagnoseUnusedNestedTypedefs(RD);
     }
 
+    if (VarDecl *VD = dyn_cast<VarDecl>(D)) {
+      DiagnoseUnusedButSetDecl(VD);
+      RefsMinusAssignments.erase(VD);
+    }
+
     if (!D->getDeclName()) continue;
 
     // If this was a forward reference to a label, verify it was defined.

diff  --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 51df75707145..431b37e6da94 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -18322,8 +18322,9 @@ void Sema::CleanupVarDeclMarking() {
          "MarkVarDeclODRUsed failed to cleanup MaybeODRUseExprs?");
 }
 
-static void DoMarkVarDeclReferenced(Sema &SemaRef, SourceLocation Loc,
-                                    VarDecl *Var, Expr *E) {
+static void DoMarkVarDeclReferenced(
+    Sema &SemaRef, SourceLocation Loc, VarDecl *Var, Expr *E,
+    llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
   assert((!E || isa<DeclRefExpr>(E) || isa<MemberExpr>(E) ||
           isa<FunctionParmPackExpr>(E)) &&
          "Invalid Expr argument to DoMarkVarDeclReferenced");
@@ -18340,6 +18341,10 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, 
SourceLocation Loc,
   bool UsableInConstantExpr =
       Var->mightBeUsableInConstantExpressions(SemaRef.Context);
 
+  if (Var->isLocalVarDeclOrParm() && !Var->hasExternalStorage()) {
+    RefsMinusAssignments.insert({Var, 0}).first->getSecond()++;
+  }
+
   // C++20 [expr.const]p12:
   //   A variable [...] is needed for constant evaluation if it is [...] a
   //   variable whose name appears as a potentially constant evaluated
@@ -18495,16 +18500,18 @@ static void DoMarkVarDeclReferenced(Sema &SemaRef, 
SourceLocation Loc,
 /// (C++ [basic.def.odr]p2, C99 6.9p3).  Note that this should not be
 /// used directly for normal expressions referring to VarDecl.
 void Sema::MarkVariableReferenced(SourceLocation Loc, VarDecl *Var) {
-  DoMarkVarDeclReferenced(*this, Loc, Var, nullptr);
+  DoMarkVarDeclReferenced(*this, Loc, Var, nullptr, RefsMinusAssignments);
 }
 
-static void MarkExprReferenced(Sema &SemaRef, SourceLocation Loc,
-                               Decl *D, Expr *E, bool MightBeOdrUse) {
+static void
+MarkExprReferenced(Sema &SemaRef, SourceLocation Loc, Decl *D, Expr *E,
+                   bool MightBeOdrUse,
+                   llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) 
{
   if (SemaRef.isInOpenMPDeclareTargetContext())
     SemaRef.checkDeclIsAllowedInOpenMPTarget(E, D);
 
   if (VarDecl *Var = dyn_cast<VarDecl>(D)) {
-    DoMarkVarDeclReferenced(SemaRef, Loc, Var, E);
+    DoMarkVarDeclReferenced(SemaRef, Loc, Var, E, RefsMinusAssignments);
     return;
   }
 
@@ -18550,7 +18557,8 @@ void Sema::MarkDeclRefReferenced(DeclRefExpr *E, const 
Expr *Base) {
     if (!isConstantEvaluated() && FD->isConsteval() &&
         !RebuildingImmediateInvocation)
       ExprEvalContexts.back().ReferenceToConsteval.insert(E);
-  MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse);
+  MarkExprReferenced(*this, E->getLocation(), E->getDecl(), E, OdrUse,
+                     RefsMinusAssignments);
 }
 
 /// Perform reference-marking and odr-use handling for a MemberExpr.
@@ -18569,13 +18577,15 @@ void Sema::MarkMemberReferenced(MemberExpr *E) {
   }
   SourceLocation Loc =
       E->getMemberLoc().isValid() ? E->getMemberLoc() : E->getBeginLoc();
-  MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse);
+  MarkExprReferenced(*this, Loc, E->getMemberDecl(), E, MightBeOdrUse,
+                     RefsMinusAssignments);
 }
 
 /// Perform reference-marking and odr-use handling for a FunctionParmPackExpr.
 void Sema::MarkFunctionParmPackReferenced(FunctionParmPackExpr *E) {
   for (VarDecl *VD : *E)
-    MarkExprReferenced(*this, E->getParameterPackLocation(), VD, E, true);
+    MarkExprReferenced(*this, E->getParameterPackLocation(), VD, E, true,
+                       RefsMinusAssignments);
 }
 
 /// Perform marking for a reference to an arbitrary declaration.  It

diff  --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index b31c484b1170..b44e8cf2e7a0 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -7782,9 +7782,34 @@ ExprResult Sema::ActOnNoexceptExpr(SourceLocation 
KeyLoc, SourceLocation,
   return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen);
 }
 
+static void MaybeDecrementCount(
+    Expr *E, llvm::DenseMap<const VarDecl *, int> &RefsMinusAssignments) {
+  DeclRefExpr *LHS = nullptr;
+  if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
+    if (!BO->isAssignmentOp())
+      return;
+    LHS = dyn_cast<DeclRefExpr>(BO->getLHS());
+  } else if (CXXOperatorCallExpr *COCE = dyn_cast<CXXOperatorCallExpr>(E)) {
+    if (!COCE->isAssignmentOp())
+      return;
+    LHS = dyn_cast<DeclRefExpr>(COCE->getArg(0));
+  }
+  if (!LHS)
+    return;
+  VarDecl *VD = dyn_cast<VarDecl>(LHS->getDecl());
+  if (!VD)
+    return;
+  auto iter = RefsMinusAssignments.find(VD);
+  if (iter == RefsMinusAssignments.end())
+    return;
+  iter->getSecond()--;
+}
+
 /// Perform the conversions required for an expression used in a
 /// context that ignores the result.
 ExprResult Sema::IgnoredValueConversions(Expr *E) {
+  MaybeDecrementCount(E, RefsMinusAssignments);
+
   if (E->hasPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(E);
     if (result.isInvalid()) return E;

diff  --git a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp 
b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
index b69bc939c39d..8bc9a1d91cd2 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.lambda/p12.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-lambda-capture -verify
+// RUN: %clang_cc1 -std=c++11 %s -Wunused -Wno-unused-but-set-variable 
-Wno-unused-lambda-capture -verify
 
 void odr_used() {
   int i = 17;

diff  --git a/clang/test/CodeGen/2007-10-30-Volatile.c 
b/clang/test/CodeGen/2007-10-30-Volatile.c
index 17aac1a987c2..96df76c039e0 100644
--- a/clang/test/CodeGen/2007-10-30-Volatile.c
+++ b/clang/test/CodeGen/2007-10-30-Volatile.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -Wall -Werror
+// RUN: %clang_cc1 -emit-llvm %s -o /dev/null -Wall 
-Wno-unused-but-set-variable -Werror
 void bork() {
   char * volatile p = 0;
   volatile int cc = 0;

diff  --git a/clang/test/CodeGen/X86/x86_32-xsave.c 
b/clang/test/CodeGen/X86/x86_32-xsave.c
index e1acdff12407..35cd273ffb83 100644
--- a/clang/test/CodeGen/X86/x86_32-xsave.c
+++ b/clang/test/CodeGen/X86/x86_32-xsave.c
@@ -1,17 +1,17 @@
-// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s 
--check-prefix=XSAVE
-// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Wno-unused-but-set-variable 
-Werror | FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVE
 
-// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s 
--check-prefix=XGETBV
-// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s 
--check-prefix=XSETBV
+// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Wno-unused-but-set-variable 
-Werror | FileCheck %s --check-prefix=XGETBV
+// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Wno-unused-but-set-variable 
-Werror | FileCheck %s --check-prefix=XSETBV
 
-// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall -Werror 
| FileCheck %s --check-prefix=XSAVEOPT
-// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o 
- -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEOPT
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o 
- -Wall -Wno-unused-but-set-variable -Werror | FileCheck %s 
--check-prefix=XSAVEOPT
 
-// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVEC
-// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -fno-signed-char -emit-llvm -o - 
-Wall -Werror | FileCheck %s --check-prefix=XSAVEC
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEC
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -fno-signed-char -emit-llvm -o - 
-Wall -Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEC
 
-// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVES
-// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - 
-Wall -Werror | FileCheck %s --check-prefix=XSAVES
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVES
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=i686-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - 
-Wall -Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVES
 
 // Don't include mm_malloc.h, it's system specific.
 #define __MM_MALLOC_H

diff  --git a/clang/test/CodeGen/X86/x86_64-xsave.c 
b/clang/test/CodeGen/X86/x86_64-xsave.c
index cfc33cb06721..33be2cceb453 100644
--- a/clang/test/CodeGen/X86/x86_64-xsave.c
+++ b/clang/test/CodeGen/X86/x86_64-xsave.c
@@ -1,17 +1,17 @@
-// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s 
--check-prefix=XSAVE
-// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Wno-unused-but-set-variable 
-Werror | FileCheck %s --check-prefix=XSAVE
+// RUN: %clang_cc1 %s -DTEST_XSAVE -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVE
 
-// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Werror | FileCheck %s 
--check-prefix=XGETBV
-// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSETBV
+// RUN: %clang_cc1 %s -DTEST_XGETBV -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -emit-llvm -o - -Wall -Wno-unused-but-set-variable 
-Werror | FileCheck %s --check-prefix=XGETBV
+// RUN: %clang_cc1 %s -DTEST_XSETBV -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -fno-signed-char -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSETBV
 
-// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall -Werror 
| FileCheck %s --check-prefix=XSAVEOPT
-// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o 
- -Wall -Werror | FileCheck %s --check-prefix=XSAVEOPT
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEOPT
+// RUN: %clang_cc1 %s -DTEST_XSAVEOPT -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaveopt -fno-signed-char -emit-llvm -o 
- -Wall -Wno-unused-but-set-variable -Werror | FileCheck %s 
--check-prefix=XSAVEOPT
 
-// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVEC
-// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -fno-signed-char -emit-llvm -o - 
-Wall -Werror | FileCheck %s --check-prefix=XSAVEC
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEC
+// RUN: %clang_cc1 %s -DTEST_XSAVEC -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsavec -fno-signed-char -emit-llvm -o - 
-Wall -Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVEC
 
-// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall -Werror | 
FileCheck %s --check-prefix=XSAVES
-// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - 
-Wall -Werror | FileCheck %s --check-prefix=XSAVES
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -emit-llvm -o - -Wall 
-Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVES
+// RUN: %clang_cc1 %s -DTEST_XSAVES -O0 -triple=x86_64-unknown-unknown 
-target-feature +xsave -target-feature +xsaves -fno-signed-char -emit-llvm -o - 
-Wall -Wno-unused-but-set-variable -Werror | FileCheck %s --check-prefix=XSAVES
 
 // Don't include mm_malloc.h, it's system specific.
 #define __MM_MALLOC_H

diff  --git a/clang/test/CodeGen/builtins-arm.c 
b/clang/test/CodeGen/builtins-arm.c
index 8c251754e46c..1acd55d46158 100644
--- a/clang/test/CodeGen/builtins-arm.c
+++ b/clang/test/CodeGen/builtins-arm.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wall -Werror -triple thumbv7-eabi -target-cpu cortex-a8 
-disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Werror -triple 
thumbv7-eabi -target-cpu cortex-a8 -disable-O0-optnone -emit-llvm -o - %s | opt 
-S -mem2reg | FileCheck %s
 
 #include <stdint.h>
 

diff  --git a/clang/test/CodeGen/builtins-riscv.c 
b/clang/test/CodeGen/builtins-riscv.c
index 5297c42ae4e9..31fb572cb274 100644
--- a/clang/test/CodeGen/builtins-riscv.c
+++ b/clang/test/CodeGen/builtins-riscv.c
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wall -Werror -triple riscv32 -disable-O0-optnone 
-emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
-// RUN: %clang_cc1 -Wall -Werror -triple riscv64 -disable-O0-optnone 
-emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Werror -triple riscv32 
-disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Werror -triple riscv64 
-disable-O0-optnone -emit-llvm -o - %s | opt -S -mem2reg | FileCheck %s
 
 void test_eh_return_data_regno() {
   // CHECK: store volatile i32 10

diff  --git a/clang/test/FixIt/fixit.cpp b/clang/test/FixIt/fixit.cpp
index 6e3a41303af9..bfff20e76c14 100644
--- a/clang/test/FixIt/fixit.cpp
+++ b/clang/test/FixIt/fixit.cpp
@@ -1,12 +1,12 @@
-// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x 
c++ -std=c++98 %s
+// RUN: %clang_cc1 -pedantic -Wall -Wno-unused-but-set-variable -Wno-comment 
-verify -fcxx-exceptions -x c++ -std=c++98 %s
 // RUN: cp %s %t-98
-// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x 
c++ -std=c++98 %t-98
-// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment 
-fcxx-exceptions -x c++ -std=c++98 %t-98
+// RUN: not %clang_cc1 -pedantic -Wall -Wno-unused-but-set-variable 
-Wno-comment -fcxx-exceptions -fixit -x c++ -std=c++98 %t-98
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Wno-unused-but-set-variable 
-Werror -Wno-comment -fcxx-exceptions -x c++ -std=c++98 %t-98
 // RUN: not %clang_cc1 -fsyntax-only -pedantic -fdiagnostics-parseable-fixits 
-x c++ -std=c++11 %s 2>&1 | FileCheck %s
-// RUN: %clang_cc1 -pedantic -Wall -Wno-comment -verify -fcxx-exceptions -x 
c++ -std=c++11 %s
+// RUN: %clang_cc1 -pedantic -Wall -Wno-unused-but-set-variable -Wno-comment 
-verify -fcxx-exceptions -x c++ -std=c++11 %s
 // RUN: cp %s %t-11
-// RUN: not %clang_cc1 -pedantic -Wall -Wno-comment -fcxx-exceptions -fixit -x 
c++ -std=c++11 %t-11
-// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Werror -Wno-comment 
-fcxx-exceptions -x c++ -std=c++11 %t-11
+// RUN: not %clang_cc1 -pedantic -Wall -Wno-unused-but-set-variable 
-Wno-comment -fcxx-exceptions -fixit -x c++ -std=c++11 %t-11
+// RUN: %clang_cc1 -fsyntax-only -pedantic -Wall -Wno-unused-but-set-variable 
-Werror -Wno-comment -fcxx-exceptions -x c++ -std=c++11 %t-11
 
 /* This is a test of the various code modification hints that are
    provided as part of warning or extension diagnostics. All of the

diff  --git a/clang/test/Misc/warning-wall.c b/clang/test/Misc/warning-wall.c
index ac2b124e3312..ee3a63e7bbd4 100644
--- a/clang/test/Misc/warning-wall.c
+++ b/clang/test/Misc/warning-wall.c
@@ -73,6 +73,7 @@ CHECK-NEXT:        -Wunevaluated-expression
 CHECK-NEXT:          -Wpotentially-evaluated-expression
 CHECK-NEXT:      -Wunused-variable
 CHECK-NEXT:        -Wunused-const-variable
+CHECK-NEXT:      -Wunused-but-set-variable
 CHECK-NEXT:      -Wunused-property-ivar
 CHECK-NEXT:    -Wvolatile-register-var
 CHECK-NEXT:    -Wobjc-missing-super-calls

diff  --git a/clang/test/Sema/shift.c b/clang/test/Sema/shift.c
index 63c953824925..34487e1156ac 100644
--- a/clang/test/Sema/shift.c
+++ b/clang/test/Sema/shift.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -Wall -Wshift-sign-overflow -ffreestanding -fsyntax-only 
-verify %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Wshift-sign-overflow 
-ffreestanding -fsyntax-only -verify %s
 
 #include <limits.h>
 

diff  --git a/clang/test/Sema/vector-gcc-compat.c 
b/clang/test/Sema/vector-gcc-compat.c
index 73b56347f1b1..78132f7f0963 100644
--- a/clang/test/Sema/vector-gcc-compat.c
+++ b/clang/test/Sema/vector-gcc-compat.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -triple 
x86_64-apple-darwin10
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything 
-Wno-unused-but-set-variable -triple x86_64-apple-darwin10
 
 // Test the compatibility of clang's vector extensions with gcc's vector
 // extensions for C. Notably &&, ||, ?: and ! are not available.

diff  --git a/clang/test/Sema/vector-gcc-compat.cpp 
b/clang/test/Sema/vector-gcc-compat.cpp
index cb6547696814..42c24d91ea8f 100644
--- a/clang/test/Sema/vector-gcc-compat.cpp
+++ b/clang/test/Sema/vector-gcc-compat.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11 -triple 
x86_64-apple-darwin10
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything 
-Wno-unused-but-set-variable -std=c++11 -triple x86_64-apple-darwin10
 
 // Test the compatibility of clang++'s vector extensions with g++'s vector
 // extensions. In comparison to the extensions available in C, the !, ?:, && 
and

diff  --git a/clang/test/Sema/warn-unused-but-set-parameters.c 
b/clang/test/Sema/warn-unused-but-set-parameters.c
new file mode 100644
index 000000000000..4da4822090f3
--- /dev/null
+++ b/clang/test/Sema/warn-unused-but-set-parameters.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused-but-set-parameter -verify %s
+
+int f0(int x,
+       int y, // expected-warning{{parameter 'y' set but not used}}
+       int z __attribute__((unused))) {
+  y = 0;
+  return x;
+}
+
+void f1(void) {
+  (void)^(int x,
+          int y, // expected-warning{{parameter 'y' set but not used}}
+          int z __attribute__((unused))) {
+    y = 0;
+    return x;
+  };
+}
+
+struct S {
+  int i;
+};
+
+void f3(struct S s) { // expected-warning{{parameter 's' set but not used}}
+  struct S t;
+  s = t;
+}

diff  --git a/clang/test/Sema/warn-unused-but-set-variables.c 
b/clang/test/Sema/warn-unused-but-set-variables.c
new file mode 100644
index 000000000000..93595a251df0
--- /dev/null
+++ b/clang/test/Sema/warn-unused-but-set-variables.c
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused-but-set-variable -verify %s
+
+struct S {
+  int i;
+};
+
+int f0() {
+  int y; // expected-warning{{variable 'y' set but not used}}
+  y = 0;
+
+  int z __attribute__((unused));
+  z = 0;
+
+  struct S s; // expected-warning{{variable 's' set but not used}}
+  struct S t;
+  s = t;
+
+  // Don't warn for an extern variable.
+  extern int w;
+  w = 0;
+
+  // Following gcc, this should not warn.
+  int a;
+  w = (a = 0);
+
+  int x;
+  x = 0;
+  return x;
+}
+
+void f1(void) {
+  (void)^() {
+    int y; // expected-warning{{variable 'y' set but not used}}
+    y = 0;
+
+    int x;
+    x = 0;
+    return x;
+  };
+}
+
+void f2 (void) {
+  // Don't warn, even if it's only used in a non-ODR context.
+  int x;
+  x = 0;
+  (void) sizeof(x);
+}

diff  --git a/clang/test/SemaCXX/goto.cpp b/clang/test/SemaCXX/goto.cpp
index beaf88cf60f1..b80305fefa4f 100644
--- a/clang/test/SemaCXX/goto.cpp
+++ b/clang/test/SemaCXX/goto.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wall -fblocks %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wall -Wno-unused-but-set-variable 
-fblocks %s
 
 // PR9463
 double *end;

diff  --git a/clang/test/SemaCXX/shift.cpp b/clang/test/SemaCXX/shift.cpp
index f99b53e358ac..144c18849050 100644
--- a/clang/test/SemaCXX/shift.cpp
+++ b/clang/test/SemaCXX/shift.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -Wall -Wshift-sign-overflow -ffreestanding -fsyntax-only 
-verify=expected,cxx17 -std=c++17 %s
-// RUN: %clang_cc1 -Wall -Wshift-sign-overflow -ffreestanding -fsyntax-only 
-verify=expected,cxx2a -std=c++2a %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Wshift-sign-overflow 
-ffreestanding -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
+// RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -Wshift-sign-overflow 
-ffreestanding -fsyntax-only -verify=expected,cxx2a -std=c++2a %s
 
 #include <limits.h>
 

diff  --git a/clang/test/SemaCXX/sizeless-1.cpp 
b/clang/test/SemaCXX/sizeless-1.cpp
index 96a3ce7542a7..cf92dffbd170 100644
--- a/clang/test/SemaCXX/sizeless-1.cpp
+++ b/clang/test/SemaCXX/sizeless-1.cpp
@@ -1,7 +1,7 @@
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++98 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++11 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=c++17 %s
-// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wrange-loop-analysis -triple arm64-linux-gnu -target-feature +sve -std=gnu++17 
%s
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu 
-target-feature +sve -std=c++98 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu 
-target-feature +sve -std=c++11 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu 
-target-feature +sve -std=c++17 %s
+// RUN: %clang_cc1 -fcxx-exceptions -fsyntax-only -verify -W -Wall 
-Wno-unused-but-set-variable -Wrange-loop-analysis -triple arm64-linux-gnu 
-target-feature +sve -std=gnu++17 %s
 
 namespace std {
 struct type_info;

diff  --git a/clang/test/SemaCXX/warn-unused-but-set-parameters-cpp.cpp 
b/clang/test/SemaCXX/warn-unused-but-set-parameters-cpp.cpp
new file mode 100644
index 000000000000..355ddd3ac7ad
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-but-set-parameters-cpp.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused-but-set-parameter -verify %s
+
+int f0(int x,
+       int y, // expected-warning{{parameter 'y' set but not used}}
+       int z __attribute__((unused))) {
+  y = 0;
+  return x;
+}
+
+void f1(void) {
+  (void)^(int x,
+          int y, // expected-warning{{parameter 'y' set but not used}}
+          int z __attribute__((unused))) {
+    y = 0;
+    return x;
+  };
+}
+
+struct S {
+  int i;
+};
+
+// In C++, don't warn for a struct (following gcc).
+void f3(struct S s) {
+  struct S t;
+  s = t;
+}
+
+// Make sure this doesn't warn.
+struct A {
+  int i;
+  A(int j) : i(j) {}
+};

diff  --git a/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp 
b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
new file mode 100644
index 000000000000..aa598408dee5
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-but-set-variables-cpp.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fblocks -fsyntax-only -Wunused-but-set-variable -verify %s
+
+struct S {
+  int i;
+};
+
+struct __attribute__((warn_unused)) SWarnUnused {
+  int j;
+};
+
+int f0() {
+  int y; // expected-warning{{variable 'y' set but not used}}
+  y = 0;
+
+  int z __attribute__((unused));
+  z = 0;
+
+  // In C++, don't warn for structs. (following gcc's behavior)
+  struct S s;
+  struct S t;
+  s = t;
+
+  // Unless it's marked with the warn_unused attribute.
+  struct SWarnUnused swu; // expected-warning{{variable 'swu' set but not 
used}}
+  struct SWarnUnused swu2;
+  swu = swu2;
+
+  int x;
+  x = 0;
+  return x + 5;
+}
+
+void f1(void) {
+  (void)^() {
+    int y; // expected-warning{{variable 'y' set but not used}}
+    y = 0;
+
+    int x;
+    x = 0;
+    return x;
+  };
+}
+
+void f2() {
+  // Don't warn for either of these cases.
+  constexpr int x = 2;
+  const int y = 1;
+  char a[x];
+  char b[y];
+}

diff  --git a/clang/test/SemaObjC/foreach.m b/clang/test/SemaObjC/foreach.m
index 477c4fc38363..06800dd12bde 100644
--- a/clang/test/SemaObjC/foreach.m
+++ b/clang/test/SemaObjC/foreach.m
@@ -1,4 +1,4 @@
-/* RUN: %clang_cc1 -Wall -fsyntax-only -verify -std=c89 -pedantic %s
+/* RUN: %clang_cc1 -Wall -Wno-unused-but-set-variable -fsyntax-only -verify 
-std=c89 -pedantic %s
  */
 
 @class NSArray;


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to