diff mbox series

C++ PATCH to fix another ICE with stray template code (PR c++/84596)

Message ID 20180313150701.GQ3522@redhat.com
State New
Headers show
Series C++ PATCH to fix another ICE with stray template code (PR c++/84596) | expand

Commit Message

Marek Polacek March 13, 2018, 3:07 p.m. UTC
Here's another case of a template code leaking into cxx_constant_value.
While I recently added the require_rvalue_constant_expression check, it
doesn't help here, because the problem is that we have a MODOP_EXPR (a
template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's
considered dependent, so fold_non_dependent_expr doesn't do its job.

I thought we might skip calling cxx_constant_value when processing a template;
we've already given an error in any case.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-03-13  Marek Polacek  <polacek@redhat.com>

	PR c++/84596
	* semantics.c (finish_static_assert): Don't call cxx_constant_value
	when processing a template.

	* g++.dg/cpp0x/static_assert15.C: New test.


	Marek

Comments

Jason Merrill March 13, 2018, 5:33 p.m. UTC | #1
On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote:
> Here's another case of a template code leaking into cxx_constant_value.
> While I recently added the require_rvalue_constant_expression check, it
> doesn't help here, because the problem is that we have a MODOP_EXPR (a
> template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's
> considered dependent, so fold_non_dependent_expr doesn't do its job.

If it's dependent, we should have taken the dependent path earlier in
the function.  Should that test use
instantiation_dependent_expression_p rather than the existing type or
value dependent check?

Jason
Marek Polacek March 13, 2018, 10:18 p.m. UTC | #2
On Tue, Mar 13, 2018 at 01:33:45PM -0400, Jason Merrill wrote:
> On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote:
> > Here's another case of a template code leaking into cxx_constant_value.
> > While I recently added the require_rvalue_constant_expression check, it
> > doesn't help here, because the problem is that we have a MODOP_EXPR (a
> > template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's
> > considered dependent, so fold_non_dependent_expr doesn't do its job.
> 
> If it's dependent, we should have taken the dependent path earlier in
> the function.  Should that test use
> instantiation_dependent_expression_p rather than the existing type or
> value dependent check?

I guess so.  It fixes the ICE, though the error disappears unless we call
a.b().  But that's probably expected.

Bootstrapped/regtested on x86_64-linux, ok for trunk?

2018-03-13  Marek Polacek  <polacek@redhat.com>

	PR c++/84596
	* semantics.c (finish_static_assert): Check
	instantiation_dependent_expression_p instead of
	{type,value}_dependent_expression_p.

	* g++.dg/cpp0x/static_assert15.C: New test.

diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index bb8b5953539..fdf37bea770 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -8630,8 +8630,7 @@ finish_static_assert (tree condition, tree message, location_t location,
   if (check_for_bare_parameter_packs (condition))
     condition = error_mark_node;
 
-  if (type_dependent_expression_p (condition) 
-      || value_dependent_expression_p (condition))
+  if (instantiation_dependent_expression_p (condition))
     {
       /* We're in a template; build a STATIC_ASSERT and put it in
          the right place. */
diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C
index e69de29bb2d..a740f73fd4a 100644
--- gcc/testsuite/g++.dg/cpp0x/static_assert15.C
+++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C
@@ -0,0 +1,10 @@
+// PR c++/84596
+// { dg-do compile { target c++11 } }
+
+template<int x>
+struct a {
+  constexpr void b() {
+    int c;
+    static_assert(c %= 1, "");
+  }
+};

	Marek
Jason Merrill March 13, 2018, 11:17 p.m. UTC | #3
OK.

On Tue, Mar 13, 2018 at 6:18 PM, Marek Polacek <polacek@redhat.com> wrote:
> On Tue, Mar 13, 2018 at 01:33:45PM -0400, Jason Merrill wrote:
>> On Tue, Mar 13, 2018 at 11:07 AM, Marek Polacek <polacek@redhat.com> wrote:
>> > Here's another case of a template code leaking into cxx_constant_value.
>> > While I recently added the require_rvalue_constant_expression check, it
>> > doesn't help here, because the problem is that we have a MODOP_EXPR (a
>> > template code), whose op1 is a TRUNC_DIV_EXPR without a type, so it's
>> > considered dependent, so fold_non_dependent_expr doesn't do its job.
>>
>> If it's dependent, we should have taken the dependent path earlier in
>> the function.  Should that test use
>> instantiation_dependent_expression_p rather than the existing type or
>> value dependent check?
>
> I guess so.  It fixes the ICE, though the error disappears unless we call
> a.b().  But that's probably expected.
>
> Bootstrapped/regtested on x86_64-linux, ok for trunk?
>
> 2018-03-13  Marek Polacek  <polacek@redhat.com>
>
>         PR c++/84596
>         * semantics.c (finish_static_assert): Check
>         instantiation_dependent_expression_p instead of
>         {type,value}_dependent_expression_p.
>
>         * g++.dg/cpp0x/static_assert15.C: New test.
>
> diff --git gcc/cp/semantics.c gcc/cp/semantics.c
> index bb8b5953539..fdf37bea770 100644
> --- gcc/cp/semantics.c
> +++ gcc/cp/semantics.c
> @@ -8630,8 +8630,7 @@ finish_static_assert (tree condition, tree message, location_t location,
>    if (check_for_bare_parameter_packs (condition))
>      condition = error_mark_node;
>
> -  if (type_dependent_expression_p (condition)
> -      || value_dependent_expression_p (condition))
> +  if (instantiation_dependent_expression_p (condition))
>      {
>        /* We're in a template; build a STATIC_ASSERT and put it in
>           the right place. */
> diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C
> index e69de29bb2d..a740f73fd4a 100644
> --- gcc/testsuite/g++.dg/cpp0x/static_assert15.C
> +++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C
> @@ -0,0 +1,10 @@
> +// PR c++/84596
> +// { dg-do compile { target c++11 } }
> +
> +template<int x>
> +struct a {
> +  constexpr void b() {
> +    int c;
> +    static_assert(c %= 1, "");
> +  }
> +};
>
>         Marek
diff mbox series

Patch

diff --git gcc/cp/semantics.c gcc/cp/semantics.c
index bb8b5953539..8680322a76c 100644
--- gcc/cp/semantics.c
+++ gcc/cp/semantics.c
@@ -8681,7 +8681,8 @@  finish_static_assert (tree condition, tree message, location_t location,
       else if (condition && condition != error_mark_node)
 	{
 	  error ("non-constant condition for static assertion");
-	  if (require_rvalue_constant_expression (condition))
+	  if (!processing_template_decl
+	      && require_rvalue_constant_expression (condition))
 	    cxx_constant_value (condition);
 	}
       input_location = saved_loc;
diff --git gcc/testsuite/g++.dg/cpp0x/static_assert15.C gcc/testsuite/g++.dg/cpp0x/static_assert15.C
index e69de29bb2d..dfb64ad5e1b 100644
--- gcc/testsuite/g++.dg/cpp0x/static_assert15.C
+++ gcc/testsuite/g++.dg/cpp0x/static_assert15.C
@@ -0,0 +1,10 @@ 
+// PR c++/84596
+// { dg-do compile { target c++11 } }
+
+template<int x>
+struct a {
+  constexpr void b() {
+    int c;
+    static_assert(c %= 1, ""); // { dg-error "non-constant" }
+  }
+};