diff mbox series

[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())") | expand

Commit Message

Paolo Carlini April 20, 2018, 5:46 p.m. UTC
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. UTC | #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. UTC | #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. UTC | #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. UTC | #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
diff mbox series

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