[C++] PR 84588 ("[8 Regression] internal compiler error: Segmentation fault (contains_struct_check())")

Message ID a2d7e7d4-06b0-95b3-74bf-b181beabfa2e@oracle.com
State New
Headers show
Series
  • [C++] PR 84588 ("[8 Regression] internal compiler error: Segmentation fault (contains_struct_check())")
Related show

Commit Message

Paolo Carlini April 20, 2018, 5:46 p.m.
Hi,

in this error-recovery regression, after sensible diagnostic about "two 
or more data types in declaration..." we get confused, we issue a 
cryptic -  but useful hint to somebody working on the present bug ;) - 
"template definition of non-template" error and we finally crash. I 
think the issue here is that we want to use 
abort_fully_implicit_template as part of the error recovery done by 
cp_parser_parameter_declaration_list, when the loop is exited early 
after a cp_parser_parameter_declaration internally called 
synthesize_implicit_template_parm. Indeed, if we do that we get the same 
error recovery behavior we get for the same testcase modified to not use 
an auto parameter (likewise for related testcases):

struct a {
   void b() {}
    void c(auto = [] {
     if (a a(int int){})
       ;
   }) {}
};

Tested x86_64-linux.

Thanks, Paolo.

///////////////////
/cp
2018-04-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84588
	* parser.c (cp_parser_parameter_declaration_list): When the
	entire parameter-declaration-list is erroneous maybe call
	abort_fully_implicit_template.

/testsuite
2018-04-20  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/84588
	* g++.dg/cpp1y/pr84588.C: New.

Comments

Paolo Carlini May 8, 2018, 2:30 p.m. | #1
Hi,

On 20/04/2018 19:46, Paolo Carlini wrote:
> Hi,

>

> in this error-recovery regression, after sensible diagnostic about 

> "two or more data types in declaration..." we get confused, we issue a 

> cryptic -  but useful hint to somebody working on the present bug ;) - 

> "template definition of non-template" error and we finally crash. I 

> think the issue here is that we want to use 

> abort_fully_implicit_template as part of the error recovery done by 

> cp_parser_parameter_declaration_list, when the loop is exited early 

> after a cp_parser_parameter_declaration internally called 

> synthesize_implicit_template_parm. Indeed, if we do that we get the 

> same error recovery behavior we get for the same testcase modified to 

> not use an auto parameter (likewise for related testcases):

>

> struct a {

>   void b() {}

>    void c(auto = [] {

>     if (a a(int int){})

>       ;

>   }) {}

> };

>

> Tested x86_64-linux.

The last pending patch of mine...

     https://gcc.gnu.org/ml/gcc-patches/2018-04/msg01014.html

Thanks!
Paolo.
Jason Merrill May 8, 2018, 5:15 p.m. | #2
On Fri, Apr 20, 2018 at 1:46 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi,

>

> in this error-recovery regression, after sensible diagnostic about "two or

> more data types in declaration..." we get confused, we issue a cryptic -

> but useful hint to somebody working on the present bug ;) - "template

> definition of non-template" error and we finally crash. I think the issue

> here is that we want to use abort_fully_implicit_template as part of the

> error recovery done by cp_parser_parameter_declaration_list, when the loop

> is exited early after a cp_parser_parameter_declaration internally called

> synthesize_implicit_template_parm. Indeed, if we do that we get the same

> error recovery behavior we get for the same testcase modified to not use an

> auto parameter (likewise for related testcases):

>

> struct a {

>   void b() {}

>    void c(auto = [] {

>     if (a a(int int){})

>       ;

>   }) {}

> };


Hmm, the erroneous declaration is within the lambda body, so messing
with whether c is a template seems wrong.

Jason
Paolo Carlini May 8, 2018, 5:46 p.m. | #3
Hi,

On 08/05/2018 19:15, Jason Merrill wrote:
> On Fri, Apr 20, 2018 at 1:46 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:

>> Hi,

>>

>> in this error-recovery regression, after sensible diagnostic about "two or

>> more data types in declaration..." we get confused, we issue a cryptic -

>> but useful hint to somebody working on the present bug ;) - "template

>> definition of non-template" error and we finally crash. I think the issue

>> here is that we want to use abort_fully_implicit_template as part of the

