Message ID | CAAgBjMmY0n=UaVTxXe+mPCSysYhPibsxOySihxt7TLH=ai3B1g@mail.gmail.com |
---|---|
State | New |
Headers | show |
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? > g++ rejects it during parsing. I tried similarly in C FE by adding a > check for decl with incomplete struct/union type in finish_decl(), > however that fails to compile the following case: > typedef struct foo foo_t; > foo_t x; > struct foo { int i; }; > g++ rejects the above case as well but gcc accepts it. > Do C and C++ standards differ in this regard ? I don't know about C++, but this sort of thing is valid C if the type is complete at the end of the translation unit or is an incomplete array type (but not in the case where the variable is static - such a case with static, if supported, is an extension).
On 01/14/16 16:57, Joseph Myers wrote: > On Thu, 14 Jan 2016, Prathamesh Kulkarni wrote: >> g++ rejects it during parsing. I tried similarly in C FE by adding a >> check for decl with incomplete struct/union type in finish_decl(), >> however that fails to compile the following case: >> typedef struct foo foo_t; >> foo_t x; >> struct foo { int i; }; >> g++ rejects the above case as well but gcc accepts it. >> Do C and C++ standards differ in this regard ? > > I don't know about C++, but this sort of thing is valid C if the type is > complete at the end of the translation unit or is an incomplete array type > (but not in the case where the variable is static - such a case with > static, if supported, is an extension). It's ill-formed C++. 7.1.1/8 allows you to use a declared but undefined struct with 'extern', but not without it. 'The name of a declared but undefined class can be used in an extern declaration. Such a declaration can only be used in ways that do not require a complete class type' (Although it doesn't seem to explicitly say that such a name can be used without an 'extern', the implication is that it cannot). nathan
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 950f6c5..1560a78 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -974,6 +974,12 @@ check_global_declaration (symtab_node *snode) ? OPT_Wunused_const_variable : OPT_Wunused_variable), "%qD defined but not used", decl); + + if (VAR_P (decl) && !DECL_EXTERNAL (decl) + && RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)) && DECL_SIZE (decl) == 0) + { + error ("storage size of %q+D isn%'t known", decl); + } } /* Discover all functions and variables that are trivially needed, analyze 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..9113076 100644 --- a/gcc/testsuite/gcc.dg/declspec-1.c +++ b/gcc/testsuite/gcc.dg/declspec-1.c @@ -9,7 +9,8 @@ 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; diff --git a/gcc/testsuite/gcc.dg/struct-incompl-2.c b/gcc/testsuite/gcc.dg/struct-incompl-2.c new file mode 100644 index 0000000..f3957eb --- /dev/null +++ b/gcc/testsuite/gcc.dg/struct-incompl-2.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +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" } */ + +extern struct undefined_object object;