enable-checking: error_mark accessed as type

Martin v. Loewis martin@mira.isdn.cs.tu-berlin.de
Sun Mar 14 12:01:00 GMT 1999


In many cases, cc1plus will put error_mark as the type into a _DECL
node. This will later break since it tries to access the error mark as
a type, eg. when checking TYPE_NEEDS_DESTRUCTOR or when calling
STRIP_NOPS inside of integer_zerop.

This patch introduces a new LANG_TYPE node, error_type_node. It is not
a general replacement of error_mark; it should only serve as the TYPE
field for nodes which have an error in their type.

The patch removes a few problems detected by enable-checking, and does
not break any test cases.

Regards,
Martin

1999-03-14  Martin von Löwis  <loewis@informatik.hu-berlin.de>

	* cp-tree.h (error_type_node): Declare.
	* decl.c: Define.
	(init_decl_processing): Initialize.
	(require_complete_types_for_parms): Use it.
	(grokvardecl): Likewise.
	* tree.c (search_tree): Support error_type_node.
	(no_linkage_check): Likewise.
	* typeck2.c (store_init_value): Likewise.

	* tree.c (build_dummy_object): Build ERROR_MARK with proper type.
	(is_dummy_object): Check for such a node.
	Detected by g++.bob/inherit1.C

	* expr.c (cplus_expand_expr): Expand 0 if new is in error.
	Detected by g++.brendan/crash19.C

Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.206
diff -c -p -r1.206 cp-tree.h
*** cp-tree.h	1999/03/09 23:02:27	1.206
--- cp-tree.h	1999/03/14 19:26:34
*************** extern tree error_mark_list;
*** 2128,2134 ****
  
  extern tree ptr_type_node;
  extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
! extern tree unknown_type_node;
  extern tree opaque_type_node, signature_type_node;
  
  /* Node for "pointer to (virtual) function".
--- 2128,2134 ----
  
  extern tree ptr_type_node;
  extern tree class_type_node, record_type_node, union_type_node, enum_type_node;
! extern tree unknown_type_node, error_type_node;
  extern tree opaque_type_node, signature_type_node;
  
  /* Node for "pointer to (virtual) function".
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.322
diff -c -p -r1.322 decl.c
*** decl.c	1999/03/13 01:16:31	1.322
--- decl.c	1999/03/14 19:27:03
*************** static tree global_type_node;
*** 331,337 ****
  
  tree class_star_type_node;
  tree class_type_node, record_type_node, union_type_node, enum_type_node;
! tree unknown_type_node;
  tree opaque_type_node, signature_type_node;
  tree sigtable_entry_type;
  
--- 331,337 ----
  
  tree class_star_type_node;
  tree class_type_node, record_type_node, union_type_node, enum_type_node;
! tree unknown_type_node, error_type_node;
  tree opaque_type_node, signature_type_node;
  tree sigtable_entry_type;
  
*************** init_decl_processing ()
*** 6419,6424 ****
--- 6419,6431 ----
    TYPE_POINTER_TO (unknown_type_node) = unknown_type_node;
    TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node;
  
+   /* Like unknown type, but for code that was in error. */
+   error_type_node = make_node (LANG_TYPE);
+   record_unknown_type (error_type_node, "error type");
+   TREE_TYPE (error_type_node) = error_type_node;
+   TYPE_POINTER_TO (error_type_node) = error_type_node;
+   TYPE_REFERENCE_TO (error_type_node) = error_type_node;
+ 
    /* This is for handling opaque types in signatures.  */
    opaque_type_node = copy_node (ptr_type_node);
    TYPE_MAIN_VARIANT (opaque_type_node) = opaque_type_node;
*************** grokvardecl (type, declarator, specbits_
*** 8674,8679 ****
--- 8681,8689 ----
        else
  	context = NULL_TREE;
  
+       if (type == error_mark_node)
+ 	type = error_type_node;
+ 
        decl = build_decl (VAR_DECL, declarator, complete_type (type));
  
        if (context)
*************** require_complete_types_for_parms (parms)
*** 11321,11327 ****
  		   IDENTIFIER_POINTER (DECL_NAME (parms)));
  	  else
  	    error ("parameter has incomplete type");
! 	  TREE_TYPE (parms) = error_mark_node;
  	}
        else
  	layout_decl (parms, 0);
--- 11331,11337 ----
  		   IDENTIFIER_POINTER (DECL_NAME (parms)));
  	  else
  	    error ("parameter has incomplete type");