>> error recovery done by cp_parser_parameter_declaration_list, when the loop

>> is exited early after a cp_parser_parameter_declaration internally called

>> synthesize_implicit_template_parm. Indeed, if we do that we get the same

>> error recovery behavior we get for the same testcase modified to not use an

>> auto parameter (likewise for related testcases):

>>

>> struct a {

>>    void b() {}

>>     void c(auto = [] {

>>      if (a a(int int){})

>>        ;

>>    }) {}

>> };

> Hmm, the erroneous declaration is within the lambda body, so messing

> with whether c is a template seems wrong.

I'm sorry, I don't follow: why you think the issue has to do with c? The 
issue happens while we are parsing:

     a a(int auto)

in the original testcase, in particular the parameters. We set 
parser->fully_implicit_function_template_p in 
synthesize_implicit_template_parm, which in turn is called by 
cp_parser_simple_type_specifier when it sees the auto. As I said, we 
don't have the bug for the snippet you quote above, which is identical 
to that attached in the bug but for the auto in the declaration of a:

struct a {
   void b() {}
   void c(void (*) () = [] {
       if (a a(int auto){})
       ;
   }) {}
};

Paolo.
Jason Merrill May 8, 2018, 7:24 p.m. | #4
On Tue, May 8, 2018 at 1:46 PM, Paolo Carlini <paolo.carlini@oracle.com> wrote:
> Hi,

>

> On 08/05/2018 19:15, Jason Merrill wrote:

>>

>> On Fri, Apr 20, 2018 at 1:46 PM, Paolo Carlini <paolo.carlini@oracle.com>

>> wrote:

>>>

>>> Hi,

>>>

>>> in this error-recovery regression, after sensible diagnostic about "two

>>> or

>>> more data types in declaration..." we get confused, we issue a cryptic -

>>> but useful hint to somebody working on the present bug ;) - "template

>>> definition of non-template" error and we finally crash. I think the issue

>>> here is that we want to use abort_fully_implicit_template as part of the

>>> error recovery done by cp_parser_parameter_declaration_list, when the

>>> loop

>>> is exited early after a cp_parser_parameter_declaration internally called

>>> synthesize_implicit_template_parm. Indeed, if we do that we get the same

>>> error recovery behavior we get for the same testcase modified to not use

>>> an

>>> auto parameter (likewise for related testcases):

>>>

>>> struct a {

>>>    void b() {}

>>>     void c(auto = [] {

>>>      if (a a(int int){})

>>>        ;

>>>    }) {}

>>> };

>>

>> Hmm, the erroneous declaration is within the lambda body, so messing

>> with whether c is a template seems wrong.

>

> I'm sorry, I don't follow: why you think the issue has to do with c? The

> issue happens while we are parsing:

>

>     a a(int auto)

>

> in the original testcase, in particular the parameters. We set

> parser->fully_implicit_function_template_p in

> synthesize_implicit_template_parm, which in turn is called by

> cp_parser_simple_type_specifier when it sees the auto. As I said, we don't

> have the bug for the snippet you quote above, which is identical to that

> attached in the bug but for the auto in the declaration of a:

>

> struct a {

>   void b() {}

>   void c(void (*) () = [] {

>       if (a a(int auto){})

>       ;

>   }) {}

> };


Ah, I was assuming the quoted testcase was the one in the PR.  The patch is OK.

Jason

Patch

Index: cp/parser.c
===================================================================
--- cp/parser.c	(revision 259516)
+++ cp/parser.c	(working copy)
@@ -21358,6 +21358,8 @@  cp_parser_parameter_declaration_list (cp_parser* p
 	{
 	  *is_error = true;
 	  parameters = error_mark_node;
+	  if (parser->fully_implicit_function_template_p)
+	    abort_fully_implicit_template (parser);
 	  break;
 	}
 
Index: testsuite/g++.dg/cpp1y/pr84588.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr84588.C	(nonexistent)
+++ testsuite/g++.dg/cpp1y/pr84588.C	(working copy)
@@ -0,0 +1,10 @@ 
+// { dg-do compile { target c++14 } }
+// { dg-options "-w" }
+
+struct a {
+  void b() {}
+  void c(auto = [] {
+    if (a a(int auto){})  // { dg-error "two or more data types" }
+      ;
+  }) {}
+};