Skip to content

Commit 0f9904a

Browse files
committed
d: Fix ICE in gimplify_var_or_parm_decl, at gimplify.cc:3308
The result type of the assert() should always be the same as its inferred expression type, which could either be `void' or `noreturn'. Also moves the pattern of calling to BUILT_IN_TRAP to its own codegen function, as it is repeated quite enough throughout the front-end. PR d/124922 gcc/d/ChangeLog: * d-codegen.cc (build_trap_call): New function. (build_array_bounds_call): Use it. (build_bounds_index_condition): Likewise. (build_bounds_slice_condition): Likewise. (d_build_call): Likewise. * expr.cc (ExprVisitor::visit (HaltExp *)): Likewise. (ExprVisitor::visit (AssertExp *)): Likewise. Return zero instead of void_node when assert contracts are disabled. * d-tree.h (build_trap_call): New prototype. gcc/testsuite/ChangeLog: * gdc.dg/pr124922.d: New test.
1 parent 9e3e6ce commit 0f9904a

4 files changed

Lines changed: 30 additions & 11 deletions

File tree

gcc/d/d-codegen.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2007,7 +2007,7 @@ build_array_bounds_call (const Loc &loc)
20072007
{
20082008
/* Terminate the program with a trap if no D runtime present. */
20092009
if (checkaction_trap_p ())
2010-
return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2010+
return build_trap_call ();
20112011
else
20122012
{
20132013
return build_libcall (LIBCALL_ARRAYBOUNDSP, 2,
@@ -2036,7 +2036,7 @@ build_bounds_index_condition (IndexExp *ie, tree index, tree length)
20362036
tree boundserr;
20372037

20382038
if (checkaction_trap_p ())
2039-
boundserr = build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2039+
boundserr = build_trap_call ();
20402040
else
20412041
{
20422042
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_INDEXP, 4,
@@ -2082,10 +2082,7 @@ build_bounds_slice_condition (SliceExp *se, tree lower, tree upper, tree length)
20822082
tree boundserr;
20832083

20842084
if (checkaction_trap_p ())
2085-
{
2086-
boundserr =
2087-
build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2088-
}
2085+
boundserr = build_trap_call ();
20892086
else
20902087
{
20912088
boundserr = build_libcall (LIBCALL_ARRAYBOUNDS_SLICEP, 5,
@@ -2156,6 +2153,14 @@ checkaction_trap_p (void)
21562153
}
21572154
}
21582155

2156+
/* Build a call to built-in trap(). */
2157+
2158+
tree
2159+
build_trap_call ()
2160+
{
2161+
return build_call_expr (builtin_decl_explicit (BUILT_IN_TRAP), 0);
2162+
}
2163+
21592164
/* Returns the TypeFunction class for Type T.
21602165
Assumes T is already the main variant type (toBasetype). */
21612166

@@ -2397,6 +2402,10 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
23972402
break;
23982403
}
23992404

2405+
/* Trap after evaluating all call arguments, as it is not expected that
2406+
we get to this point after the `noreturn' parameter. */
2407+
saved_args = compound_expr (saved_args, build_trap_call ());
2408+
24002409
/* Add a stub result type for the expression. */
24012410
tree result = build_zero_cst (TREE_TYPE (ctype));
24022411
return compound_expr (saved_args, result);

gcc/d/d-tree.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ extern tree build_bounds_index_condition (IndexExp *, tree, tree);
608608
extern tree build_bounds_slice_condition (SliceExp *, tree, tree, tree);
609609
extern bool array_bounds_check (void);
610610
extern bool checkaction_trap_p (void);
611+
extern tree build_trap_call (void);
611612
extern TypeFunction *get_function_type (Type *);
612613
extern bool call_side_effect_free_p (FuncDeclaration *, Type *);
613614
extern bool call_by_alias_p (FuncDeclaration *, FuncDeclaration *);

gcc/d/expr.cc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1783,13 +1783,12 @@ class ExprVisitor : public Visitor
17831783
else if (global.params.useAssert == CHECKENABLEon && checkaction_trap_p ())
17841784
{
17851785
/* Generate: __builtin_trap() */
1786-
tree fn = builtin_decl_explicit (BUILT_IN_TRAP);
1787-
assert_fail = build_call_expr (fn, 0);
1786+
assert_fail = build_trap_call ();
17881787
}
17891788
else
17901789
{
17911790
/* Assert contracts are turned off. */
1792-
this->result_ = void_node;
1791+
this->result_ = build_zero_cst (build_ctype (e->type));
17931792
return;
17941793
}
17951794

@@ -1905,8 +1904,7 @@ class ExprVisitor : public Visitor
19051904
void visit (HaltExp *) final override
19061905
{
19071906
/* Should we use trap() or abort()? */
1908-
tree ttrap = builtin_decl_explicit (BUILT_IN_TRAP);
1909-
this->result_ = build_call_expr (ttrap, 0);
1907+
this->result_ = build_trap_call ();
19101908
}
19111909

19121910
/* Build a symbol pointer offset expression. */

gcc/testsuite/gdc.dg/pr124922.d

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// { dg-do compile }
2+
// { dg-additional-options "-fno-assert -fdump-tree-original" }
3+
module object;
4+
alias noreturn = typeof(*null);
5+
void main()
6+
{
7+
void function(noreturn) fun;
8+
noreturn bar;
9+
fun(bar);
10+
}
11+
// { dg-final { scan-tree-dump-times "__builtin_trap" 1 "original" } }

0 commit comments

Comments
 (0)