More gimplification and inlining patches

Richard Kenner kenner@vlsi1.ultra.nyu.edu
Tue Jul 6 03:12:00 GMT 2004


These fix more ICEs in the ACATS suite.  I thought it was all, but I've now
been able to run the full suite and see there are still a few left.

It turned out to be incorrect to remap the type of a PARM_DECL of a
function being inlined: that type is to be interpreted in the calling
function's context.  The correct fix was to only remap types that are
variably-modified by variables in the function being called: if the type
is modified by variables of an outer function, that same type must be used.

Also, array_type_nelts returns the number minus one and both callers
got it wrong.  A few other minor things are fixed here as well.

Tested on x86_64-linux-gnu.

2004-07-05  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>

	* langhooks-def.h (LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P): Extra arg.
	* langhooks.h (var_mod_type_p): Likewise.
	* c-decl.c (finish_decl): Add extra arg to variably_modified_type_p.
	* expr.c (count_type_elements): Properly handle return from
	array_type_nelts and properly test for overflow.
	* gimplify.c (gimplify_init_constructor): Properly handle return
	from array_type_nelts.
	(gimplify_addr_expr): Remove redundant clear of TREE_SIDE_EFFECTS.
	* integrate.c (copy_decl_for_inlining): Correct comments.
	* tree-inline.c (remap_decl): Update comments, remove dead code,
	and copy DECL_FIELD_OFFSET and DECL_QUALIFIER, if they exist.
	(remap_type): Only remap if variably modified by vars in function
	being inlined.
	(copy_body_r): Use compatible_type langhooks to see when can fold.
	(setup_one_parameter): Don't remap type.
	(inline_forbidden_p_1): Add arg to variably_modified_type_p.
	* tree.c (recompute_tree_invarant_for_addr_expr): Properly
	compute TREE_INVARIANT for decl case.
	(find_var_from_fn): New function.
	(variably_modified_type_p): Add arg and call new function.
	* tree.h (variably_modified_type_p): Add extra arg.
	
	* cp/cp-lang.c (cp_var_mod_type_p): Add extra arg.
	* cp/decl.c (grokdeclarator): Extra arg to variably_modified_type_p.
	* cp/pt.c (check_instantiated_args, unify): Likewise.

