I like to ping this patch.
Am Freitag, dem 09.08.2024 um 10:20 +0200 schrieb Martin Uecker: > ok? > > Am Samstag, dem 29.06.2024 um 20:30 +0200 schrieb Martin Uecker: > > Probably not entirely fool-proof when using statement > > expressions in initializers, but should be good enough. > > > > > > Bootstrapped and regression tested on x86_64. > > > > > > > > c: Diagnose declarations that are used only in their own initializer > > [PR115027] > > > > Track the declaration that is currently being initialized and do not > > mark it as read when it is used in its own initializer. This then > > allows it to be diagnosed as set-but-unused when it is not used > > elsewhere. > > > > PR c/115027 > > > > gcc/c/ > > * c-tree.h (in_decl_init): Declare variable. > > * c-parser.cc (c_parser_initializer): Record decl being > > initialized. > > * c-typeck.cc (in_decl_init): Defintie variable. > > (mark_exp_read): Ignore decl currently being initialized. > > > > gcc/testsuite/ > > * gcc.dg/pr115027.c: New test. > > > > diff --git a/gcc/c/c-parser.cc b/gcc/c/c-parser.cc > > index 8c4e697a4e1..46060665115 100644 > > --- a/gcc/c/c-parser.cc > > +++ b/gcc/c/c-parser.cc > > @@ -6126,11 +6126,14 @@ c_parser_type_name (c_parser *parser, bool > > alignas_ok) > > static struct c_expr > > c_parser_initializer (c_parser *parser, tree decl) > > { > > + struct c_expr ret; > > + tree save = in_decl_init; > > + in_decl_init = decl; > > + > > if (c_parser_next_token_is (parser, CPP_OPEN_BRACE)) > > - return c_parser_braced_init (parser, NULL_TREE, false, NULL, decl); > > + ret = c_parser_braced_init (parser, NULL_TREE, false, NULL, decl); > > else > > { > > - struct c_expr ret; > > location_t loc = c_parser_peek_token (parser)->location; > > ret = c_parser_expr_no_commas (parser, NULL); > > if (decl != error_mark_node && C_DECL_VARIABLE_SIZE (decl)) > > @@ -6154,8 +6157,9 @@ c_parser_initializer (c_parser *parser, tree decl) > > || C_DECL_DECLARED_CONSTEXPR (COMPOUND_LITERAL_EXPR_DECL > > (ret.value)))) > > ret = convert_lvalue_to_rvalue (loc, ret, true, true, true); > > - return ret; > > } > > + in_decl_init = save; > > + return ret; > > } > > > > /* The location of the last comma within the current initializer list, > > diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h > > index 15da875a029..8013963b06d 100644 > > --- a/gcc/c/c-tree.h > > +++ b/gcc/c/c-tree.h > > @@ -740,6 +740,8 @@ extern int in_typeof; > > extern bool c_in_omp_for; > > extern bool c_omp_array_section_p; > > > > +extern tree in_decl_init; > > + > > extern tree c_last_sizeof_arg; > > extern location_t c_last_sizeof_loc; > > > > diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc > > index 455dc374b48..34279dc1d1a 100644 > > --- a/gcc/c/c-typeck.cc > > +++ b/gcc/c/c-typeck.cc > > @@ -73,6 +73,9 @@ int in_sizeof; > > /* The level of nesting inside "typeof". */ > > int in_typeof; > > > > +/* When inside an initializer, this is set to the decl being initialized. > > */ > > +tree in_decl_init; > > + > > /* True when parsing OpenMP loop expressions. */ > > bool c_in_omp_for; > > > > @@ -2047,7 +2050,8 @@ mark_exp_read (tree exp) > > { > > case VAR_DECL: > > case PARM_DECL: > > - DECL_READ_P (exp) = 1; > > + if (exp != in_decl_init) > > + DECL_READ_P (exp) = 1; > > break; > > case ARRAY_REF: > > case COMPONENT_REF: > > diff --git a/gcc/testsuite/gcc.dg/pr115027.c > > b/gcc/testsuite/gcc.dg/pr115027.c > > new file mode 100644 > > index 00000000000..ac2699f8392 > > --- /dev/null > > +++ b/gcc/testsuite/gcc.dg/pr115027.c > > @@ -0,0 +1,8 @@ > > +/* { dg-do compile } */ > > +/* { dg-options "-Wunused-but-set-variable" } */ > > + > > +void f(void) > > +{ > > + struct foo { void *p; }; > > + struct foo g = { &g }; /* { dg-warning "set but not used" } */ > > +} > > >