Bug creation and email sending has been disabled, file new bugs at gcc.gnu.org/bugzilla
Bug 235 - ICE with array slice assign on 32 bit
Summary: ICE with array slice assign on 32 bit
Status: RESOLVED FIXED
Alias: None
Product: GDC
Classification: Unclassified
Component: gdc (show other bugs)
Version: development
Hardware: x86 All
: --- major
Assignee: Iain Buclaw
URL:
Depends on:
Blocks:
 
Reported: 2016-08-08 17:34 CEST by Johannes Pfau
Modified: 2016-10-29 07:04 CEST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Johannes Pfau 2016-08-08 17:34:42 CEST
Found on ARM, reproducible on x86 (32bit) as well:


char[] func1()
{
    return [];
}

void test1()
{
    func1()[] = 'y';
}
gdc -c test7.d -m32

In d_build_call CALL_EXPR_RETURN_SLOT_OPT is set on 32 bit targets only and build_target_expr is called. in ExprVisitor::AssignExp we call d_save_expr on the result. For 32 bit targets is_lvalue_p returns true, as we have a TARGET_EXPR and not CALL_EXPR. Because of that we don't create a SAVE_EXPR. The codegen then somehow recursively accesses some expressions which causes the error below. Also "gdc -c test7.d -m32 -fdump-tree-original" does not work and enters an infinite loop.

---------------------------------------------------------
test7.d: In function 'test1':
test7.d:8:5: internal compiler error: in gimple_add_tmp_var, at gimplify.c:703
     func1()[] = 'y';
     ^
0x9d16b9 gimple_add_tmp_var(tree_node*)
	../../gcc-7-20160619/gcc/gimplify.c:703
0x9d9867 gimplify_target_expr
	../../gcc-7-20160619/gcc/gimplify.c:5688
0x9d9867 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10803
0x9deb03 gimplify_compound_lval
	../../gcc-7-20160619/gcc/gimplify.c:2195
0x9d5d4a gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10386
0x9e8cfa gimplify_modify_expr
	../../gcc-7-20160619/gcc/gimplify.c:4798
0x9d7b8a gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10434
0x9daee6 gimplify_stmt(tree_node**, gimple**)
	../../gcc-7-20160619/gcc/gimplify.c:5767
0x9d5e9b gimplify_statement_list
	../../gcc-7-20160619/gcc/gimplify.c:1549
0x9d5e9b gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10851
0x9daee6 gimplify_stmt(tree_node**, gimple**)
	../../gcc-7-20160619/gcc/gimplify.c:5767
0x9dc135 gimplify_bind_expr
	../../gcc-7-20160619/gcc/gimplify.c:1154
0x9d8045 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10633
0x9daee6 gimplify_stmt(tree_node**, gimple**)
	../../gcc-7-20160619/gcc/gimplify.c:5767
0x9dbb01 gimplify_compound_expr
	../../gcc-7-20160619/gcc/gimplify.c:5029
0x9e1ba7 gimplify_modify_expr_rhs
	../../gcc-7-20160619/gcc/gimplify.c:4407
0x9e8b39 gimplify_modify_expr
	../../gcc-7-20160619/gcc/gimplify.c:4757
0x9d7b8a gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10434
0x9d7cce gimplify_target_expr
	../../gcc-7-20160619/gcc/gimplify.c:5698
0x9d7cce gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	../../gcc-7-20160619/gcc/gimplify.c:10803
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://bugzilla.gdcproject.org> for instructions.
Comment 1 Iain Buclaw 2016-08-14 18:26:23 CEST
I guess the right way to go about it is to separate save_expr into lvalue and rvalue variants.  Probably the best way to ensure we don't try to initialize a temporary.

Places that really need save_expr I guess would then just call save_expr directly.
Comment 2 Iain Buclaw 2016-10-22 11:50:13 CEST
Looks like something recursive is going on.

---
$ gdc bug235.d -m32 -fdump-tree-original=stdout

;; Function func1 (_D6bug2355func1FZAa)
;; enabled by -tree-original

{
  return <retval> = {.length=0, .ptr=0B};
}

;; Function test1 (_D6bug2355test1FZv)
;; enabled by -tree-original

gdc: internal compiler error: Segmentation fault (program cc1d)
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
---

It hangs for a while before the segfault.  Best guess would be stack overflow.
Comment 3 Iain Buclaw 2016-10-22 12:00:14 CEST
In compound_expr
---
if (TREE_CODE (arg1) == TARGET_EXPR)
  {
    // If the rhs is a TARGET_EXPR, then build the compound expression
    // inside the target_expr's initializer.  This helps the compiler
    // to eliminate unnecessary temporaries.
    tree init = compound_expr(arg0, TREE_OPERAND (arg1, 1));
    TREE_OPERAND (arg1, 1) = init;

    return arg1;
  }
---

(gdb) call debug_generic_expr (arg1)
TARGET_EXPR <D.3436, func1 () [return slot optimization]>

---

(gdb) call debug_generic_expr (init)
{
  char * D.3438;
  uint D.3437;

  D.3437 = (TARGET_EXPR <D.3436, func1 () [return slot optimization]>).length;
  D.3438 = (TARGET_EXPR <D.3436, func1 () [return slot optimization]>).ptr;
  while (1)
    {
      if (D.3437 == 0) break;
      *D.3438 = 121;
      D.3438++ ;
      D.3437-- ;
    }
}, func1 () [return slot optimization];

---

This is where the recursion comes from.  On x86_64 no TARGET_EXPR is created.  I'd say the creation of a TARGET_EXPR may be dubious anyway.  Hmm...