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.

Thanks,
Prathamesh
>
>> 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).
>
> --
> Joseph S. Myers
> jos...@codesourcery.com
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 915376d..ac542e1 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -4791,6 +4791,12 @@ 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))
+         && 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..8af04f7 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,13 @@ 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)
+       error ("storage size of %q+D isn%'t known", decl);
+    }
 }
 
 /* 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..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/pr24293.c b/gcc/testsuite/gcc.dg/pr24293.c
new file mode 100644
index 0000000..33285e7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr24293.c
@@ -0,0 +1,10 @@
+/* { 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" } */
+
+extern struct undefined_object object;

Attachment: ChangeLog
Description: Binary data

Reply via email to