Bug 92705 - [10 Regression] ICE: Segmentation fault (in build_new_op_1)
Summary: [10 Regression] ICE: Segmentation fault (in build_new_op_1)
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 10.0
: P3 normal
Target Milestone: 10.0
Assignee: Jakub Jelinek
URL:
Keywords: ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2019-11-28 11:47 UTC by Arseny Solokha
Modified: 2019-12-03 08:54 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2019-11-29 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Arseny Solokha 2019-11-28 11:47:32 UTC
g++-10.0.0-alpha20191124 snapshot (r278660) ICEs when compiling the following testcase reduced from test/SemaCXX/builtin-ptrtomember-overload-1.cpp from the clang 9.0.0 test suite:

struct A {};
struct E {};

struct R {
    operator E*();
};

struct S {
    operator E*();
};

struct B1  : R, S {
    operator A*();
};

void foo1(B1 b1, int E::* pmf) {
        int i = b1->*pmf;
}

% g++-10.0.0-alpha20191124 -c gmnbcjli.cpp
gmnbcjli.cpp: In function 'void foo1(B1, int E::*)':
gmnbcjli.cpp:17:22: internal compiler error: Segmentation fault
   17 |         int i = b1->*pmf;
      |                      ^~~
0xf36080 crash_signal
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/toplev.c:328
0x839d0e build_new_op_1
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/call.c:6375
0x83a33a build_new_op(op_location_t const&, tree_code, int, tree_node*, tree_node*, tree_node*, tree_node**, int)
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/call.c:6500
0x9f8dd1 build_x_binary_op(op_location_t const&, tree_code, tree_node*, tree_code, tree_node*, tree_code, tree_node**, int)
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/typeck.c:4223
0x92d178 cp_parser_binary_expression
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:9645
0x92e026 cp_parser_assignment_expression
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:9780
0x92d869 cp_parser_constant_expression
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:10074
0x92dfcb cp_parser_initializer_clause
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:23032
0x9320b7 cp_parser_initializer
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22970
0x957b5b cp_parser_init_declarator
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:20678
0x93aa52 cp_parser_simple_declaration
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:13624
0x93c87f cp_parser_declaration_statement
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:13055
0x93d3c4 cp_parser_statement
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11380
0x93e3c5 cp_parser_statement_seq_opt
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11742
0x93e492 cp_parser_compound_statement
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:11696
0x953e74 cp_parser_function_body
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22876
0x953e74 cp_parser_ctor_initializer_opt_and_function_body
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:22927
0x957005 cp_parser_function_definition_after_declarator
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:28597
0x957fe4 cp_parser_function_definition_from_specifiers_and_declarator
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:28513
0x957fe4 cp_parser_init_declarator
	/var/tmp/portage/sys-devel/gcc-10.0.0_alpha20191124/work/gcc-10-20191124/gcc/cp/parser.c:20505
Comment 1 Jakub Jelinek 2019-11-29 11:08:55 UTC
Started with r277864.  This isn't error-recovery, there is no error printed before it ICEs.
Slightly shortened:
struct A {};
struct B {};
struct C { operator B*(); };
struct D { operator B*(); };
struct E : C, D { operator A*(); };
void foo(E e, int B::* pmf) { int i = e->*pmf; }
Comment 2 Jakub Jelinek 2019-11-29 11:38:12 UTC
The ICE is because conv is ck_ambig with user_conv_p set.
Looking at other conv->user_conv_p tests, e.g. reference_binding does:
  if (conv->user_conv_p)
    {
...

      for (conversion *t = conv; t; t = next_conversion (t))
        if (t->kind == ck_user
            && DECL_CONV_FN_P (t->cand->fn))
          {
and doesn't expect that user_conv_p implies that ck_user will appear.
The following patch restores the previous diagnostics on the testcase, but I'm afraid I have no idea what is right.  If ck_ambig with user_conv_p set is right, then it itself isn't ck_user and next_conversion on it is NULL.

--- gcc/cp/call.c.jj	2019-11-28 18:58:55.671297387 +0100
+++ gcc/cp/call.c	2019-11-29 12:33:04.033386816 +0100
@@ -6370,8 +6370,12 @@ build_new_op_1 (const op_location_t &loc
 	  conv = cand->convs[0];
 	  if (conv->user_conv_p)
 	    {
-	      while (conv->kind != ck_user)
-		conv = next_conversion (conv);
+	      for (conversion *t = conv; t; t = next_conversion (t))
+		if (t->kind == ck_user)
+		  {
+		    conv = t;
+		    break;
+		  }
 	      arg1 = convert_like (conv, arg1, complain);
 	    }
 
@@ -6380,8 +6384,12 @@ build_new_op_1 (const op_location_t &loc
 	      conv = cand->convs[1];
 	      if (conv->user_conv_p)
 		{
-		  while (conv->kind != ck_user)
-		    conv = next_conversion (conv);
+		  for (conversion *t = conv; t; t = next_conversion (t))
+		    if (t->kind == ck_user)
+		      {
+			conv = t;
+			break;
+		      }
 		  arg2 = convert_like (conv, arg2, complain);
 		}
 	    }
@@ -6391,8 +6399,12 @@ build_new_op_1 (const op_location_t &loc
 	      conv = cand->convs[2];
 	      if (conv->user_conv_p)
 		{
-		  while (conv->kind != ck_user)
-		    conv = next_conversion (conv);
+		  for (conversion *t = conv; t; t = next_conversion (t))
+		    if (t->kind == ck_user)
+		      {
+			conv = t;
+			break;
+		      }
 		  arg3 = convert_like (conv, arg3, complain);
 		}
 	    }
Comment 3 Jakub Jelinek 2019-11-29 12:02:25 UTC
Though, previously the convert_like calls were done no matter what the conversion is, so with the above patch maybe after the if (conv->user_conv_p) ... stmts, with whatever the conv is.  Not sure if it makes a difference for anything.
Comment 4 Jakub Jelinek 2019-12-03 08:20:49 UTC
Author: jakub
Date: Tue Dec  3 08:20:18 2019
New Revision: 278922

URL: https://gcc.gnu.org/viewcvs?rev=278922&root=gcc&view=rev
Log:
	PR c++/92705
	* call.c (strip_standard_conversion): New function.
	(build_new_op_1): Use it for user_conv_p.
	(compare_ics): Likewise.
	(source_type): Likewise.

	* g++.dg/conversion/ambig4.C: New test.

Added:
    trunk/gcc/testsuite/g++.dg/conversion/ambig4.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/call.c
    trunk/gcc/testsuite/ChangeLog
Comment 5 Jakub Jelinek 2019-12-03 08:54:05 UTC
Fixed.