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
Confirmed.
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)
In GCC 4.9-5.x, this just ICEd. Before GCC 4.9, GCC didn't recongize _Atomic.
You can also get ICE with _Atomic int with a similar testcase: ``` _Atomic int c; void f(void); int g(void) { return (c += f()); } ```
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.