On 16 January 2016 at 02:56, Joseph Myers <jos...@codesourcery.com> wrote: > On Fri, 15 Jan 2016, Prathamesh Kulkarni wrote: > >> On 15 January 2016 at 03:27, Joseph Myers <jos...@codesourcery.com> wrote: >> > On Thu, 14 Jan 2016, Prathamesh Kulkarni wrote: >> > >> >> Hi, >> >> For test-case containing only the following declaration: >> >> static struct undefined_struct object; >> >> gcc rejects it at -O0 in assemble_variable() with error "storage size >> >> of <var> is unknown", >> >> however no error is reported when compiled with -O2. >> > >> > Cf bug 24293 (for the -fsyntax-only case) - does this patch fix that? >> Ah this doesn't fix PR24293, it seems analyze_function() doesn't get >> called for -fsyntax-only. >> I don't have a good solution for this. I assume varpool won't be >> populated for -fsyntax-only ? >> And we need to walk over decls with incomplete struct/union types >> after parsing the whole translation unit. >> In the attached patch, I kept a global vec<tree> incomplete_record_decls; >> In finish_decl(), if the decl is static, has type struct/union and >> size 0 then it is appened to incomplete_record_decls. >> In c_parser_translation_unit(), iterate over incomplete_record_decls >> and if report error if any decl has size zero. >> The patch passes testsuite. > > There's a GNU C extension allowing forward declarations of enums, and it > seems that > > static enum e x; > > doesn't get diagnosed either with -fsyntax-only. Thus I think you should > cover that case as well. Done in the attached patch. It regresses pr63549.c because the error showed up there, adjusted the test-case to accept the error. OK to commit ?
Thanks, Prathamesh > > -- > Joseph S. Myers > jos...@codesourcery.com
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index 915376d..d36fc67 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -4791,6 +4791,13 @@ finish_decl (tree decl, location_t init_loc, tree init, TREE_TYPE (decl) = error_mark_node; } + if ((RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) + || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) + && DECL_SIZE (decl) == 0 && TREE_STATIC (decl)) + { + incomplete_record_decls.safe_push (decl); + } + if (is_global_var (decl) && DECL_SIZE (decl) != 0) { if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c index a0e0052..3c8a496 100644 --- a/gcc/c/c-parser.c +++ b/gcc/c/c-parser.c @@ -59,6 +59,8 @@ along with GCC; see the file COPYING3. If not see #include "gimple-expr.h" #include "context.h" +vec<tree> incomplete_record_decls = vNULL; + void set_c_expr_source_range (c_expr *expr, location_t start, location_t finish) @@ -1421,6 +1423,16 @@ c_parser_translation_unit (c_parser *parser) } while (c_parser_next_token_is_not (parser, CPP_EOF)); } + + for (unsigned i = 0; i < incomplete_record_decls.length (); ++i) + { + tree decl = incomplete_record_decls[i]; + if (DECL_SIZE (decl) == 0 && TREE_TYPE (decl) != error_mark_node) + { + error ("storage size of %q+D isn%'t known", decl); + TREE_TYPE (decl) = error_mark_node; + } + } } /* Parse an external declaration (C90 6.7, C99 6.9). diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h index 81a3d58..cf79ba7 100644 --- a/gcc/c/c-tree.h +++ b/gcc/c/c-tree.h @@ -731,4 +731,6 @@ set_c_expr_source_range (c_expr *expr, /* In c-fold.c */ extern tree decl_constant_value_for_optimization (tree); +extern vec<tree> incomplete_record_decls; + #endif /* ! GCC_C_TREE_H */ diff --git a/gcc/testsuite/gcc.dg/Wcxx-compat-8.c b/gcc/testsuite/gcc.dg/Wcxx-compat-8.c index f7e8c55..4e9ddc1 100644 --- a/gcc/testsuite/gcc.dg/Wcxx-compat-8.c +++ b/gcc/testsuite/gcc.dg/Wcxx-compat-8.c @@ -33,6 +33,7 @@ enum e3 __typeof__ (struct s5 { int i; }) v5; /* { dg-warning "invalid in C\[+\]\[+\]" } */ __typeof__ (struct t5) w5; /* { dg-bogus "invalid in C\[+\]\[+\]" } */ + /* { dg-error "storage size of 'w5' isn't known" "" { target *-*-* } 35 } */ int f1 (struct s1 *p) @@ -64,4 +65,4 @@ f5 () return &((struct t8) { }); /* { dg-warning "invalid in C\[+\]\[+\]" } */ } -/* { dg-error "invalid use of undefined type" "" { target *-*-* } 64 } */ +/* { dg-error "invalid use of undefined type" "" { target *-*-* } 65 } */ diff --git a/gcc/testsuite/gcc.dg/declspec-1.c b/gcc/testsuite/gcc.dg/declspec-1.c index c19f107..b024601 100644 --- a/gcc/testsuite/gcc.dg/declspec-1.c +++ b/gcc/testsuite/gcc.dg/declspec-1.c @@ -9,13 +9,15 @@ typedef int t; /* These should all be diagnosed, but only once, not for every identifier declared. */ struct s0 int x0, /* { dg-error "two or more data types" } */ -x1; +/* { dg-error "storage size of 'x0' isn't known" "" { target *-*-* } 11 } */ +x1; /* { dg-error "storage size of 'x1' isn't known" } */ char union u0 x2, /* { dg-error "two or more data types" } */ x3; enum e0 struct s1 x4, /* { dg-error "two or more data types" } */ -x5; + /* { dg-error "storage size of 'x4' isn't known" "" { target *-*-* } 18 } */ +x5; /* { dg-error "storage size of 'x5' isn't known" } */ short short x6, /* { dg-error "duplicate" } */ x7; diff --git a/gcc/testsuite/gcc.dg/pr24293.c b/gcc/testsuite/gcc.dg/pr24293.c new file mode 100644 index 0000000..5bf7ad17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr24293.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-fsyntax-only" } */ + +static struct foo x; /* { dg-error "storage size of 'x' isn't known" } */ +static union bar y; /* { dg-error "storage size of 'y' isn't known" } */ + +typedef struct P p; +static p p_obj; /* { dg-error "storage size of 'p_obj' isn't known" } */ + +static enum e e_var; /* { dg-error "storage size of 'e_var' isn't known" } */ + +extern struct undefined_object object; diff --git a/gcc/testsuite/gcc.dg/pr63549.c b/gcc/testsuite/gcc.dg/pr63549.c index c9b1718..bd0b706 100644 --- a/gcc/testsuite/gcc.dg/pr63549.c +++ b/gcc/testsuite/gcc.dg/pr63549.c @@ -2,6 +2,6 @@ /* { dg-do compile } */ /* { dg-options "" } */ -enum E e; +enum E e; /* { dg-error "storage size of 'e' isn't known" } */ int a[10]; int i = a[e]; /* { dg-error "has an incomplete type" } */
ChangeLog
Description: Binary data