diff mbox

C++ PATCH for c++/66543 (-Wunused-but-set false positives)

Message ID 5716870D.2030709@redhat.com
State New
Headers show

Commit Message

Jason Merrill April 19, 2016, 7:29 p.m. UTC
We've been seeing false positives from these warnings in template code 
due to uses not making it through into the instantiation:

1) If a pack expansion has no elements
2) If a parameter used in a trailing-return-type is instantiated into a 
dummy distinct from the real instantiation
3) If a generic lambda that refers to the decl is never instantiated

Tested x86_64-pc-linux-gnu, applying to trunk.

Comments

Jakub Jelinek April 19, 2016, 7:49 p.m. UTC | #1
On Tue, Apr 19, 2016 at 03:29:17PM -0400, Jason Merrill wrote:
> We've been seeing false positives from these warnings in template code due
> to uses not making it through into the instantiation:
> 
> 1) If a pack expansion has no elements
> 2) If a parameter used in a trailing-return-type is instantiated into a
> dummy distinct from the real instantiation
> 3) If a generic lambda that refers to the decl is never instantiated
> 
> Tested x86_64-pc-linux-gnu, applying to trunk.

Looks safe even for 6.1 to me, or if you want to give it more time on trunk,
at least for 6.2.  But we'll do a rc2 later this week in any case.

> commit 16a145d52dcd75c5da6702ca7024a4570abf6d36
> Author: Jason Merrill <jason@redhat.com>
> Date:   Wed Mar 2 09:40:14 2016 -0500
> 
>     	PR c++/66543 - -Wunused-but-set* false positives
>     
>     	* expr.c (mark_exp_read): Handle NON_DEPENDENT_EXPR.
>     	* pt.c (make_pack_expansion): Call mark_exp_read.
>     	* semantics.c (finish_id_expression): Call mark_type_use in
>     	unevaluated context.

	Jakub
diff mbox

Patch

commit 16a145d52dcd75c5da6702ca7024a4570abf6d36
Author: Jason Merrill <jason@redhat.com>
Date:   Wed Mar 2 09:40:14 2016 -0500

    	PR c++/66543 - -Wunused-but-set* false positives
    
    	* expr.c (mark_exp_read): Handle NON_DEPENDENT_EXPR.
    	* pt.c (make_pack_expansion): Call mark_exp_read.
    	* semantics.c (finish_id_expression): Call mark_type_use in
    	unevaluated context.

diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c
index 702b717..61b3953 100644
--- a/gcc/cp/expr.c
+++ b/gcc/cp/expr.c
@@ -145,6 +145,7 @@  mark_exp_read (tree exp)
     case ADDR_EXPR:
     case INDIRECT_REF:
     case FLOAT_EXPR:
+    case NON_DEPENDENT_EXPR:
       mark_exp_read (TREE_OPERAND (exp, 0));
       break;
     case COMPOUND_EXPR:
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index f9a9d99..e18422f 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -3696,6 +3696,8 @@  make_pack_expansion (tree arg)
       /* Propagate type and const-expression information.  */
       TREE_TYPE (result) = TREE_TYPE (arg);
       TREE_CONSTANT (result) = TREE_CONSTANT (arg);
+      /* Mark this read now, since the expansion might be length 0.  */
+      mark_exp_read (arg);
     }
   else
     /* Just use structural equality for these TYPE_PACK_EXPANSIONS;
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 56864b4..85ef993 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -3487,6 +3487,12 @@  finish_id_expression (tree id_expression,
       if (!scope && decl != error_mark_node && identifier_p (id_expression))
 	maybe_note_name_used_in_class (id_expression, decl);
 
+      /* A use in unevaluated operand might not be instantiated appropriately
+	 if tsubst_copy builds a dummy parm, or if we never instantiate a
+	 generic lambda, so mark it now.  */
+      if (processing_template_decl && cp_unevaluated_operand)
+	mark_type_use (decl);
+
       /* Disallow uses of local variables from containing functions, except
 	 within lambda-expressions.  */
       if (outer_automatic_var_p (decl))
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-7.C b/gcc/testsuite/g++.dg/warn/Wunused-parm-7.C
new file mode 100644
index 0000000..ff1dda5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-7.C
@@ -0,0 +1,17 @@ 
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wunused-but-set-parameter" }
+
+template <typename... Ts> void sink(Ts...);
+
+struct A { int i; };
+
+template <int... I>
+void f(A a)
+{
+  return sink((a.i + I)...);
+}
+
+int main()
+{
+  f<>(A());
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-8.C b/gcc/testsuite/g++.dg/warn/Wunused-parm-8.C
new file mode 100644
index 0000000..867ad6a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-8.C
@@ -0,0 +1,9 @@ 
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wunused-but-set-parameter" }
+
+auto l = [](auto t) -> decltype(true ? t : 0) { return {}; };
+
+int main()
+{
+  l(42);
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-24.C b/gcc/testsuite/g++.dg/warn/Wunused-var-24.C
new file mode 100644
index 0000000..924b2db
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-24.C
@@ -0,0 +1,10 @@ 
+// PR c++/66543
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wunused-but-set-variable" }
+
+int main() {
+  auto f = []() { };
+  [=](auto) {
+    using Foo = decltype(f());
+  };
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-25.C b/gcc/testsuite/g++.dg/warn/Wunused-var-25.C
new file mode 100644
index 0000000..959e79c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-25.C
@@ -0,0 +1,15 @@ 
+// { dg-do compile { target c++14 } }
+// { dg-options "-Wunused-but-set-variable" }
+
+template <int... I> struct A { };
+template <int... I>
+auto f()
+{
+  constexpr int ar[sizeof...(I)+1] = {I...};
+  return A<ar[I]...>();
+}
+
+int main()
+{
+  f<>();
+}