On Wed, Jan 10, 2018 at 11:59 AM, Jason Merrill <ja...@redhat.com> wrote:
> On Wed, Jan 10, 2018 at 11:56 AM, Jakub Jelinek <ja...@redhat.com> wrote:
>> On Wed, Jan 10, 2018 at 11:52:16AM -0500, Jason Merrill wrote:
>>> On Fri, Jan 5, 2018 at 5:14 PM, Jakub Jelinek <ja...@redhat.com> wrote:
>>> > Jason's recent change removed a mark_rvalue_use call from 
>>> > constant_value_1,
>>> > which unfortunately regressed quite a few cases where
>>> > -Wunused-but-set-variable now has false positives.
>>>
>>> > The easiest fix seems to be just deal with the -Wunused-but-set-variable
>>> > issue at that point.
>>>
>>> Hmm, we ought to have called mark_rvalue_use before we get here.  I'm
>>> concerned that these issues indicate that lambda captures won't work
>>> in the situations in the testcase, since we rely on mark_rvalue_use to
>>> look through them.
>>
>> Unless you have ideas where to put those mark_rvalue_use calls, I'll defer
>> these PRs to you then, this was just an attempt for an easy way out of it
>> for the warning.  At least the testcases should be usable for future patch.
>
> Makes sense, thanks.

Fixed thus:
commit b84a080faaf81b956ae930ba092dd0caf5669fc0
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Jan 10 17:36:01 2018 -0500

            PR c++/82728 - wrong -Wunused-but-set-variable
    
            PR c++/82799
            PR c++/83690
            * call.c (perform_implicit_conversion_flags): Call mark_rvalue_use.
            * decl.c (case_conversion): Likewise.
            * semantics.c (finish_static_assert): Call
            perform_implicit_conversion_flags.

diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index c822a70a017..5f2c6becb35 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -10514,6 +10514,11 @@ perform_implicit_conversion_flags (tree type, tree 
expr,
   void *p;
   location_t loc = EXPR_LOC_OR_LOC (expr, input_location);
 
+  if (TREE_CODE (type) == REFERENCE_TYPE)
+    expr = mark_lvalue_use (expr);
+  else
+    expr = mark_rvalue_use (expr);
+
   if (error_operand_p (expr))
     return error_mark_node;
 
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 6ba657801d9..ee469d35137 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -3541,6 +3541,8 @@ case_conversion (tree type, tree value)
   if (value == NULL_TREE)
     return value;
 
+  value = mark_rvalue_use (value);
+
   if (cxx_dialect >= cxx11
       && (SCOPED_ENUM_P (type)
          || !INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (TREE_TYPE (value))))
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 60608c797f2..f9c5285f724 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -8608,6 +8608,8 @@ void
 finish_static_assert (tree condition, tree message, location_t location, 
                       bool member_p)
 {
+  tsubst_flags_t complain = tf_warning_or_error;
+
   if (message == NULL_TREE
       || message == error_mark_node
       || condition == NULL_TREE
@@ -8640,9 +8642,9 @@ finish_static_assert (tree condition, tree message, 
location_t location,
     }
 
   /* Fold the expression and convert it to a boolean value. */
-  condition = instantiate_non_dependent_expr (condition);
-  condition = cp_convert (boolean_type_node, condition, tf_warning_or_error);
-  condition = maybe_constant_value (condition);
+  condition = perform_implicit_conversion_flags (boolean_type_node, condition,
+                                                complain, LOOKUP_NORMAL);
+  condition = fold_non_dependent_expr (condition);
 
   if (TREE_CODE (condition) == INTEGER_CST && !integer_zerop (condition))
     /* Do nothing; the condition is satisfied. */
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch2.C 
b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch2.C
new file mode 100644
index 00000000000..677f3056bf8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-switch2.C
@@ -0,0 +1,18 @@
+// PR c++/82728
+// { dg-do compile { target c++11 } }
+
+void
+foo ()
+{
+  const int i = 1;
+
+  [=]()
+    {
+      switch (0)
+       {
+       case i:
+         break;
+       }
+      static_assert (i, "i");
+    };
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-27.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-27.C
new file mode 100644
index 00000000000..0ef71531284
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-27.C
@@ -0,0 +1,14 @@
+// PR c++/82728
+// { dg-do compile }
+// { dg-options "-Wunused-but-set-variable" }
+
+void
+foo ()
+{
+  const int i = 1;             // { dg-bogus "set but not used" }
+  switch (0)
+    {
+    case i:
+      break;
+    }
+}
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-28.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-28.C
new file mode 100644
index 00000000000..69601671535
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-28.C
@@ -0,0 +1,15 @@
+// PR c++/82799
+// { dg-do compile }
+// { dg-options "-Wunused-but-set-variable" }
+
+enum E { b };     
+struct C {
+  template <E>
+  int foo ()
+  {
+    const bool i = 0;          // { dg-bogus "set but not used" }
+    const int r = i ? 7 : 9;
+    return r;
+  }
+  void bar () { foo <b> (); }
+};
diff --git a/gcc/testsuite/g++.dg/warn/Wunused-var-29.C 
b/gcc/testsuite/g++.dg/warn/Wunused-var-29.C
new file mode 100644
index 00000000000..24eeb958f4a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/Wunused-var-29.C
@@ -0,0 +1,10 @@
+// PR c++/83690
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wunused-but-set-variable" }
+
+void
+foo ()
+{
+  constexpr bool foo = true;           // { dg-bogus "set but not used" }
+  static_assert (foo, "foo");
+}

Reply via email to