Message ID | 20160919215700.GR7282@tucnak.redhat.com |
---|---|
State | New |
Headers | show |
OK. On Mon, Sep 19, 2016 at 5:57 PM, Jakub Jelinek <jakub@redhat.com> wrote: > 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 <jakub@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
--- 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); +}