Message ID | Y6BFjLgQdwlgkNnZ@tucnak |
---|---|
State | New |
Headers | show |
Series | c: Diagnose compound literals with function type [PR108043] | expand |
On Mon, Dec 19, 2022 at 12:05:48PM +0100, Jakub Jelinek wrote: > Hi! > > Both C99 and latest C2X say that compound literal shall have an object type > (complete object type in the latter case) or array of unknown bound, > so complit with function type is invalid. When the initializer had to be > non-empty for such case, we used to diagnose it as incorrect initializer, > but with (fntype){} now allowed we just ICE on it. > > The following patch diagnoses that. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? This looks OK to me, thanks. > 2022-12-19 Jakub Jelinek <jakub@redhat.com> > > PR c/108043 > * c-parser.cc (c_parser_postfix_expression_after_paren_type): Diagnose > compound literals with function type. > > * gcc.dg/pr108043.c: New test. > * gcc.dg/c99-complit-2.c (foo): Adjust expected diagnostics for > complit with function type. > > --- gcc/c/c-parser.cc.jj 2022-11-18 09:00:44.331323558 +0100 > +++ gcc/c/c-parser.cc 2022-12-16 13:08:51.143083269 +0100 > @@ -10924,6 +10924,11 @@ c_parser_postfix_expression_after_paren_ > error_at (type_loc, "compound literal has variable size"); > type = error_mark_node; > } > + else if (TREE_CODE (type) == FUNCTION_TYPE) > + { > + error_at (type_loc, "compound literal has function type"); > + type = error_mark_node; > + } > if (constexpr_p && type != error_mark_node) > { > tree type_no_array = strip_array_types (type); > --- gcc/testsuite/gcc.dg/pr108043.c.jj 2022-12-16 13:15:40.122083457 +0100 > +++ gcc/testsuite/gcc.dg/pr108043.c 2022-12-16 13:15:20.840366320 +0100 > @@ -0,0 +1,12 @@ > +/* PR c/108043 */ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > + > +typedef void F (void); > + > +void > +foo (void) > +{ > + (F) {}; /* { dg-error "compound literal has function type" } */ > + (F) { foo }; /* { dg-error "compound literal has function type" } */ > +} > --- gcc/testsuite/gcc.dg/c99-complit-2.c.jj 2020-01-12 11:54:37.393398623 +0100 > +++ gcc/testsuite/gcc.dg/c99-complit-2.c 2022-12-19 11:51:45.098467295 +0100 > @@ -23,7 +23,7 @@ foo (int a) > /* { dg-error "init" "incomplete union type" { target *-*-* } .-1 } */ > /* { dg-error "invalid use of undefined type" "" { target *-*-* } .-2 } */ > (void (void)) { 0 }; /* { dg-bogus "warning" "warning in place of error" } */ > - /* { dg-error "init" "function type" { target *-*-* } .-1 } */ > + /* { dg-error "compound literal has function type" "function type" { target *-*-* } .-1 } */ > (int [a]) { 1 }; /* { dg-bogus "warning" "warning in place of error" } */ > /* { dg-error "init|variable" "VLA type" { target *-*-* } .-1 } */ > /* Initializers must not attempt to initialize outside the object > > Jakub > Marek
--- gcc/c/c-parser.cc.jj 2022-11-18 09:00:44.331323558 +0100 +++ gcc/c/c-parser.cc 2022-12-16 13:08:51.143083269 +0100 @@ -10924,6 +10924,11 @@ c_parser_postfix_expression_after_paren_ error_at (type_loc, "compound literal has variable size"); type = error_mark_node; } + else if (TREE_CODE (type) == FUNCTION_TYPE) + { + error_at (type_loc, "compound literal has function type"); + type = error_mark_node; + } if (constexpr_p && type != error_mark_node) { tree type_no_array = strip_array_types (type); --- gcc/testsuite/gcc.dg/pr108043.c.jj 2022-12-16 13:15:40.122083457 +0100 +++ gcc/testsuite/gcc.dg/pr108043.c 2022-12-16 13:15:20.840366320 +0100 @@ -0,0 +1,12 @@ +/* PR c/108043 */ +/* { dg-do compile } */ +/* { dg-options "" } */ + +typedef void F (void); + +void +foo (void) +{ + (F) {}; /* { dg-error "compound literal has function type" } */ + (F) { foo }; /* { dg-error "compound literal has function type" } */ +} --- gcc/testsuite/gcc.dg/c99-complit-2.c.jj 2020-01-12 11:54:37.393398623 +0100 +++ gcc/testsuite/gcc.dg/c99-complit-2.c 2022-12-19 11:51:45.098467295 +0100 @@ -23,7 +23,7 @@ foo (int a) /* { dg-error "init" "incomplete union type" { target *-*-* } .-1 } */ /* { dg-error "invalid use of undefined type" "" { target *-*-* } .-2 } */ (void (void)) { 0 }; /* { dg-bogus "warning" "warning in place of error" } */ - /* { dg-error "init" "function type" { target *-*-* } .-1 } */ + /* { dg-error "compound literal has function type" "function type" { target *-*-* } .-1 } */ (int [a]) { 1 }; /* { dg-bogus "warning" "warning in place of error" } */ /* { dg-error "init|variable" "VLA type" { target *-*-* } .-1 } */ /* Initializers must not attempt to initialize outside the object