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