This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Move variably_modified_type_p to tree-inline.c
On Tue, Oct 22, 2002 at 05:48:34PM -0700, Mark Mitchell wrote:
>
>
> --On Tuesday, October 22, 2002 03:51:16 PM -0700 Zack Weinberg
> <zack@codesourcery.com> wrote:
>
> >This is phase one of a fix for PR 6994.
>
> Cool. This patch is OK. While you're there, would you fix my typo:
>
> + elements are. (Note that the VLA case has alredy been checked
>
> That's "already".
>
> This good go in c-common.c; the notion of "variably modified type" is
> C99-ism. But then we have to increase the horrible damage that was
> done to tree-inline.c. So, I think you should just put it in tree.c;
> it's really a property of types; nothing specific to do with inlining.
>
> You can certainly move it there without re-bootstrapping.
Okay. Here is the patch I just applied.
zw
* langhooks.h (struct lang_hooks_for_tree_inlining): Add
var_mod_type_p.
* langhooks-def.h: Default for tree_inlining.var_mod_type_p is
hook_tree_bool_false.
* tree.c (variably_modified_type_p): Moved here from
cp/tree.c. Use lang_hooks.tree_inlining.var_mod_type_p for
language-specific cases. Due to this, must weaken some 'if
and only if' checks to merely 'if'.
* tree.h: Prototype variably_modified_type_p.
* tree-inline.c (walk_tree): #undef WALK_SUBTREE_TAIL at end.
cp:
* cp-lang.c (cp_var_mod_type_p): New: C++ hook for
variably_modified_type_p.
* cp-tree.h: Remove prototype of variably_modified_type_p.
* tree.c (variably_modified_type_p): Remove; now implemented
in language-independent code.
===================================================================
Index: langhooks-def.h
--- langhooks-def.h 22 Aug 2002 00:42:40 -0000 1.37
+++ langhooks-def.h 23 Oct 2002 17:00:48 -0000
@@ -140,6 +140,8 @@ tree lhd_tree_inlining_convert_parm_for_
lhd_tree_inlining_copy_res_decl_for_inlining
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P \
lhd_tree_inlining_anon_aggr_type_p
+#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P \
+ hook_tree_bool_false
#define LANG_HOOKS_TREE_INLINING_START_INLINING \
lhd_tree_inlining_start_inlining
#define LANG_HOOKS_TREE_INLINING_END_INLINING \
@@ -156,6 +158,7 @@ tree lhd_tree_inlining_convert_parm_for_
LANG_HOOKS_TREE_INLINING_AUTO_VAR_IN_FN_P, \
LANG_HOOKS_TREE_INLINING_COPY_RES_DECL_FOR_INLINING, \
LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P, \
+ LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P, \
LANG_HOOKS_TREE_INLINING_START_INLINING, \
LANG_HOOKS_TREE_INLINING_END_INLINING, \
LANG_HOOKS_TREE_INLINING_CONVERT_PARM_FOR_INLINING \
===================================================================
Index: langhooks.h
--- langhooks.h 22 Sep 2002 14:09:34 -0000 1.47
+++ langhooks.h 23 Oct 2002 17:00:49 -0000
@@ -50,6 +50,7 @@ struct lang_hooks_for_tree_inlining
void *, int *,
void *));
int (*anon_aggr_type_p) PARAMS ((union tree_node *));
+ bool (*var_mod_type_p) PARAMS ((union tree_node *));
int (*start_inlining) PARAMS ((union tree_node *));
void (*end_inlining) PARAMS ((union tree_node *));
union tree_node *(*convert_parm_for_inlining) PARAMS ((union tree_node *,
===================================================================
Index: tree-inline.c
--- tree-inline.c 14 Oct 2002 18:12:11 -0000 1.32
+++ tree-inline.c 23 Oct 2002 17:00:49 -0000
@@ -1647,6 +1647,7 @@ walk_tree (tp, func, data, htab_)
return NULL_TREE;
#undef WALK_SUBTREE
+#undef WALK_SUBTREE_TAIL
}
/* Like walk_tree, but does not walk duplicate nodes more than
===================================================================
Index: tree.c
--- tree.c 14 Oct 2002 10:36:41 -0000 1.277
+++ tree.c 23 Oct 2002 17:00:50 -0000
@@ -4151,6 +4151,65 @@ int_fits_type_p (c, type)
}
}
+/* 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()]; };
+
+ is valid, and other languages may define similar constructs. */
+
+bool
+variably_modified_type_p (type)
+ tree type;
+{
+ /* If TYPE itself has variable size, it is variably modified.
+
+ We do not yet have a representation of the C99 '[*]' syntax.
+ When a representation is chosen, this function should be modified
+ to test for that case as well. */
+ if (TYPE_SIZE (type)
+ && TYPE_SIZE (type) != error_mark_node
+ && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
+ return true;
+
+ /* If TYPE is a pointer or reference, it is variably modified if
+ the type pointed to is variably modified. */
+ if ((TREE_CODE (type) == POINTER_TYPE
+ || TREE_CODE (type) == REFERENCE_TYPE)
+ && variably_modified_type_p (TREE_TYPE (type)))
+ return true;
+
+ /* If TYPE is an array, it is variably modified if the array
+ elements are. (Note that the VLA case has already been checked
+ above.) */
+ if (TREE_CODE (type) == ARRAY_TYPE
+ && variably_modified_type_p (TREE_TYPE (type)))
+ return true;
+
+ /* If TYPE is a function type, it is variably modified if any of the
+ parameters or the return type are variably modified. */
+ if (TREE_CODE (type) == FUNCTION_TYPE
+ || TREE_CODE (type) == METHOD_TYPE)
+ {
+ tree parm;
+
+ if (variably_modified_type_p (TREE_TYPE (type)))
+ return true;
+ for (parm = TYPE_ARG_TYPES (type);
+ parm && parm != void_list_node;
+ parm = TREE_CHAIN (parm))
+ if (variably_modified_type_p (TREE_VALUE (parm)))
+ return true;
+ }
+
+ /* 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);
+}
+
/* Given a DECL or TYPE, return the scope in which it was declared, or
NULL_TREE if there is no containing scope. */
===================================================================
Index: tree.h
--- tree.h 14 Oct 2002 10:36:41 -0000 1.359
+++ tree.h 23 Oct 2002 17:00:51 -0000
@@ -2909,6 +2909,7 @@ struct obstack;
/* In tree.c */
extern int really_constant_p PARAMS ((tree));
extern int int_fits_type_p PARAMS ((tree, tree));
+extern bool variably_modified_type_p PARAMS ((tree));
extern int tree_log2 PARAMS ((tree));
extern int tree_floor_log2 PARAMS ((tree));
extern int simple_cst_equal PARAMS ((tree, tree));
===================================================================
Index: cp/cp-lang.c
--- cp/cp-lang.c 13 Sep 2002 00:22:58 -0000 1.41
+++ cp/cp-lang.c 23 Oct 2002 17:01:12 -0000
@@ -32,6 +32,7 @@ static HOST_WIDE_INT cxx_get_alias_set P
static bool ok_to_generate_alias_set_for_type PARAMS ((tree));
static bool cxx_warn_unused_global_decl PARAMS ((tree));
static tree cp_expr_size PARAMS ((tree));
+static bool cp_var_mod_type_p PARAMS ((tree));
#undef LANG_HOOKS_NAME
#define LANG_HOOKS_NAME "GNU C++"
@@ -126,6 +127,8 @@ static tree cp_expr_size PARAMS ((tree))
cp_convert_parm_for_inlining
#undef LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P
#define LANG_HOOKS_TREE_INLINING_ANON_AGGR_TYPE_P anon_aggr_type_p
+#undef LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P
+#define LANG_HOOKS_TREE_INLINING_VAR_MOD_TYPE_P cp_var_mod_type_p
#undef LANG_HOOKS_TREE_INLINING_START_INLINING
#define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining
#undef LANG_HOOKS_TREE_INLINING_END_INLINING
@@ -310,3 +313,21 @@ cp_expr_size (exp)
/* Use the default code. */
return lhd_expr_size (exp);
}
+
+/* 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_PTRMEM_P (type) || TYPE_PTRMEMFUNC_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. */
+ return false;
+}
+
===================================================================
Index: cp/cp-tree.h
--- cp/cp-tree.h 21 Oct 2002 08:40:24 -0000 1.761
+++ cp/cp-tree.h 23 Oct 2002 17:01:14 -0000
@@ -4191,7 +4191,6 @@ extern tree cxx_unsave_expr_now PARAMS
extern tree cxx_maybe_build_cleanup PARAMS ((tree));
extern void init_tree PARAMS ((void));
extern int pod_type_p PARAMS ((tree));
-extern bool variably_modified_type_p (tree);
extern int zero_init_p PARAMS ((tree));
extern tree canonical_type_variant PARAMS ((tree));
extern void unshare_base_binfos PARAMS ((tree));
===================================================================
Index: cp/tree.c
--- cp/tree.c 11 Oct 2002 19:55:21 -0000 1.304
+++ cp/tree.c 23 Oct 2002 17:01:14 -0000
@@ -1958,72 +1958,6 @@ pod_type_p (t)
return 1;
}
-/* Returns true if T is a variably modified type, in the sense of
- C99.
-
- 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()]; };
-
- is valid. Even though GNU C++ does not allow that, this function
- may sometimes be used in the C front end, so it treats any type
- with variable size in the same way that C99 treats VLAs.
-
- In particular, a variably modified type is one that involves a type
- with variable size. */
-
-bool
-variably_modified_type_p (tree type)
-{
- /* If TYPE itself has variable size, it is variably modified.
-
- We do not yet have a representation of the C99 '[*]' syntax.
- When a representation is chosen, this function should be modified
- to test for that case as well. */
- if (TYPE_SIZE (type)
- && TYPE_SIZE (type) != error_mark_node
- && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
- return true;
-
- /* If TYPE is a pointer or reference, it is variably modified if and
- only if the type pointed to is variably modified. */
- if (TYPE_PTR_P (type)
- || TREE_CODE (type) == REFERENCE_TYPE)
- return variably_modified_type_p (TREE_TYPE (type));
-
- /* If TYPE is an array, it is variably modified if the array
- elements are. (Note that the VLA case has alredy been checked
- above). */
- if (TREE_CODE (type) == ARRAY_TYPE)
- return variably_modified_type_p (TREE_TYPE (type));
-
- /* If TYPE is a pointer-to-member, it is variably modified if either
- the class or the member are variably modified. */
- if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type))
- return (variably_modified_type_p (TYPE_PTRMEM_CLASS_TYPE (type))
- || variably_modified_type_p (TYPE_PTRMEM_POINTED_TO_TYPE (type)));
-
- /* If TYPE Is a function type, it is variably modified if any of the
- parameters or the return type are variably modified. */
- if (TREE_CODE (type) == FUNCTION_TYPE
- || TREE_CODE (type) == METHOD_TYPE)
- {
- tree parm;
-
- if (variably_modified_type_p (TREE_TYPE (type)))
- return true;
- for (parm = TYPE_ARG_TYPES (type);
- parm && parm != void_list_node;
- parm = TREE_CHAIN (parm))
- if (variably_modified_type_p (TREE_VALUE (parm)))
- return true;
- }
-
- /* All other types are not variably modified. */
- return false;
-}
-
/* Returns 1 iff zero initialization of type T means actually storing
zeros in it. */