diff mbox series

[C++] Fix checking ICE in pt.c (PR c++/83817)

Message ID 20180115215837.GF2063@tucnak
State New
Headers show
Series [C++] Fix checking ICE in pt.c (PR c++/83817) | expand

Commit Message

Jakub Jelinek Jan. 15, 2018, 9:58 p.m. UTC
Hi!

function in this case can be either a CALL_EXPR or AGGR_INIT_EXPR.
CALL_FROM_THUNK_P macro is defined in tree.h and so knows just about the
generic CALL_EXPR, and the C++ FE adds AGGR_INIT_FROM_THUNK_P macro, which
is defined the same (protected_flag) except for the checking, one requires
a CALL_EXPR, another one AGGR_INIT_EXPR.  So, this spot seemed to do the
right thing actually when doing release checking, just in non-release
checking it would ICE if function is AGGR_INIT_EXPR.  From the
AGGR_INIT_FROM_THUNK_P flag we later on set CALL_FROM_THUNK_P when we later
generate the CALL_EXPR.

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

2018-01-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/83817
	* pt.c (tsubst_copy_and_build) <case CALL_EXPR>: If function
	is AGGR_INIT_EXPR rather than CALL_EXPR, set AGGR_INIT_FROM_THUNK_P
	instead of CALL_FROM_THUNK_P.

	* g++.dg/cpp1y/pr83817.C: New test.


	Jakub

Comments

Jason Merrill Jan. 16, 2018, 1:59 a.m. UTC | #1
OK.

On Mon, Jan 15, 2018 at 4:58 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> Hi!
>
> function in this case can be either a CALL_EXPR or AGGR_INIT_EXPR.
> CALL_FROM_THUNK_P macro is defined in tree.h and so knows just about the
> generic CALL_EXPR, and the C++ FE adds AGGR_INIT_FROM_THUNK_P macro, which
> is defined the same (protected_flag) except for the checking, one requires
> a CALL_EXPR, another one AGGR_INIT_EXPR.  So, this spot seemed to do the
> right thing actually when doing release checking, just in non-release
> checking it would ICE if function is AGGR_INIT_EXPR.  From the
> AGGR_INIT_FROM_THUNK_P flag we later on set CALL_FROM_THUNK_P when we later
> generate the CALL_EXPR.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2018-01-15  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/83817
>         * pt.c (tsubst_copy_and_build) <case CALL_EXPR>: If function
>         is AGGR_INIT_EXPR rather than CALL_EXPR, set AGGR_INIT_FROM_THUNK_P
>         instead of CALL_FROM_THUNK_P.
>
>         * g++.dg/cpp1y/pr83817.C: New test.
>
> --- gcc/cp/pt.c.jj      2018-01-11 18:58:48.365391793 +0100
> +++ gcc/cp/pt.c 2018-01-15 18:32:44.433150762 +0100
> @@ -17819,7 +17819,10 @@ tsubst_copy_and_build (tree t,
>                 CALL_EXPR_REVERSE_ARGS (function) = rev;
>                 if (thk)
>                   {
> -                   CALL_FROM_THUNK_P (function) = true;
> +                   if (TREE_CODE (function) == CALL_EXPR)
> +                     CALL_FROM_THUNK_P (function) = true;
> +                   else
> +                     AGGR_INIT_FROM_THUNK_P (function) = true;
>                     /* The thunk location is not interesting.  */
>                     SET_EXPR_LOCATION (function, UNKNOWN_LOCATION);
>                   }
> --- gcc/testsuite/g++.dg/cpp1y/pr83817.C.jj     2018-01-15 18:34:37.494143930 +0100
> +++ gcc/testsuite/g++.dg/cpp1y/pr83817.C        2018-01-15 18:34:05.212145878 +0100
> @@ -0,0 +1,17 @@
> +// PR c++/83817
> +// { dg-do compile { target c++14 } }
> +
> +struct A;
> +struct B { template <typename> using C = A; };
> +struct D : B { struct F { typedef C<char> E; }; };
> +struct G {
> +  struct I { I (D, A &); } h;
> +  D::F::E &k ();
> +  D j;
> +  G (G &&) : h (j, k ()) {}
> +};
> +struct N { G l; };
> +typedef N (*M)(N &);
> +struct H { const char *o; M s; };
> +N foo (N &);
> +H r { "", [](auto &x) { return foo (x); }};
>
>         Jakub
diff mbox series

Patch

--- gcc/cp/pt.c.jj	2018-01-11 18:58:48.365391793 +0100
+++ gcc/cp/pt.c	2018-01-15 18:32:44.433150762 +0100
@@ -17819,7 +17819,10 @@  tsubst_copy_and_build (tree t,
 		CALL_EXPR_REVERSE_ARGS (function) = rev;
 		if (thk)
 		  {
-		    CALL_FROM_THUNK_P (function) = true;
+		    if (TREE_CODE (function) == CALL_EXPR)
+		      CALL_FROM_THUNK_P (function) = true;
+		    else
+		      AGGR_INIT_FROM_THUNK_P (function) = true;
 		    /* The thunk location is not interesting.  */
 		    SET_EXPR_LOCATION (function, UNKNOWN_LOCATION);
 		  }
--- gcc/testsuite/g++.dg/cpp1y/pr83817.C.jj	2018-01-15 18:34:37.494143930 +0100
+++ gcc/testsuite/g++.dg/cpp1y/pr83817.C	2018-01-15 18:34:05.212145878 +0100
@@ -0,0 +1,17 @@ 
+// PR c++/83817
+// { dg-do compile { target c++14 } }
+
+struct A;
+struct B { template <typename> using C = A; };
+struct D : B { struct F { typedef C<char> E; }; };
+struct G {
+  struct I { I (D, A &); } h;
+  D::F::E &k ();
+  D j;
+  G (G &&) : h (j, k ()) {}
+};
+struct N { G l; };
+typedef N (*M)(N &);
+struct H { const char *o; M s; };
+N foo (N &);
+H r { "", [](auto &x) { return foo (x); }};