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"); +}