Hi!

layout_class_type for FIELD_DECLs with error_mark_node skips further
processing, so such fields don't have DECL_FIELD_OFFSET and
DECL_FIELD_BIT_OFFSET, thus byte_position ICEs on it.

So, when we walk in constexpr handling all FIELD_DECLs, this patch fixes it
by skipping over fields with error_mark_node types.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2016-09-19  Jakub Jelinek  <ja...@redhat.com>

        PR c++/77626
        * constexpr.c (cxx_fold_indirect_ref): Don't call byte_position on
        FIELD_DECLs with error_mark_node type.  Remove useless break; after
        return.

        * g++.dg/other/pr77626.C: New test.

--- gcc/cp/constexpr.c.jj       2016-09-16 22:22:00.000000000 +0200
+++ gcc/cp/constexpr.c  2016-09-19 13:00:02.542599407 +0200
@@ -2894,13 +2894,11 @@ cxx_fold_indirect_ref (location_t loc, t
          tree field = TYPE_FIELDS (optype);
          for (; field; field = DECL_CHAIN (field))
            if (TREE_CODE (field) == FIELD_DECL
+               && TREE_TYPE (field) != error_mark_node
                && integer_zerop (byte_position (field))
                && (same_type_ignoring_top_level_qualifiers_p
                    (TREE_TYPE (field), type)))
-             {
-               return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
-               break;
-             }
+             return fold_build3 (COMPONENT_REF, type, op, field, NULL_TREE);
        }
     }
   else if (TREE_CODE (sub) == POINTER_PLUS_EXPR
@@ -2972,14 +2970,12 @@ cxx_fold_indirect_ref (location_t loc, t
              tree field = TYPE_FIELDS (op00type);
              for (; field; field = DECL_CHAIN (field))
                if (TREE_CODE (field) == FIELD_DECL
+                   && TREE_TYPE (field) != error_mark_node
                    && tree_int_cst_equal (byte_position (field), op01)
                    && (same_type_ignoring_top_level_qualifiers_p
                        (TREE_TYPE (field), type)))
-                 {
-                   return fold_build3 (COMPONENT_REF, type, op00,
-                                       field, NULL_TREE);
-                   break;
-                 }
+                 return fold_build3 (COMPONENT_REF, type, op00,
+                                     field, NULL_TREE);
            }
        }
     }
--- gcc/testsuite/g++.dg/other/pr77626.C.jj     2016-09-19 13:22:57.895418630 
+0200
+++ gcc/testsuite/g++.dg/other/pr77626.C        2016-09-19 13:22:21.000000000 
+0200
@@ -0,0 +1,13 @@
+// PR c++/77626
+// { dg-do compile }
+
+struct B;                      // { dg-message "forward declaration of" }
+struct A { struct B b; };      // { dg-error "has incomplete type" }
+void bar (int);
+
+void
+foo ()
+{
+  A a;
+  bar ((int &) a);
+}

        Jakub

Reply via email to