*** c-decl.c	5 Jul 2004 19:49:10 -0000	1.527
--- c-decl.c	6 Jul 2004 01:14:05 -0000
*************** finish_decl (tree decl, tree init, tree 
*** 3038,3042 ****
      {
        if (!DECL_FILE_SCOPE_P (decl)
! 	  && variably_modified_type_p (TREE_TYPE (decl)))
  	add_stmt (build_stmt (DECL_EXPR, decl));
  
--- 3038,3042 ----
      {
        if (!DECL_FILE_SCOPE_P (decl)
! 	  && variably_modified_type_p (TREE_TYPE (decl), NULL_TREE))
  	add_stmt (build_stmt (DECL_EXPR, decl));
  
*** expr.c	5 Jul 2004 21:57:43 -0000	1.668
--- expr.c	6 Jul 2004 01:14:14 -0000
*************** count_type_elements (tree type)
*** 4498,4506 ****
  	if (telts && host_integerp (telts, 1))
  	  {
! 	    HOST_WIDE_INT n = tree_low_cst (telts, 1);
  	    HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type));
  	    if (n == 0)
  	      return 0;
! 	    if (max / n < m)
  	      return n * m;
  	  }
--- 4498,4506 ----
  	if (telts && host_integerp (telts, 1))
  	  {
! 	    HOST_WIDE_INT n = tree_low_cst (telts, 1) + 1;
  	    HOST_WIDE_INT m = count_type_elements (TREE_TYPE (type));
  	    if (n == 0)
  	      return 0;
! 	    else if (max / n > m)
  	      return n * m;
  	  }
*** gimplify.c	5 Jul 2004 16:39:15 -0000	2.41
--- gimplify.c	6 Jul 2004 01:14:22 -0000
*************** gimplify_init_constructor (tree *expr_p,
*** 2515,2519 ****
  		tree nelts = array_type_nelts (type);
  		if (!host_integerp (nelts, 1)
! 		    || tree_low_cst (nelts, 1) != len)
  		  cleared = 1;;
  	      }
--- 2515,2519 ----
  		tree nelts = array_type_nelts (type);
  		if (!host_integerp (nelts, 1)
! 		    || tree_low_cst (nelts, 1) + 1 != len)
  		  cleared = 1;;
  	      }
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 3051,3060 ****
        if (ret != GS_ERROR)
  	{
! 	  /* At this point, the argument of the ADDR_EXPR should be
! 	     sufficiently simple that there are never side effects.  */
! 	  /* ??? Could split out the decision code from build1 to verify.  */
! 	  TREE_SIDE_EFFECTS (expr) = 0;
! 
! 	  /* Make sure TREE_INVARIANT/TREE_CONSTANT is set properly.  */
  	  recompute_tree_invarant_for_addr_expr (expr);
  
--- 3051,3056 ----
        if (ret != GS_ERROR)
  	{
! 	  /* Make sure TREE_INVARIANT, TREE_CONSTANT, and TREE_SIDE_EFFECTS
! 	     is set properly.  */
  	  recompute_tree_invarant_for_addr_expr (expr);
  
*** integrate.c	4 Jul 2004 08:06:54 -0000	1.262
--- integrate.c	6 Jul 2004 01:14:22 -0000
*************** function_attribute_inlinable_p (tree fnd
*** 106,112 ****
  }
  
! /* Copy NODE (which must be a DECL, but not a PARM_DECL).  The DECL
!    originally was in the FROM_FN, but now it will be in the
!    TO_FN.  */
  
  tree
--- 106,111 ----
  }
  
! /* Copy NODE (which must be a DECL).  The DECL originally was in the FROM_FN,
!    but now it will be in the TO_FN.  */
  
  tree
*************** copy_decl_for_inlining (tree decl, tree 
*** 133,137 ****
  	type = TREE_TYPE (decl);
  
!       /* For a parameter, we must make an equivalent VAR_DECL, not a
  	 new PARM_DECL.  */
        copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
--- 132,136 ----
  	type = TREE_TYPE (decl);
  
!       /* For a parameter or result, we must make an equivalent VAR_DECL, not a
  	 new PARM_DECL.  */
        copy = build_decl (VAR_DECL, DECL_NAME (decl), type);
*** langhooks-def.h	5 Jul 2004 14:22:28 -0000	1.81
--- langhooks-def.h	6 Jul 2004 01:14:22 -0000
*************** extern int lhd_gimplify_expr (tree *, tr
*** 158,162 ****
    lhd_tree_inlining_anon_aggr_type_p
  #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P \
!   hook_bool_tree_false
  #define LANG_HOOKS_TREE_INLINING_START_INLINING \
    lhd_tree_inlining_start_inlining
--- 158,162 ----
    lhd_tree_inlining_anon_aggr_type_p
  #define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P \
!   hook_bool_tree_tree_false
  #define LANG_HOOKS_TREE_INLINING_START_INLINING \
    lhd_tree_inlining_start_inlining
*** langhooks.h	5 Jul 2004 14:22:28 -0000	1.87
--- langhooks.h	6 Jul 2004 01:14:24 -0000
*************** struct lang_hooks_for_tree_inlining
*** 44,48 ****
  				      void *, int *, tree);
    int (*anon_aggr_type_p) (tree);
!   bool (*var_mod_type_p) (tree);
    int (*start_inlining) (tree);
    void (*end_inlining) (tree);
--- 44,48 ----
  				      void *, int *, tree);
    int (*anon_aggr_type_p) (tree);
!   bool (*var_mod_type_p) (tree, tree);
    int (*start_inlining) (tree);
    void (*end_inlining) (tree);
*** tree-inline.c	5 Jul 2004 16:39:15 -0000	1.121
--- tree-inline.c	6 Jul 2004 01:14:26 -0000
*************** insert_decl_map (inline_data *id, tree k
*** 156,188 ****
  }
  
! /* Remap DECL during the copying of the BLOCK tree for the function.  */
  
  static tree
  remap_decl (tree decl, inline_data *id)
  {
!   splay_tree_node n;
!   tree fn;
! 
!   /* We only remap local variables in the current function.  */
!   fn = VARRAY_TOP_TREE (id->fns);
! #if 0
!   /* We need to remap statics, too, so that they get expanded even if the
!      inline function is never emitted out of line.  We might as well also
!      remap extern decls so that they show up in the debug info.  */
!   if (! lang_hooks.tree_inlining.auto_var_in_fn_p (decl, fn))
!     return NULL_TREE;
! #endif
! 
!   /* See if we have remapped this declaration.  */
!   n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
  
!   /* If we didn't already have an equivalent for this declaration,
!      create one now.  */
    if (!n)
      {
-       tree t;
- 
        /* Make a copy of the variable or label.  */
!       t = copy_decl_for_inlining (decl, fn, VARRAY_TREE (id->fns, 0));
  
        /* Remap types, if necessary.  */
--- 156,174 ----
  }
  
! /* Remap DECL during the copying of the BLOCK tree for the function. 
!    We are only called to remap local variables in the current function.  */
  
  static tree
  remap_decl (tree decl, inline_data *id)
  {
!   splay_tree_node n = splay_tree_lookup (id->decl_map, (splay_tree_key) decl);
!   tree fn = VARRAY_TOP_TREE (id->fns);
  
!   /* See if we have remapped this declaration.  If we didn't already have an
!      equivalent for this declaration, create one now.  */
    if (!n)
      {
        /* Make a copy of the variable or label.  */
!       tree t = copy_decl_for_inlining (decl, fn, VARRAY_TREE (id->fns, 0));
  
        /* Remap types, if necessary.  */
*************** remap_decl (tree decl, inline_data *id)
*** 198,201 ****
--- 184,195 ----
        walk_tree (&DECL_SIZE_UNIT (t), copy_body_r, id, NULL);
  
+       /* If fields, do likewise for offset and qualifier. */
+       if (TREE_CODE (t) == FIELD_DECL)
+ 	{
+ 	  walk_tree (&DECL_FIELD_OFFSET (t), copy_body_r, id, NULL);
+ 	  if (TREE_CODE (DECL_CONTEXT (t)) == QUAL_UNION_TYPE)
+ 	    walk_tree (&DECL_QUALIFIER (t), copy_body_r, id, NULL);
+ 	}
+ 
  #if 0
        /* FIXME handle anon aggrs.  */
*************** remap_type (tree type, inline_data *id)
*** 244,249 ****
      return (tree) node->value;
  
!   /* The type only needs remapping if it's variably modified.  */
!   if (! variably_modified_type_p (type))
      {
        insert_decl_map (id, type, type);
--- 238,244 ----
      return (tree) node->value;
  
!   /* The type only needs remapping if it's variably modified by a variable
!      in the function we are inlining.  */
!   if (! variably_modified_type_p (type, VARRAY_TOP_TREE (id->fns)))
      {
        insert_decl_map (id, type, type);
*************** static tree
*** 459,468 ****
  copy_body_r (tree *tp, int *walk_subtrees, void *data)
  {
!   inline_data* id;
!   tree fn;
! 
!   /* Set up.  */
!   id = (inline_data *) data;
!   fn = VARRAY_TOP_TREE (id->fns);
  
  #if 0
--- 454,459 ----
  copy_body_r (tree *tp, int *walk_subtrees, void *data)
  {
!   inline_data *id = (inline_data *) data;
!   tree fn = VARRAY_TOP_TREE (id->fns);
  
  #if 0
*************** copy_body_r (tree *tp, int *walk_subtree
*** 508,512 ****
       variables.  We don't want to copy static variables; there's only
       one of those, no matter how many times we inline the containing
!      function.  */
    else if (lang_hooks.tree_inlining.auto_var_in_fn_p (*tp, fn))
      {
--- 499,503 ----
       variables.  We don't want to copy static variables; there's only
       one of those, no matter how many times we inline the containing
!      function.  Similarly for globals from an outer function.  */
    else if (lang_hooks.tree_inlining.auto_var_in_fn_p (*tp, fn))
      {
*************** copy_body_r (tree *tp, int *walk_subtree
*** 604,614 ****
  	      if (TREE_CODE (value) == INDIRECT_REF)
  		{
! 		  /* Assume that the argument types properly match the
! 		     parameter types.  We can't compare them well enough
! 		     without a comptypes langhook, and we don't want to
! 		     call convert and introduce a NOP_EXPR to convert
! 		     between two equivalent types (i.e. that only differ
! 		     in use of typedef names).  */
! 		  *tp = TREE_OPERAND (value, 0);
  		  return copy_body_r (tp, walk_subtrees, data);
  		}
--- 595,605 ----
  	      if (TREE_CODE (value) == INDIRECT_REF)
  		{
! 		  if  (!lang_hooks.types_compatible_p
! 		       (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0))))
! 		    *tp = fold_convert (TREE_TYPE (*tp),
! 					TREE_OPERAND (value, 0));
! 		  else
! 		    *tp = TREE_OPERAND (value, 0);
! 
  		  return copy_body_r (tp, walk_subtrees, data);
  		}
*************** copy_body_r (tree *tp, int *walk_subtree
*** 627,631 ****
  	      value = (tree) n->value;
  	      STRIP_NOPS (value);
! 	      if (TREE_CODE (value) == ADDR_EXPR)
  		{
  		  *tp = TREE_OPERAND (value, 0);
--- 618,624 ----
  	      value = (tree) n->value;
  	      STRIP_NOPS (value);
! 	      if (TREE_CODE (value) == ADDR_EXPR
! 		  && (lang_hooks.types_compatible_p
! 		      (TREE_TYPE (*tp), TREE_TYPE (TREE_OPERAND (value, 0)))))
  		{
  		  *tp = TREE_OPERAND (value, 0);
*************** setup_one_parameter (inline_data *id, tr
*** 740,746 ****
      }
  
!   /* Make an equivalent VAR_DECL with the remapped type.  */
    var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
-   TREE_TYPE (var) = remap_type (TREE_TYPE (var), id);
  
    /* See if the frontend wants to pass this by invisible reference.  If
--- 733,740 ----
      }
  
!   /* Make an equivalent VAR_DECL.  Note that we must NOT remap the type
!      here since the type of this decl must be visible to the calling
!      function. */
    var = copy_decl_for_inlining (p, fn, VARRAY_TREE (id->fns, 0));
  
    /* See if the frontend wants to pass this by invisible reference.  If
*************** inline_forbidden_p_1 (tree *nodep, int *
*** 1073,1077 ****
  	 F is inlined, and we abort in find_function_data.  */
        for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
! 	if (variably_modified_type_p (TREE_TYPE (t)))
  	  {
  	    inline_forbidden_reason
--- 1067,1071 ----
  	 F is inlined, and we abort in find_function_data.  */
        for (t = TYPE_FIELDS (node); t; t = TREE_CHAIN (t))
! 	if (variably_modified_type_p (TREE_TYPE (t), NULL))
  	  {
  	    inline_forbidden_reason
*** tree.c	5 Jul 2004 17:28:33 -0000	1.388
--- tree.c	6 Jul 2004 01:14:29 -0000
*************** do { tree _node = (NODE); \
*** 2353,2366 ****
  	      
    /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
!      it.  If it's a decl, it's definitely invariant and it's constant if the
!      decl is static.  (Taking the address of a volatile variable is not
!      volatile.)  If it's a constant, the address is both invariant and
!      constant.  Otherwise it's neither.  */
    if (TREE_CODE (node) == INDIRECT_REF)
      UPDATE_TITCSE (node);
    else if (DECL_P (node))
      {
!       if (!staticp (node))
  	tc = false;
      }
    else if (TREE_CODE_CLASS (TREE_CODE (node)) == 'c')
--- 2353,2370 ----
  	      
    /* Now see what's inside.  If it's an INDIRECT_REF, copy our properties from
!      it.  If it's a decl, it's invariant and constant if the decl is static.
!      It's also invariant if it's a decl in the current function.  (Taking the
!      address of a volatile variable is not volatile.)  If it's a constant,
!      the address is both invariant and constant.  Otherwise it's neither.  */
    if (TREE_CODE (node) == INDIRECT_REF)
      UPDATE_TITCSE (node);
    else if (DECL_P (node))
      {
!       if (staticp (node))
! 	;
!       else if (decl_function_context (node) == current_function_decl)
  	tc = false;
+       else
+ 	ti = tc = false;
      }
    else if (TREE_CODE_CLASS (TREE_CODE (node)) == 'c')
*************** int_fits_type_p (tree c, tree type)
*** 4686,4694 ****
  }
  
  /* Returns true if T is, contains, or refers to a type with variable
!    size.  This concept is more general than that of C99 'variably
!    modified types': in C99, a struct type is never variably modified
!    because a VLA may not appear as a structure member.  However, in
!    GNU C code like:
  
       struct S { int i[f()]; };
--- 4690,4719 ----
  }
  
+ /* Subprogram of following function.  Called by walk_tree.
+ 
+    Return *TP if it is an automatic variable or parameter of the
+    function passed in as DATA.  */
+ 
+ static tree
+ find_var_from_fn (tree *tp, int *walk_subtrees, void *data)
+ {
+   tree fn = (tree) data;
+ 
+   if (TYPE_P (*tp))
+     *walk_subtrees = 0;
+ 
+   else if (DECL_P (*tp) && lang_hooks.tree_inlining.auto_var_in_fn_p (*tp, fn))
+     return *tp;
+ 
+   return NULL_TREE;
+ }
+ 
  /* Returns true if T is, contains, or refers to a type with variable
!    size.  If FN is nonzero, only return true if a modifier of the type
!    or position of FN is a variable or parameter inside FN.
! 
!    This concept is more general than that of C99 'variably modified types':
!    in C99, a struct type is never variably modified because a VLA may not
!    appear as a structure member.  However, in GNU C code like:
  
       struct S { int i[f()]; };
*************** int_fits_type_p (tree c, tree type)
*** 4697,4704 ****
  
  bool
! variably_modified_type_p (tree type)
  {
    tree t;
  
    if (type == error_mark_node)
      return false;
--- 4722,4737 ----
  
  bool
! variably_modified_type_p (tree type, tree fn)
  {
    tree t;
  
+ /* Test if T is either variable (if FN is zero) or an expression containing
+    a variable in FN.  */
+ #define RETURN_TRUE_IF_VAR(T)						\
+   do { tree _t = (T);							\
+     if (_t && _t != error_mark_node && TREE_CODE (_t) != INTEGER_CST	\
+         && (!fn || walk_tree (&_t, find_var_from_fn, fn, NULL)))	\
+       return true;  } while (0)
+ 
    if (type == error_mark_node)
      return false;
*************** variably_modified_type_p (tree type)
*** 4709,4715 ****
       When a representation is chosen, this function should be modified
       to test for that case as well.  */
!   t = TYPE_SIZE (type);
!   if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
!     return true;
  
    switch (TREE_CODE (type))
--- 4742,4747 ----
       When a representation is chosen, this function should be modified
       to test for that case as well.  */
!   RETURN_TRUE_IF_VAR (TYPE_SIZE (type));
!   RETURN_TRUE_IF_VAR (TYPE_SIZE_UNIT(type));
  
    switch (TREE_CODE (type))
*************** variably_modified_type_p (tree type)
*** 4720,4724 ****
      case SET_TYPE:
      case VECTOR_TYPE:
!       if (variably_modified_type_p (TREE_TYPE (type)))
  	return true;
        break;
--- 4752,4756 ----
      case SET_TYPE:
      case VECTOR_TYPE:
!       if (variably_modified_type_p (TREE_TYPE (type), fn))
  	return true;
        break;
*************** variably_modified_type_p (tree type)
*** 4728,4732 ****
        /* If TYPE is a function type, it is variably modified if any of the
           parameters or the return type are variably modified.  */
!       if (variably_modified_type_p (TREE_TYPE (type)))
  	  return true;
  
--- 4760,4764 ----
        /* If TYPE is a function type, it is variably modified if any of the
           parameters or the return type are variably modified.  */
!       if (variably_modified_type_p (TREE_TYPE (type), fn))
  	  return true;
  
*************** variably_modified_type_p (tree type)
*** 4734,4738 ****
  	   t && t != void_list_node;
  	   t = TREE_CHAIN (t))
! 	if (variably_modified_type_p (TREE_VALUE (t)))
  	  return true;
        break;
--- 4766,4770 ----
  	   t && t != void_list_node;
  	   t = TREE_CHAIN (t))
! 	if (variably_modified_type_p (TREE_VALUE (t), fn))
  	  return true;
        break;
*************** variably_modified_type_p (tree type)
*** 4745,4755 ****
        /* Scalar types are variably modified if their end points
  	 aren't constant.  */
!       t = TYPE_MIN_VALUE (type);
!       if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
! 	return true;
! 
!       t = TYPE_MAX_VALUE (type);
!       if (t && t != error_mark_node && TREE_CODE (t) != INTEGER_CST)
! 	return true;
        break;
  
--- 4777,4782 ----
        /* Scalar types are variably modified if their end points
  	 aren't constant.  */
!       RETURN_TRUE_IF_VAR (TYPE_MIN_VALUE (type));
!       RETURN_TRUE_IF_VAR (TYPE_MAX_VALUE (type));
        break;
  
*************** variably_modified_type_p (tree type)
*** 4764,4775 ****
  	if (TREE_CODE (t) == FIELD_DECL)
  	  {
! 	    tree t1 = DECL_FIELD_OFFSET (t);
  
! 	    if (t1 && t1 != error_mark_node && TREE_CODE (t1) != INTEGER_CST)
! 	      return true;
! 
! 	    t1 = DECL_SIZE (t);
! 	    if (t1 && t1 != error_mark_node && TREE_CODE (t1) != INTEGER_CST)
! 	      return true;
  	  }
  	break;
--- 4791,4800 ----
  	if (TREE_CODE (t) == FIELD_DECL)
  	  {
! 	    RETURN_TRUE_IF_VAR (DECL_FIELD_OFFSET (t));
! 	    RETURN_TRUE_IF_VAR (DECL_SIZE (t));
! 	    RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t));
  
! 	    if (TREE_CODE (type) == QUAL_UNION_TYPE)
! 	      RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t));
  	  }
  	break;
*************** variably_modified_type_p (tree type)
*** 4781,4785 ****
    /* The current language may have other cases to check, but in general,
       all other types are not variably modified.  */
!   return lang_hooks.tree_inlining.var_mod_type_p (type);
  }
  
--- 4806,4812 ----
    /* The current language may have other cases to check, but in general,
       all other types are not variably modified.  */
!   return lang_hooks.tree_inlining.var_mod_type_p (type, fn);
! 
! #undef RETURN_TRUE_IF_VAR
  }
  
*** tree.h	5 Jul 2004 16:39:14 -0000	1.541
--- tree.h	6 Jul 2004 01:14:35 -0000
*************** extern int objects_must_conflict_p (tree
*** 3470,3474 ****
  extern int really_constant_p (tree);
  extern int int_fits_type_p (tree, tree);
! extern bool variably_modified_type_p (tree);
  extern int tree_log2 (tree);
  extern int tree_floor_log2 (tree);
--- 3470,3474 ----
  extern int really_constant_p (tree);
  extern int int_fits_type_p (tree, tree);
! extern bool variably_modified_type_p (tree, tree);
  extern int tree_log2 (tree);
  extern int tree_floor_log2 (tree);
*** cp/cp-lang.c	26 Jun 2004 21:11:21 -0000	1.83
--- cp/cp-lang.c	6 Jul 2004 01:15:02 -0000
*************** static bool cxx_warn_unused_global_decl 
*** 39,43 ****
  static tree cp_expr_size (tree);
  static size_t cp_tree_size (enum tree_code);
! static bool cp_var_mod_type_p (tree);
  static int cxx_types_compatible_p (tree, tree);
  static void cxx_initialize_diagnostics (diagnostic_context *);
--- 39,43 ----
  static tree cp_expr_size (tree);
  static size_t cp_tree_size (enum tree_code);
! static bool cp_var_mod_type_p (tree, tree);
  static int cxx_types_compatible_p (tree, tree);
  static void cxx_initialize_diagnostics (diagnostic_context *);
*************** cp_tree_size (enum tree_code code)
*** 308,322 ****
  
  /* Returns true if T is a variably modified type, in the sense of C99.
     This routine needs only check cases that cannot be handled by the
!    language-independent logic in tree-inline.c.  */
  
  static bool
! cp_var_mod_type_p (tree type)
  {
    /* If TYPE is a pointer-to-member, it is variably modified if either
       the class or the member are variably modified.  */
    if (TYPE_PTR_TO_MEMBER_P (type))
!     return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
! 	    || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type)));
  
    /* All other types are not variably modified.  */
--- 308,324 ----
  
  /* Returns true if T is a variably modified type, in the sense of C99.
+    FN is as passed to variably_modified_p.
     This routine needs only check cases that cannot be handled by the
!    language-independent logic in tree.c.  */
  
  static bool
! cp_var_mod_type_p (tree type, tree fn)
  {
    /* If TYPE is a pointer-to-member, it is variably modified if either
       the class or the member are variably modified.  */
    if (TYPE_PTR_TO_MEMBER_P (type))
!     return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type), fn)
! 	    || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type),
! 					 fn));
  
    /* All other types are not variably modified.  */
*** cp/decl.c	5 Jul 2004 17:28:36 -0000	1.1234
--- cp/decl.c	6 Jul 2004 01:15:08 -0000
*************** grokdeclarator (const cp_declarator *dec
*** 7330,7334 ****
    if ((decl_context == FIELD || decl_context == PARM)
        && !processing_template_decl 
!       && variably_modified_type_p (type))
      {
        if (decl_context == FIELD)
--- 7330,7334 ----
    if ((decl_context == FIELD || decl_context == PARM)
        && !processing_template_decl 
!       && variably_modified_type_p (type, NULL_TREE))
      {
        if (decl_context == FIELD)
*** cp/pt.c	5 Jul 2004 09:35:39 -0000	1.879
--- cp/pt.c	6 Jul 2004 01:15:14 -0000
*************** check_instantiated_args (tree tmpl, tree
*** 8558,8562 ****
  	  /* In order to avoid all sorts of complications, we do not
  	     allow variably-modified types as template arguments.  */
! 	  else if (variably_modified_type_p (t))
  	    {
  	      if (complain & tf_error)
--- 8558,8562 ----
  	  /* In order to avoid all sorts of complications, we do not
  	     allow variably-modified types as template arguments.  */
! 	  else if (variably_modified_type_p (t, NULL_TREE))
  	    {
  	      if (complain & tf_error)
*************** unify (tree tparms, tree targs, tree par
*** 9733,9737 ****
  	     instantiation.  Besides, such types are not allowed in
  	     ISO C++, so we can do as we please here.  */
! 	  if (variably_modified_type_p (arg))
  	    return 1;
  	}
--- 9733,9737 ----
  	     instantiation.  Besides, such types are not allowed in
  	     ISO C++, so we can do as we please here.  */
! 	  if (variably_modified_type_p (arg, NULL_TREE))
  	    return 1;
  	}




More information about the Gcc-patches mailing list