cp-tree.h (CPTI_CLEANUP_TYPE): New macro.
* cp-tree.h (CPTI_CLEANUP_TYPE): New macro. (cleanup_type): Likewise. (search_tree): Change prototype. * decl.c (local_variable_p): Adjust for new interface to search_tree. (check_default_argument): Likewise. * error.c (dump_expr): Handle INIT_EXPR. * except.c (expand_throw): Don't make cleanup_type a local static. * expr.c (cplus_expand_expr): Don't handle NEW_EXPR. * init.c (build_new): Call build_new_1 directly, rather than building a NEW_EXPR. (build_new_1): Tidy. Don't build a VEC_INIT_EXPR except when processing file-scope initializers. * lex.c (init_parse): Add an opname_tab entry for INIT_EXPR. * tree.c: Include splay-tree.h (no_linkage_helper): Adjust for new interface to search_tree. (search_tree): Pass around pointers to tree nodes, rather than the nodes themselves. Handle VEC_INIT_EXPR. (no_linkage_check): Adjust for new interface to search_tree. (mapcar): Handle VEC_INIT_EXPR. (target_remap): New variable. (bot_manip): Use it. (bot_replace): New function. (break_out_target_exprs): Use it to remap all variables used in a default argument expression. * typeck.c (build_modify_expr): Don't crash when outside a function and presented with an INIT_EXPR assignment * Makefile.in (tree.o): Depend on splay-tree.h. From-SVN: r29659
This commit is contained in:
parent
d353a00cf3
commit
b3ab27f3c3
@ -1,3 +1,34 @@
|
||||
1999-09-24 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* cp-tree.h (CPTI_CLEANUP_TYPE): New macro.
|
||||
(cleanup_type): Likewise.
|
||||
(search_tree): Change prototype.
|
||||
* decl.c (local_variable_p): Adjust for new interface to
|
||||
search_tree.
|
||||
(check_default_argument): Likewise.
|
||||
* error.c (dump_expr): Handle INIT_EXPR.
|
||||
* except.c (expand_throw): Don't make cleanup_type a local static.
|
||||
* expr.c (cplus_expand_expr): Don't handle NEW_EXPR.
|
||||
* init.c (build_new): Call build_new_1 directly, rather than
|
||||
building a NEW_EXPR.
|
||||
(build_new_1): Tidy. Don't build a VEC_INIT_EXPR except when
|
||||
processing file-scope initializers.
|
||||
* lex.c (init_parse): Add an opname_tab entry for INIT_EXPR.
|
||||
* tree.c: Include splay-tree.h
|
||||
(no_linkage_helper): Adjust for new interface to search_tree.
|
||||
(search_tree): Pass around pointers to tree nodes, rather than the
|
||||
nodes themselves. Handle VEC_INIT_EXPR.
|
||||
(no_linkage_check): Adjust for new interface to search_tree.
|
||||
(mapcar): Handle VEC_INIT_EXPR.
|
||||
(target_remap): New variable.
|
||||
(bot_manip): Use it.
|
||||
(bot_replace): New function.
|
||||
(break_out_target_exprs): Use it to remap all variables used in a
|
||||
default argument expression.
|
||||
* typeck.c (build_modify_expr): Don't crash when outside a
|
||||
function and presented with an INIT_EXPR assignment
|
||||
* Makefile.in (tree.o): Depend on splay-tree.h.
|
||||
|
||||
Fri Sep 24 10:48:10 1999 Bernd Schmidt <bernds@cygnus.co.uk>
|
||||
|
||||
* decl.c (duplicate_decls): Use DECL_BUILT_IN_CLASS rather than
|
||||
|
@ -274,7 +274,8 @@ cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \
|
||||
search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \
|
||||
$(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h $(RTL_H)
|
||||
tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H)
|
||||
$(srcdir)/../system.h $(srcdir)/../toplev.h $(srcdir)/../ggc.h $(RTL_H) \
|
||||
$(srcdir)/../../include/splay-tree.h
|
||||
ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h
|
||||
rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \
|
||||
$(srcdir)/../system.h $(srcdir)/../toplev.h
|
||||
|
@ -408,6 +408,7 @@ enum cp_tree_index
|
||||
CPTI_WCHAR_DECL,
|
||||
CPTI_VTABLE_ENTRY_TYPE,
|
||||
CPTI_DELTA_TYPE,
|
||||
CPTI_CLEANUP_TYPE,
|
||||
|
||||
CPTI_TP_DESC_TYPE,
|
||||
CPTI_ACCESS_MODE_TYPE,
|
||||
@ -560,6 +561,9 @@ extern tree cp_global_trees[CPTI_MAX];
|
||||
/* The declaration for `std::atexit'. */
|
||||
#define atexit_node cp_global_trees[CPTI_ATEXIT]
|
||||
|
||||
/* The type of a destructor. */
|
||||
#define cleanup_type cp_global_trees[CPTI_CLEANUP_TYPE]
|
||||
|
||||
/* Global state. */
|
||||
|
||||
struct saved_scope {
|
||||
@ -3855,7 +3859,7 @@ extern void push_permanent_obstack PROTO((void));
|
||||
extern tree build_dummy_object PROTO((tree));
|
||||
extern tree maybe_dummy_object PROTO((tree, tree *));
|
||||
extern int is_dummy_object PROTO((tree));
|
||||
extern tree search_tree PROTO((tree, tree (*)(tree)));
|
||||
extern tree search_tree PROTO((tree *, tree (*)(tree *)));
|
||||
extern int cp_valid_lang_attribute PROTO((tree, tree, tree, tree));
|
||||
extern tree make_ptrmem_cst PROTO((tree, tree));
|
||||
extern tree cp_build_qualified_type_real PROTO((tree, int, int));
|
||||
|
@ -149,7 +149,7 @@ static boolean typename_compare PROTO((hash_table_key, hash_table_key));
|
||||
static void push_binding PROTO((tree, tree, struct binding_level*));
|
||||
static int add_binding PROTO((tree, tree));
|
||||
static void pop_binding PROTO((tree, tree));
|
||||
static tree local_variable_p PROTO((tree));
|
||||
static tree local_variable_p PROTO((tree *));
|
||||
static tree find_binding PROTO((tree, tree));
|
||||
static tree select_decl PROTO((tree, int));
|
||||
static int lookup_flags PROTO((int, int));
|
||||
@ -11188,13 +11188,15 @@ require_complete_types_for_parms (parms)
|
||||
}
|
||||
}
|
||||
|
||||
/* Returns DECL if DECL is a local variable (or parameter). Returns
|
||||
/* Returns *TP if *TP is a local variable (or parameter). Returns
|
||||
NULL_TREE otherwise. */
|
||||
|
||||
static tree
|
||||
local_variable_p (t)
|
||||
tree t;
|
||||
local_variable_p (tp)
|
||||
tree *tp;
|
||||
{
|
||||
tree t = *tp;
|
||||
|
||||
if ((TREE_CODE (t) == VAR_DECL
|
||||
/* A VAR_DECL with a context that is a _TYPE is a static data
|
||||
member. */
|
||||
@ -11273,7 +11275,7 @@ check_default_argument (decl, arg)
|
||||
|
||||
The keyword `this' shall not be used in a default argument of a
|
||||
member function. */
|
||||
var = search_tree (arg, local_variable_p);
|
||||
var = search_tree (&arg, local_variable_p);
|
||||
if (var)
|
||||
{
|
||||
cp_error ("default argument `%E' uses local variable `%D'",
|
||||
|
@ -1476,6 +1476,7 @@ dump_expr (t, nop)
|
||||
dump_expr (TREE_OPERAND (t, 1), 0);
|
||||
break;
|
||||
|
||||
case INIT_EXPR:
|
||||
case MODIFY_EXPR:
|
||||
case PLUS_EXPR:
|
||||
case MINUS_EXPR:
|
||||
|
@ -830,7 +830,6 @@ expand_throw (exp)
|
||||
tree exp;
|
||||
{
|
||||
tree fn;
|
||||
static tree cleanup_type;
|
||||
|
||||
if (! doing_eh (1))
|
||||
return;
|
||||
|
@ -239,9 +239,6 @@ cplus_expand_expr (exp, target, tmode, modifier)
|
||||
integer_one_node),
|
||||
TREE_OPERAND (exp, 1), 0), target, tmode, modifier);
|
||||
|
||||
case NEW_EXPR:
|
||||
return expand_expr (build_new_1 (exp), target, tmode, modifier);
|
||||
|
||||
case STMT_EXPR:
|
||||
{
|
||||
tree rtl_expr = begin_stmt_expr ();
|
||||
|
@ -2065,6 +2065,9 @@ build_new (placement, decl, init, use_global_new)
|
||||
rval = build (NEW_EXPR, build_pointer_type (type), placement, t, init);
|
||||
NEW_EXPR_USE_GLOBAL (rval) = use_global_new;
|
||||
TREE_SIDE_EFFECTS (rval) = 1;
|
||||
rval = build_new_1 (rval);
|
||||
if (rval == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
/* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */
|
||||
rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval);
|
||||
@ -2188,11 +2191,7 @@ build_new_1 (exp)
|
||||
&& TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node));
|
||||
|
||||
if (use_cookie)
|
||||
{
|
||||
tree extra = BI_header_size;
|
||||
|
||||
size = size_binop (PLUS_EXPR, size, extra);
|
||||
}
|
||||
size = size_binop (PLUS_EXPR, size, BI_header_size);
|
||||
|
||||
if (has_array)
|
||||
{
|
||||
@ -2378,6 +2377,13 @@ build_new_1 (exp)
|
||||
rval = newrval;
|
||||
TREE_HAS_CONSTRUCTOR (rval) = 1;
|
||||
}
|
||||
else if (current_function_decl)
|
||||
rval = (build_vec_init
|
||||
(NULL_TREE,
|
||||
save_expr (rval),
|
||||
build_binary_op (MINUS_EXPR, nelts, integer_one_node),
|
||||
init,
|
||||
/*from_array=*/0));
|
||||
else
|
||||
rval = build (VEC_INIT_EXPR, TREE_TYPE (rval),
|
||||
save_expr (rval), init, nelts);
|
||||
|
@ -795,6 +795,7 @@ init_parse (filename)
|
||||
opname_tab[(int) INDIRECT_REF] = "*";
|
||||
opname_tab[(int) ARRAY_REF] = "[]";
|
||||
opname_tab[(int) MODIFY_EXPR] = "=";
|
||||
opname_tab[(int) INIT_EXPR] = "=";
|
||||
opname_tab[(int) NEW_EXPR] = "new";
|
||||
opname_tab[(int) DELETE_EXPR] = "delete";
|
||||
opname_tab[(int) VEC_NEW_EXPR] = "new []";
|
||||
|
@ -28,8 +28,10 @@ Boston, MA 02111-1307, USA. */
|
||||
#include "rtl.h"
|
||||
#include "toplev.h"
|
||||
#include "ggc.h"
|
||||
#include "splay-tree.h"
|
||||
|
||||
static tree bot_manip PROTO((tree));
|
||||
static tree bot_replace PROTO((tree *));
|
||||
static tree build_cplus_array_type_1 PROTO((tree, tree));
|
||||
static void list_hash_add PROTO((int, tree));
|
||||
static int list_hash PROTO((tree, tree, tree));
|
||||
@ -37,7 +39,7 @@ static tree list_hash_lookup PROTO((int, tree, tree, tree));
|
||||
static void propagate_binfo_offsets PROTO((tree, tree));
|
||||
static int avoid_overlap PROTO((tree, tree));
|
||||
static cp_lvalue_kind lvalue_p_1 PROTO((tree, int));
|
||||
static tree no_linkage_helper PROTO((tree));
|
||||
static tree no_linkage_helper PROTO((tree *));
|
||||
static tree build_srcloc PROTO((char *, int));
|
||||
static void mark_list_hash PROTO ((void *));
|
||||
|
||||
@ -1529,19 +1531,20 @@ copy_template_template_parm (t)
|
||||
non-null, return that value. */
|
||||
|
||||
tree
|
||||
search_tree (t, func)
|
||||
tree t;
|
||||
tree (*func) PROTO((tree));
|
||||
search_tree (tp, func)
|
||||
tree *tp;
|
||||
tree (*func) PROTO((tree *));
|
||||
{
|
||||
#define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp
|
||||
#define TRY(ARG) if (tmp=search_tree (&ARG, func), tmp != NULL_TREE) return tmp
|
||||
|
||||
tree t = *tp;
|
||||
tree tmp;
|
||||
enum tree_code code;
|
||||
|
||||
if (t == NULL_TREE)
|
||||
return t;
|
||||
|
||||
tmp = func (t);
|
||||
if (t == NULL_TREE)
|
||||
return NULL_TREE;
|
||||
|
||||
tmp = func (tp);
|
||||
if (tmp)
|
||||
return tmp;
|
||||
|
||||
@ -1618,6 +1621,7 @@ search_tree (t, func)
|
||||
case TARGET_EXPR:
|
||||
case AGGR_INIT_EXPR:
|
||||
case NEW_EXPR:
|
||||
case VEC_INIT_EXPR:
|
||||
TRY (TREE_OPERAND (t, 0));
|
||||
TRY (TREE_OPERAND (t, 1));
|
||||
TRY (TREE_OPERAND (t, 2));
|
||||
@ -1737,9 +1741,11 @@ search_tree (t, func)
|
||||
/* Passed to search_tree. Checks for the use of types with no linkage. */
|
||||
|
||||
static tree
|
||||
no_linkage_helper (t)
|
||||
tree t;
|
||||
no_linkage_helper (tp)
|
||||
tree *tp;
|
||||
{
|
||||
tree t = *tp;
|
||||
|
||||
if (TYPE_P (t)
|
||||
&& (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE)
|
||||
&& (decl_function_context (TYPE_MAIN_DECL (t))
|
||||
@ -1760,7 +1766,7 @@ no_linkage_check (t)
|
||||
if (processing_template_decl)
|
||||
return NULL_TREE;
|
||||
|
||||
t = search_tree (t, no_linkage_helper);
|
||||
t = search_tree (&t, no_linkage_helper);
|
||||
if (t != error_mark_node)
|
||||
return t;
|
||||
return NULL_TREE;
|
||||
@ -1986,6 +1992,7 @@ mapcar (t, func)
|
||||
return t;
|
||||
|
||||
case NEW_EXPR:
|
||||
case VEC_INIT_EXPR:
|
||||
t = copy_node (t);
|
||||
TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func);
|
||||
TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func);
|
||||
@ -2093,8 +2100,19 @@ array_type_nelts_total (type)
|
||||
return sz;
|
||||
}
|
||||
|
||||
static
|
||||
tree
|
||||
/* When we parse a default argument expression, we may create
|
||||
temporary variables via TARGET_EXPRs. When we actually use the
|
||||
default-argument expression, we make a copy of the expression, but
|
||||
we must relpace the temporaries with appropriate local versions. */
|
||||
|
||||
/* A map from VAR_DECLs declared in TARGET_EXPRs in a default argument
|
||||
to corresponding "instantiations" of those variables. */
|
||||
static splay_tree target_remap;
|
||||
static int target_remap_count;
|
||||
|
||||
/* Called from break_out_target_exprs via mapcar. */
|
||||
|
||||
static tree
|
||||
bot_manip (t)
|
||||
tree t;
|
||||
{
|
||||
@ -2102,16 +2120,26 @@ bot_manip (t)
|
||||
return t;
|
||||
else if (TREE_CODE (t) == TARGET_EXPR)
|
||||
{
|
||||
tree u;
|
||||
|
||||
if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR)
|
||||
{
|
||||
mark_used (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 1), 0), 0));
|
||||
return build_cplus_new
|
||||
u = build_cplus_new
|
||||
(TREE_TYPE (t), break_out_target_exprs (TREE_OPERAND (t, 1)));
|
||||
}
|
||||
t = copy_node (t);
|
||||
TREE_OPERAND (t, 0) = build (VAR_DECL, TREE_TYPE (t));
|
||||
layout_decl (TREE_OPERAND (t, 0), 0);
|
||||
return t;
|
||||
else
|
||||
{
|
||||
u = copy_node (t);
|
||||
TREE_OPERAND (u, 0) = build (VAR_DECL, TREE_TYPE (t));
|
||||
layout_decl (TREE_OPERAND (u, 0), 0);
|
||||
}
|
||||
|
||||
/* Map the old variable to the new one. */
|
||||
splay_tree_insert (target_remap,
|
||||
(splay_tree_key) TREE_OPERAND (t, 0),
|
||||
(splay_tree_value) TREE_OPERAND (u, 0));
|
||||
return u;
|
||||
}
|
||||
else if (TREE_CODE (t) == CALL_EXPR)
|
||||
mark_used (TREE_OPERAND (TREE_OPERAND (t, 0), 0));
|
||||
@ -2119,13 +2147,43 @@ bot_manip (t)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Replace all remapped VAR_DECLs in T with their new equivalents. */
|
||||
|
||||
static tree
|
||||
bot_replace (t)
|
||||
tree *t;
|
||||
{
|
||||
if (TREE_CODE (*t) == VAR_DECL)
|
||||
{
|
||||
splay_tree_node n = splay_tree_lookup (target_remap,
|
||||
(splay_tree_key) *t);
|
||||
if (n)
|
||||
*t = (tree) n->value;
|
||||
}
|
||||
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* Actually, we'll just clean out the target exprs for the moment. */
|
||||
|
||||
tree
|
||||
break_out_target_exprs (t)
|
||||
tree t;
|
||||
{
|
||||
return mapcar (t, bot_manip);
|
||||
if (!target_remap_count++)
|
||||
target_remap = splay_tree_new (splay_tree_compare_pointers,
|
||||
/*splay_tree_delete_key_fn=*/NULL,
|
||||
/*splay_tree_delete_value_fn=*/NULL);
|
||||
t = mapcar (t, bot_manip);
|
||||
search_tree (&t, bot_replace);
|
||||
|
||||
if (!--target_remap_count)
|
||||
{
|
||||
splay_tree_delete (target_remap);
|
||||
target_remap = NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/* Obstack used for allocating nodes in template function and variable
|
||||
|
@ -5877,7 +5877,8 @@ build_modify_expr (lhs, modifycode, rhs)
|
||||
{
|
||||
newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL,
|
||||
"assignment", NULL_TREE, 0);
|
||||
if (lhs == DECL_RESULT (current_function_decl))
|
||||
if (current_function_decl &&
|
||||
lhs == DECL_RESULT (current_function_decl))
|
||||
{
|
||||
if (DECL_INITIAL (lhs))
|
||||
warning ("return value from function receives multiple initializations");
|
||||
|
Loading…
Reference in New Issue
Block a user