https://gcc.gnu.org/bugzilla/show_bug.cgi?id=127624

            Bug ID: 127624
           Summary: ICE: segfault in record_locally_defined_typedef when
                    -Wunused-local-typedefs is enabled by a diagnostic
                    pragma inside the function body
           Product: gcc
           Version: 17.0
            Status: UNCONFIRMED
          Keywords: ice-on-valid-code
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: captainnemo9292 at gmail dot com
  Target Milestone: ---

Turning on -Wunused-local-typedefs with a diagnostic pragma inside a function
that was started with the warning off, and then declaring a local typedef,
segfaults:

  void a(void) {
  #pragma GCC diagnostic warning "-Wunused-local-typedefs"
    typedef int b;
  }

  $ gcc -c t.c
  t.c:3:3: internal compiler error: Segmentation fault
  record_locally_defined_typedef(tree_node*)
  pushdecl(tree_node*)
  start_decl
  c_parse_file

https://godbolt.org/z/YzPE5YGdh - 12.1 through trunk (17.0 20260926), release
and checking builds alike; "error" instead of "warning" in the pragma behaves
the same. Putting the pragma before the function, or passing
-Wunused-local-typedefs / -Wall on the command line, works as expected, and
the "ignored" direction inside a function (PR53469) is fine.

store_parm_decls allocates the C language_function only when the warning is
already on:

  if (warn_unused_local_typedefs)
    cfun->language = ggc_cleared_alloc<language_function> ();

record_locally_defined_typedef later checks warn_unused_local_typedefs again,
finds it on, and dereferences cfun->language, which is still NULL. Either the
allocation should not be conditional (c_push_function_context already
allocates it lazily in the "might have been already allocated" case), or
record_locally_defined_typedef should allocate on demand / bail out when
cfun->language is NULL. The C++ front end is not affected.

Found by fuzzing; reduced by hand.

Reply via email to