diff mbox

[C++] Fix ICE with class fields with invalid types (PR c++/77626)

Message ID 20160919215700.GR7282@tucnak.redhat.com
State New
Headers show

Commit Message

Jakub Jelinek Sept. 19, 2016, 9:57 p.m. UTC
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.


	Jakub

Comments

Jason Merrill Sept. 20, 2016, 3:01 p.m. UTC | #1
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
diff mbox

Patch

--- 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);
+}