re PR middle-end/59338 (error: position plus size exceeds size of referenced object...
authorRichard Biener <rguenther@suse.de>
Fri, 29 Nov 2013 12:09:12 +0000 (12:09 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Fri, 29 Nov 2013 12:09:12 +0000 (12:09 +0000)
2013-11-29  Richard Biener  <rguenther@suse.de>

PR middle-end/59338
* tree-cfg.c (verify_expr): Restrict bounds verification of
BIT_FIELD_REF arguments to non-aggregate typed base objects.

* gcc.dg/torture/pr59338.c: New testcase.

From-SVN: r205521

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/torture/pr59338.c [new file with mode: 0644]
gcc/tree-cfg.c

index fdd9485adcb606b281735c539ff39f872af86080..9e7e1873de0508e5142d78e930a011e271db8231 100644 (file)
@@ -1,3 +1,9 @@
+2013-11-29  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/59338
+       * tree-cfg.c (verify_expr): Restrict bounds verification of
+       BIT_FIELD_REF arguments to non-aggregate typed base objects.
+
 2013-11-29  Richard Biener  <rguenther@suse.de>
 
        PR tree-optimization/59334
index 4580ec5fa522e1850cb6ba0320a1d467b1169dc5..411d5e963aa2550d7d3b5fc07764889ced896ffd 100644 (file)
@@ -1,3 +1,8 @@
+2013-11-29  Richard Biener  <rguenther@suse.de>
+
+       PR middle-end/59338
+       * gcc.dg/torture/pr59338.c: New testcase.
+
 2013-11-29  Jakub Jelinek  <jakub@redhat.com>
 
        PR lto/59326
diff --git a/gcc/testsuite/gcc.dg/torture/pr59338.c b/gcc/testsuite/gcc.dg/torture/pr59338.c
new file mode 100644 (file)
index 0000000..481c84d
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+typedef enum
+{
+  XYZZY,
+} enumType;
+
+typedef struct
+{
+  unsigned char More : 1;
+} tResp;
+
+typedef struct
+{
+  enumType QueryType;
+  union
+    {
+      tResp l[0];
+    } u;
+} tQResp;
+
+void test(void)
+{
+  tQResp *qResp = (0);
+  if (qResp->u.l[0].More == 0)
+    return;
+}
index f8937c6e0f18692f9701bb0ac7ca42bb172b9b18..605990eed0e956b1c77db2280eea2e57b534bbf2 100644 (file)
@@ -2715,17 +2715,6 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
          tree t0 = TREE_OPERAND (t, 0);
          tree t1 = TREE_OPERAND (t, 1);
          tree t2 = TREE_OPERAND (t, 2);
-         tree t0_type = TREE_TYPE (t0);
-         unsigned HOST_WIDE_INT t0_size = 0;
-
-         if (tree_fits_uhwi_p (TYPE_SIZE (t0_type)))
-           t0_size = tree_to_uhwi (TYPE_SIZE (t0_type));
-         else 
-           {
-             HOST_WIDE_INT t0_max_size = max_int_size_in_bytes (t0_type);
-             if (t0_max_size > 0)
-               t0_size = t0_max_size * BITS_PER_UNIT;
-           }
          if (!tree_fits_uhwi_p (t1)
              || !tree_fits_uhwi_p (t2))
            {
@@ -2749,8 +2738,9 @@ verify_expr (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
                     "match field size of BIT_FIELD_REF");
              return t;
            }
-         if (t0_size != 0
-             && tree_to_uhwi (t1) + tree_to_uhwi (t2) > t0_size)
+         if (!AGGREGATE_TYPE_P (TREE_TYPE (t0))
+             && (tree_to_uhwi (t1) + tree_to_uhwi (t2)
+                 > tree_to_uhwi (TYPE_SIZE (TREE_TYPE (t0)))))
            {
              error ("position plus size exceeds size of referenced object in "
                     "BIT_FIELD_REF");