]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/57793 (ICE with bitfields in get_bit_range)
authorJason Merrill <jason@redhat.com>
Sat, 13 Jul 2013 23:10:17 +0000 (19:10 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Sat, 13 Jul 2013 23:10:17 +0000 (19:10 -0400)
PR c++/57793
c/
* c-decl.c (finish_struct): Check for too-large class.
cp/
* class.c (layout_class_type): Check for too-large class.

From-SVN: r200938

gcc/c/ChangeLog
gcc/c/c-decl.c
gcc/cp/ChangeLog
gcc/cp/class.c
gcc/testsuite/c-c++-common/pr57793.c [new file with mode: 0644]

index 43cc83902efd0e1c1082c0bd04b44ae38874f610..15bc1aa26fc63dfd120e13b73d9905dcfe4b71d7 100644 (file)
@@ -1,3 +1,8 @@
+2013-07-13  Jason Merrill  <jason@redhat.com>
+
+       PR c++/57793
+       * c-decl.c (finish_struct): Check for too-large class.
+
 2013-07-04  Joern Rennecke <joern.rennecke@embecosm.com>
 
        PR c/57821
index 8170a80ac6d08d1d44a9df343c6109365bb38206..f7ae648f024fb6ad198570571acfad8caca46181 100644 (file)
@@ -7210,6 +7210,12 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 
   layout_type (t);
 
+  if (TYPE_SIZE_UNIT (t)
+      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
+      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
+      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
+    error ("type %qT is too large", t);
+
   /* Give bit-fields their proper types.  */
   {
     tree *fieldlistp = &fieldlist;
index 3b59f2146a6c2b94bd4adbef30dab6084d688b5c..1bf287aecee60ccbb39a99eb608a6377696306e2 100644 (file)
@@ -1,5 +1,8 @@
 2013-07-13  Jason Merrill  <jason@redhat.com>
 
+       PR c++/57793
+       * class.c (layout_class_type): Check for too-large class.
+
        * call.c (can_convert): Allow user-defined conversions.
        (can_convert_standard): New.
        * cp-tree.h: Declare it.
index e5166324e4c2be9768f6b8e74f218a85839143fa..45652a68dbef83a49b9026f535d9259907a794f1 100644 (file)
@@ -6237,6 +6237,12 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
+  if (TYPE_SIZE_UNIT (t)
+      && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
+      && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))
+      && !valid_constant_size_p (TYPE_SIZE_UNIT (t)))
+    error ("type %qT is too large", t);
+
   /* Warn about bases that can't be talked about due to ambiguity.  */
   warn_about_ambiguous_bases (t);
 
diff --git a/gcc/testsuite/c-c++-common/pr57793.c b/gcc/testsuite/c-c++-common/pr57793.c
new file mode 100644 (file)
index 0000000..d66fada
--- /dev/null
@@ -0,0 +1,23 @@
+/* PR c++/57793 */
+
+struct A { unsigned a : 1; unsigned b : 1; };
+struct B     /* { dg-error "type .B. is too large" "" { target { c++ && ilp32 } } } */
+{
+  unsigned char c[0x40000000];
+  unsigned char d[0x40000ff0];
+  struct A e;
+}; /* { dg-error "type .struct B. is too large" "" { target { c && ilp32 } } } */
+
+void *foo (struct B *p)
+{
+  if (p->e.a)
+    return (void *) 0;
+  p->e.b = 1;
+  return p->c;
+}
+
+void
+bar (struct B *p)
+{
+  foo (p);
+}