aboutsummaryrefslogtreecommitdiff
path: root/gcc/c
diff options
context:
space:
mode:
authorPrathamesh Kulkarni <prathamesh.kulkarni@linaro.org>2016-01-20 16:25:23 +0000
committerPrathamesh Kulkarni <prathamesh3492@gcc.gnu.org>2016-01-20 16:25:23 +0000
commitd25c7690621ad26fe03b0c38040ded1e8667372c (patch)
tree8f34e243e6c141a45fea0369c0d2d05d4e2954cf /gcc/c
parentb235cdd5f50456368772692ce5ec139e2e09b360 (diff)
downloadgcc-d25c7690621ad26fe03b0c38040ded1e8667372c.zip
gcc-d25c7690621ad26fe03b0c38040ded1e8667372c.tar.gz
gcc-d25c7690621ad26fe03b0c38040ded1e8667372c.tar.bz2
re PR c/24293 (Undefined behaviour not diagnosed with -fsyntax-only)
2016-01-15 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org> PR c/24293 * c-tree.h (incomplete_record_decls): Declare. * c-parser.c (incomplete_record_decls): Define. (c_parser_translation_unit): Iterate through incomplete_record_decls and report error if any decl has zero size. * c-decl.c (finish_decl): Append static decl with incomplete struct/union or enum type to incomplete_record_decls. testsuite/ * gcc.dg/pr24293.c: New test. * gcc.dg/Wcxx-compat-8.c: Adjust to accept error due to incomplete struct type. * gcc.dg/declspec-1.c: Likewise. * gcc.dg/pr63549.c: Likewise. From-SVN: r232622
Diffstat (limited to 'gcc/c')
-rw-r--r--gcc/c/ChangeLog10
-rw-r--r--gcc/c/c-decl.c6
-rw-r--r--gcc/c/c-parser.c19
-rw-r--r--gcc/c/c-tree.h2
4 files changed, 37 insertions, 0 deletions
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index d11a822..697dd8d 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,13 @@
+2016-01-15 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ PR c/24293
+ * c-tree.h (incomplete_record_decls): Declare.
+ * c-parser.c (incomplete_record_decls): Define.
+ (c_parser_translation_unit): Iterate through incomplete_record_decls and
+ report error if any decl has zero size.
+ * c-decl.c (finish_decl): Append static decl with incomplete struct/union
+ or enum type to incomplete_record_decls.
+
2016-01-14 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/68773
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 5830e22..1ec6042 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))
+ || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
+ && DECL_SIZE (decl) == NULL_TREE
+ && 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 919680a..efac47b 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -59,6 +59,15 @@ along with GCC; see the file COPYING3. If not see
#include "gimple-expr.h"
#include "context.h"
+/* We need to walk over decls with incomplete struct/union/enum types
+ after parsing the whole translation unit.
+ In finish_decl(), if the decl is static, has incomplete
+ struct/union/enum type, it is appeneded to incomplete_record_decls.
+ In c_parser_translation_unit(), we iterate over incomplete_record_decls
+ and report error if any of the decls are still incomplete. */
+
+vec<tree> incomplete_record_decls = vNULL;
+
void
set_c_expr_source_range (c_expr *expr,
location_t start, location_t finish)
@@ -1421,6 +1430,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) == NULL_TREE && 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 */