! 	  TREE_TYPE (parms) = error_type_node;
  	}
        else
  	layout_decl (parms, 0);
Index: expr.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/expr.c,v
retrieving revision 1.20
diff -c -p -r1.20 expr.c
*** expr.c	1998/12/16 21:15:23	1.20
--- expr.c	1999/03/14 19:27:04
***************
*** 1,6 ****
  /* Convert language-specific tree expression to rtl instructions,
     for GNU compiler.
!    Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
--- 1,6 ----
  /* Convert language-specific tree expression to rtl instructions,
     for GNU compiler.
!    Copyright (C) 1988, 92-97, 1998, 1999 Free Software Foundation, Inc.
  
  This file is part of GNU CC.
  
*************** cplus_expand_expr (exp, target, tmode, m
*** 217,223 ****
  	  TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
  
      case NEW_EXPR:
!       return expand_expr (build_new_1 (exp), target, tmode, modifier);
  
      default:
        break;
--- 217,229 ----
  	  TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
  
      case NEW_EXPR:
!       {
! 	tree new_expr = build_new_1 (exp);
! 	if (new_expr != error_mark_node)
! 	  return expand_expr (new_expr, target, tmode, modifier);
! 	else
! 	  return expand_expr (integer_zero_node, target, tmode, modifier);
!       }
  
      default:
        break;
Index: tree.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/tree.c,v
retrieving revision 1.98
diff -c -p -r1.98 tree.c
*** tree.c	1999/03/06 17:41:36	1.98
--- tree.c	1999/03/14 19:27:06
*************** search_tree (t, func)
*** 1763,1768 ****
--- 1763,1774 ----
  	TRY (TYPE_PTRMEMFUNC_FN_TYPE (t));
        break;
        
+ 
+     case LANG_TYPE:
+       if (t == error_type_node)
+ 	return t;
+       /* else fall through. */
+ 
        /*  This list is incomplete, but should suffice for now.
  	  It is very important that `sorry' not call
  	  `report_error_function'.  That could cause an infinite loop.  */
*************** no_linkage_check (t)
*** 1799,1805 ****
       tree t;
  {
    t = search_tree (t, no_linkage_helper);
!   if (t != error_mark_node)
      return t;
    return NULL_TREE;
  }
--- 1805,1811 ----
       tree t;
  {
    t = search_tree (t, no_linkage_helper);
!   if (t != error_mark_node && t != error_type_node)
      return t;
    return NULL_TREE;
  }
*************** tree
*** 2700,2706 ****
  build_dummy_object (type)
       tree type;
  {
!   tree decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node);
    return build_indirect_ref (decl, NULL_PTR);
  }
  
--- 2706,2713 ----
  build_dummy_object (type)
       tree type;
  {
!   tree decl = build1 (NOP_EXPR, build_pointer_type (type), 
! 		      build (ERROR_MARK, error_type_node));
    return build_indirect_ref (decl, NULL_PTR);
  }
  
*************** is_dummy_object (ob)
*** 2743,2749 ****
    if (TREE_CODE (ob) == INDIRECT_REF)
      ob = TREE_OPERAND (ob, 0);
    return (TREE_CODE (ob) == NOP_EXPR
! 	  && TREE_OPERAND (ob, 0) == error_mark_node);
  }
  
  /* Returns 1 iff type T is a POD type, as defined in [basic.types].  */
--- 2750,2757 ----
    if (TREE_CODE (ob) == INDIRECT_REF)
      ob = TREE_OPERAND (ob, 0);
    return (TREE_CODE (ob) == NOP_EXPR
! 	  && TREE_OPERAND (ob, 0)
! 	  && TREE_CODE (TREE_OPERAND (ob, 0)) == ERROR_MARK);
  }
  
  /* Returns 1 iff type T is a POD type, as defined in [basic.types].  */
Index: typeck2.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/typeck2.c,v
retrieving revision 1.51
diff -c -p -r1.51 typeck2.c
*** typeck2.c	1999/03/13 01:16:36	1.51
--- typeck2.c	1999/03/14 19:27:10
*************** store_init_value (decl, init)
*** 529,534 ****
--- 529,536 ----
    type = TREE_TYPE (decl);
    if (TREE_CODE (type) == ERROR_MARK)
      return NULL_TREE;
+   if (type == error_type_node)
+     return NULL_TREE;
  
  #if 0
    /* This breaks arrays, and should not have any effect for other decls.  */


More information about the Gcc-patches mailing list