https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127608
Bug ID: 127608
Summary: ICE in ctor_for_folding (varpool.cc) with a two-level
'#pragma weak' alias chain on variables that are also
defined
Product: gcc
Version: 17.0
Status: UNCONFIRMED
Keywords: ice-on-invalid-code
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: captainnemo9292 at gmail dot com
Target Milestone: ---
A #pragma weak alias that targets another #pragma weak alias, where both
symbols are also defined normally, ICEs when the aliased variable is read:
int d, b, k = 1;
#pragma weak b = d
#pragma weak k = b
int foo(void) { return k; }
$ gcc -O2 -c t.c
t.c:1:8: error: 'b' defined both normally and as 'alias' attribute
t.c:1:11: error: 'k' defined both normally and as 'alias' attribute
t.c:4:24: internal compiler error: in ctor_for_folding, at varpool.cc:449
ctor_for_folding(tree_node*)
get_symbol_constant_value(tree_node*)
gimplify_expr
https://godbolt.org/z/zaGWKWeKh - same at -O0/-O1, on 12.1 through trunk
(17.0 20260925). Release-checking builds print "confused by earlier errors,
bailing out" instead, since it is a gcc_assert.
ctor_for_folding walks k to its ultimate alias target d (decl != real_decl)
and then asserts
gcc_assert (!DECL_INITIAL (decl)
|| (node->alias && node->get_alias_target () == real_node)
|| DECL_INITIAL (decl) == error_mark_node);
k has an initializer and its direct alias target is b, not the ultimate
target d, so the assert fails. The invariant holds for well-formed aliases
(an alias with an initializer can only be a direct alias), but after the
"defined both normally and as alias" error the C front end keeps the alias
attribute from #pragma weak in place, and the chain ends up in the symbol
table. With __attribute__((alias("b"))) instead of the pragma the same two
errors
are printed but there is no ICE, so the pragma path should probably recover
the same way (or ctor_for_folding should return error_mark_node when
DECL_INITIAL is set on a non-direct alias). One level of aliasing does not
trigger it.
Found by fuzzing; reduced by hand.