Fix PR10168: don't warn for unused non-dependent variables in both the template definition and each instantiation.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@133580 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e78aa29..cc66ec6 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -415,8 +415,10 @@
              !Var->isCXXForRangeDecl())
     SemaRef.ActOnUninitializedDecl(Var, false);
 
-  // Diagnose unused local variables.
-  if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed())
+  // Diagnose unused local variables with dependent types, where the diagnostic
+  // will have been deferred.
+  if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed() &&
+      D->getType()->isDependentType())
     SemaRef.DiagnoseUnusedDecl(Var);
 
   return Var;
diff --git a/test/SemaCXX/for-range-unused.cpp b/test/SemaCXX/for-range-unused.cpp
index 7e26c78..7b7d84d 100644
--- a/test/SemaCXX/for-range-unused.cpp
+++ b/test/SemaCXX/for-range-unused.cpp
@@ -5,8 +5,7 @@
 template <typename T>
   struct Vector {
     void doIt() {
-      // FIXME: PR10168: Only warn once for this!
-      int a; // expected-warning 2{{unused variable 'a'}}
+      int a; // expected-warning {{unused variable 'a'}}
 
       for (auto& e : elements)
         ;
@@ -18,5 +17,5 @@
 
 int main(int, char**) {
   Vector<int>    vector;
-  vector.doIt(); // expected-note {{requested here}}
+  vector.doIt();
 }
diff --git a/test/SemaCXX/warn-unused-variables.cpp b/test/SemaCXX/warn-unused-variables.cpp
index 81f22a7..5ba1f2a 100644
--- a/test/SemaCXX/warn-unused-variables.cpp
+++ b/test/SemaCXX/warn-unused-variables.cpp
@@ -54,3 +54,29 @@
   static int y = 0; // expected-warning{{unused variable 'y'}}
 #pragma unused(x)
 }
+
+// PR10168
+namespace PR10168 {
+  // We expect a warning in the definition only for non-dependent variables, and
+  // a warning in the instantiation only for dependent variables.
+  template<typename T>
+  struct S {
+    void f() {
+      int a; // expected-warning {{unused variable 'a'}}
+      T b; // expected-warning 2{{unused variable 'b'}}
+    }
+  };
+
+  template<typename T>
+  void f() {
+    int a; // expected-warning {{unused variable 'a'}}
+    T b; // expected-warning 2{{unused variable 'b'}}
+  }
+
+  void g() {
+    S<int>().f(); // expected-note {{here}}
+    S<char>().f(); // expected-note {{here}}
+    f<int>(); // expected-note {{here}}
+    f<char>(); // expected-note {{here}}
+  }
+}