Bug 110737 - GCC: internal compiler error: Segmentation fault when processing __builtin_isinf and _Atomic long double together
Summary: GCC: internal compiler error: Segmentation fault when processing __builtin_is...
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 14.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: error-recovery, ice-on-invalid-code
Depends on:
Blocks:
 
Reported: 2023-07-19 08:19 UTC by wierton
Modified: 2023-07-19 22:29 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail: 6.1.0, 8.1.0
Last reconfirmed: 2023-07-19 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description wierton 2023-07-19 08:19:53 UTC
When attempting to compile below program using gcc-14 with option `gcc-14 small.c`, gcc throws internal error.
```
_Atomic long double c;
void f(void);
void g(void) { __builtin_isinf(c /= f()); }
```

The output of gcc is pasted below:
```
<source>: In function 'g':
<source>:3:1: error: void value not ignored as it ought to be
    3 | void g(void) { __builtin_isinf(c /= f()); }
      | ^~~~
<source>:3:34: internal compiler error: Segmentation fault
    3 | void g(void) { __builtin_isinf(c /= f()); }
      |                                  ^~
0x21594ee internal_error(char const*, ...)
	???:0
0xd6ec47 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	???:0
0xd7182a gimplify_stmt(tree_node**, gimple**)
	???:0
0xd6f79b gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	???:0
0xd7182a gimplify_stmt(tree_node**, gimple**)
	???:0
0xd6ec6a gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	???:0
0xd7182a gimplify_stmt(tree_node**, gimple**)
	???:0
0xd6ec04 gimplify_expr(tree_node**, gimple**, gimple**, bool (*)(tree_node*), int)
	???:0
0xd7182a gimplify_stmt(tree_node**, gimple**)
	???:0
0xd72cc3 gimplify_body(tree_node*, bool)
	???:0
0xd7311f gimplify_function_tree(tree_node*)
	???:0
0xbaffa7 cgraph_node::analyze()
	???:0
0xbb3af1 symbol_table::finalize_compilation_unit()
	???:0
Please submit a full bug report, with preprocessed source (by using -freport-bug).
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.
```

The above segment fault can be verified at compiler explorer: https://gcc.godbolt.org/z/Ghxe5Mc6e
Comment 1 Richard Biener 2023-07-19 09:38:01 UTC
Confirmed.
Comment 2 Andrew Pinski 2023-07-19 20:42:13 UTC
7137          /* TARGET_EXPR temps aren't part of the enclosing block, so add it
7138             to the temps list.  Handle also variable length TARGET_EXPRs.  */
7139          if (!poly_int_tree_p (DECL_SIZE (temp)))
7140            {
7141              if (!TYPE_SIZES_GIMPLIFIED (TREE_TYPE (temp)))
7142                gimplify_type_sizes (TREE_TYPE (temp), &init_pre_p);
7143              /* FIXME: this is correct only when the size of the type does
(gdb) p temp
$1 = (tree) 0x7ffff760d3f0
(gdb) p debug_tree(temp)
 <var_decl 0x7ffff760d3f0 D.4640
    type <void_type 0x7ffff761e0a8 void VOID
        align:8 warn_if_not_align:0 symtab:0 alias-set -1 canonical-type 0x7ffff761e0a8
        pointer_to_this <pointer_type 0x7ffff761e150>>
    addressable used ignored read VOID t5.c:4:1

(slightly different compiler)
  TARGET_EXPR <D.2762, f ()>;
  TARGET_EXPR <D.2763, (void) (D.2763 = VIEW_CONVERT_EXPR<long double>(__atomic_load_16 ((const volatile void *) &c, 5)))>;
  TARGET_EXPR <D.2768, __builtin_ia32_fnstenv ((void *) &D.2768)>;, __builtin_ia32_fnclex ();;, TARGET_EXPR <D.2770, __builtin_ia32_stmxcsr ()>;, TARGET_EXPR <D.2771, (D.2770 | 8064) & 4294967232>;;, __builtin_ia32_ldmxcsr (D.2771);;

  if (__atomic_compare_exchange_16 ((volatile void *) &c, (void *) &D.2763, VIEW_CONVERT_EXPR<__int128 unsigned>(D.2764), 0, 5, 5))


Note for C++ front-end, it uses error_mark_node for here rather than a void type for D.2762 ( D.4640)
Comment 3 Andrew Pinski 2023-07-19 21:00:48 UTC
In GCC 4.9-5.x, this just ICEd. Before GCC 4.9, GCC didn't recongize _Atomic.
Comment 4 Andrew Pinski 2023-07-19 21:35:31 UTC
You can also get ICE with _Atomic int with a similar testcase:
```
_Atomic int c;
void f(void);
int g(void)
{
        return (c += f());
}
```
Comment 5 Andrew Pinski 2023-07-19 22:29:28 UTC
build_atomic_assign does not handle this in a reasonable fashion.
Note there is code like :
  if (modifycode != NOP_EXPR)
    add_stmt (rhs);

  /* NOP_EXPR indicates it's a straight store of the RHS. Simply issue
     an atomic_store.  */
  if (modifycode == NOP_EXPR)
    {
...
      /* VAL is the value which was stored, return a COMPOUND_STMT of
	 the statement and that value.  */
      return build2 (COMPOUND_EXPR, nonatomic_lhs_type, compound_stmt, val);
    }

Which definitely could be improved too.