c: Implement C23 rules for undefined static functions in _Generic
A fairly late change in C23, the resolution of CD2 ballot comments
US-077 and US-078, added certain locations in _Generic to the
obviously unevaluated locations where it is permitted to have a
reference to a static function that is never defined.
Implement this feature in GCC. The main complication is that, unlike
previous cases where it's known at the end of an operand to a
construct such as sizeof whether that operand is obviously unevaluated
and so an appropriate argument can be passed to pop_maybe_used, in the
case of a default generic association in _Generic it may not be known
until the end of that _Generic expression whether that case is
evaluated or not. Thus, we arrange for the state of the
maybe_used_decls stack to be saved in this case and later restored
once the correct argument to pop_maybe_used is known.
There may well be further changes in this area in C2y (if the
"discarded" proposal is adopted, further locations will be OK for such
references to undefined static functions). For now, only expressions
and not type names in _Generic have this special treatment.
Bootstrapped with no regressions for x86_64-pc-linux-gnu.
gcc/c/
* c-typeck.cc (in_generic, save_maybe_used, restore_maybe_used):
New.
(mark_decl_used, record_maybe_used_decl, pop_maybe_used): Use
in_generic.
(struct maybe_used_decl): Move to c-tree.h.
* c-tree.h (struct maybe_used_decl): Move from c-typeck.cc.
(in_generic, save_maybe_used, restore_maybe_used): Declare.
* c-parser.cc (c_parser_generic_selection): Increment and
decrement in_generic. Use pop_maybe_used, save_maybe_used and
restore_maybe_used.
gcc/testsuite/
* gcc.dg/c11-generic-4.c, gcc.dg/c23-generic-5.c,
gcc.dg/c2y-generic-5.c: New tests.