langhooks.h (struct lang_hooks_for_tree_inlining): Add start_inlining, end_inlining.
* langhooks.h (struct lang_hooks_for_tree_inlining): Add start_inlining, end_inlining. * tree-inline.c (expand_call_inline): Call them. * langhooks-def.h (LANG_HOOKS_TREE_INLINING_START_INLINING): Define. (LANG_HOOKS_TREE_INLINING_END_INLINING): Define. (LANG_HOOKS_TREE_INLINING_INITIALIZER): Add them. * langhooks.c (lhd_tree_inlining_start_inlining): New fn. (lhd_tree_inlining_end_inlining): New fn. * cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define. (LANG_HOOKS_TREE_INLINING_END_INLINING): Define. * tree.c (cp_start_inlining, cp_end_inlining): New fns. * pt.c (push_tinst_level): No longer static. * cp-tree.h: Declare them. * init.c (resolve_offset_ref): Don't check access for the base conversion to access a FIELD_DECL. * cp-tree.h (TYPE_REFFN_P): New macro. * decl.c (bad_specifiers): Check it, too. * rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY on the __*_type_info type if we haven't seen a definition. From-SVN: r47703
This commit is contained in:
parent
e4aae2617a
commit
742a37d529
@ -1,3 +1,14 @@
|
||||
2001-12-04 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* langhooks.h (struct lang_hooks_for_tree_inlining): Add
|
||||
start_inlining, end_inlining.
|
||||
* tree-inline.c (expand_call_inline): Call them.
|
||||
* langhooks-def.h (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
|
||||
(LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
|
||||
(LANG_HOOKS_TREE_INLINING_INITIALIZER): Add them.
|
||||
* langhooks.c (lhd_tree_inlining_start_inlining): New fn.
|
||||
(lhd_tree_inlining_end_inlining): New fn.
|
||||
|
||||
2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* c-common.c (shadow_warning): New function, moved from cp/decl.c.
|
||||
|
@ -1,3 +1,20 @@
|
||||
2001-12-05 Jason Merrill <jason@redhat.com>
|
||||
|
||||
* cp-lang.c (LANG_HOOKS_TREE_INLINING_START_INLINING): Define.
|
||||
(LANG_HOOKS_TREE_INLINING_END_INLINING): Define.
|
||||
* tree.c (cp_start_inlining, cp_end_inlining): New fns.
|
||||
* pt.c (push_tinst_level): No longer static.
|
||||
* cp-tree.h: Declare them.
|
||||
|
||||
* init.c (resolve_offset_ref): Don't check access for the base
|
||||
conversion to access a FIELD_DECL.
|
||||
|
||||
* cp-tree.h (TYPE_REFFN_P): New macro.
|
||||
* decl.c (bad_specifiers): Check it, too.
|
||||
|
||||
* rtti.c (create_pseudo_type_info): Set CLASSTYPE_INTERFACE_ONLY
|
||||
on the __*_type_info type if we haven't seen a definition.
|
||||
|
||||
2001-12-05 Neil Booth <neil@daikokuya.demon.co.uk>
|
||||
|
||||
* decl.c: Include c-common.h.
|
||||
|
@ -83,6 +83,10 @@ static HOST_WIDE_INT cxx_get_alias_set PARAMS ((tree));
|
||||
cp_copy_res_decl_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_START_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_START_INLINING cp_start_inlining
|
||||
#undef LANG_HOOKS_TREE_INLINING_END_INLINING
|
||||
#define LANG_HOOKS_TREE_INLINING_END_INLINING cp_end_inlining
|
||||
#undef LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN
|
||||
#define LANG_HOOKS_TREE_DUMP_DUMP_TREE_FN cp_dump_tree
|
||||
#undef LANG_HOOKS_TREE_DUMP_TYPE_QUALS_FN
|
||||
|
@ -2487,6 +2487,9 @@ extern int flag_new_for_scope;
|
||||
#define TYPE_PTRFN_P(NODE) \
|
||||
(TREE_CODE (NODE) == POINTER_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
|
||||
#define TYPE_REFFN_P(NODE) \
|
||||
(TREE_CODE (NODE) == REFERENCE_TYPE \
|
||||
&& TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE)
|
||||
|
||||
/* Nonzero for _TYPE node means that this type is a pointer to member
|
||||
function type. */
|
||||
@ -3968,6 +3971,7 @@ extern void do_decl_instantiation PARAMS ((tree, tree, tree));
|
||||
extern void do_type_instantiation PARAMS ((tree, tree, int));
|
||||
extern tree instantiate_decl PARAMS ((tree, int));
|
||||
extern tree get_bindings PARAMS ((tree, tree, tree));
|
||||
extern int push_tinst_level PARAMS ((tree));
|
||||
extern void pop_tinst_level PARAMS ((void));
|
||||
extern int more_specialized_class PARAMS ((tree, tree));
|
||||
extern int is_member_template PARAMS ((tree));
|
||||
@ -4240,6 +4244,8 @@ extern int cp_is_overload_p PARAMS ((tree));
|
||||
extern int cp_auto_var_in_fn_p PARAMS ((tree,tree));
|
||||
extern tree cp_copy_res_decl_for_inlining PARAMS ((tree, tree, tree, void*,
|
||||
int*, void*));
|
||||
extern int cp_start_inlining PARAMS ((tree));
|
||||
extern void cp_end_inlining PARAMS ((tree));
|
||||
|
||||
/* in typeck.c */
|
||||
extern int string_conv_p PARAMS ((tree, tree, int));
|
||||
|
@ -8750,6 +8750,7 @@ bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises)
|
||||
if (raises
|
||||
&& (TREE_CODE (object) == TYPE_DECL
|
||||
|| (!TYPE_PTRFN_P (TREE_TYPE (object))
|
||||
&& !TYPE_REFFN_P (TREE_TYPE (object))
|
||||
&& !TYPE_PTRMEMFUNC_P (TREE_TYPE (object)))))
|
||||
cp_error_at ("`%D' declared with an exception specification", object);
|
||||
}
|
||||
|
@ -1831,9 +1831,12 @@ resolve_offset_ref (exp)
|
||||
if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE)
|
||||
base = build_scoped_ref (base, TYPE_OFFSET_BASETYPE (type));
|
||||
|
||||
basetype = lookup_base (TREE_TYPE (base), basetype, ba_check, NULL);
|
||||
/* Don't check access on the conversion; we might be after a member
|
||||
promoted by an access- or using-declaration, and we have already
|
||||
checked access for the member itself. */
|
||||
basetype = lookup_base (TREE_TYPE (base), basetype, ba_ignore, NULL);
|
||||
expr = build_base_path (PLUS_EXPR, base, basetype, 1);
|
||||
|
||||
|
||||
if (expr == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
@ -98,7 +98,6 @@ static int try_one_overload PARAMS ((tree, tree, tree, tree, tree,
|
||||
unification_kind_t, int));
|
||||
static int unify PARAMS ((tree, tree, tree, tree, int));
|
||||
static void add_pending_template PARAMS ((tree));
|
||||
static int push_tinst_level PARAMS ((tree));
|
||||
static void reopen_tinst_level PARAMS ((tree));
|
||||
static tree classtype_mangled_name PARAMS ((tree));
|
||||
static char *mangle_class_name_for_template PARAMS ((const char *, tree, tree));
|
||||
@ -4460,7 +4459,7 @@ static int last_template_error_tick;
|
||||
/* We're starting to instantiate D; record the template instantiation context
|
||||
for diagnostics and to restore it later. */
|
||||
|
||||
static int
|
||||
int
|
||||
push_tinst_level (d)
|
||||
tree d;
|
||||
{
|
||||
|
@ -1162,6 +1162,15 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
|
||||
/* Get the vtable decl. */
|
||||
real_type = xref_tag (class_type_node, get_identifier (real_name), 1);
|
||||
if (! TYPE_SIZE (real_type))
|
||||
{
|
||||
/* We never saw a definition of this type, so we need to tell the
|
||||
compiler that this is an exported class, as indeed all of the
|
||||
__*_type_info classes are. */
|
||||
SET_CLASSTYPE_INTERFACE_KNOWN (real_type);
|
||||
CLASSTYPE_INTERFACE_ONLY (real_type) = 1;
|
||||
}
|
||||
|
||||
vtable_decl = get_vtable_decl (real_type, /*complete=*/1);
|
||||
vtable_decl = build_unary_op (ADDR_EXPR, vtable_decl, 0);
|
||||
|
||||
@ -1185,12 +1194,12 @@ create_pseudo_type_info VPARAMS((const char *real_name, int ident, ...))
|
||||
pseudo_type = make_aggr_type (RECORD_TYPE);
|
||||
finish_builtin_type (pseudo_type, pseudo_name, fields, ix, ptr_type_node);
|
||||
TYPE_HAS_CONSTRUCTOR (pseudo_type) = 1;
|
||||
VA_CLOSE (ap);
|
||||
|
||||
result = tree_cons (NULL_TREE, NULL_TREE, NULL_TREE);
|
||||
TINFO_VTABLE_DECL (result) = vtable_decl;
|
||||
TINFO_PSEUDO_TYPE (result) = pseudo_type;
|
||||
|
||||
VA_CLOSE (ap);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2230,6 +2230,30 @@ cp_copy_res_decl_for_inlining (result, fn, caller, decl_map_,
|
||||
return var;
|
||||
}
|
||||
|
||||
/* Record that we're about to start inlining FN, and return non-zero if
|
||||
that's OK. Used for lang_hooks.tree_inlining.start_inlining. */
|
||||
|
||||
int
|
||||
cp_start_inlining (fn)
|
||||
tree fn;
|
||||
{
|
||||
if (DECL_TEMPLATE_INSTANTIATION (fn))
|
||||
return push_tinst_level (fn);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Record that we're done inlining FN. Used for
|
||||
lang_hooks.tree_inlining.end_inlining. */
|
||||
|
||||
void
|
||||
cp_end_inlining (fn)
|
||||
tree fn ATTRIBUTE_UNUSED;
|
||||
{
|
||||
if (DECL_TEMPLATE_INSTANTIATION (fn))
|
||||
pop_tinst_level ();
|
||||
}
|
||||
|
||||
/* Initialize tree.c. */
|
||||
|
||||
void
|
||||
|
@ -60,6 +60,8 @@ tree lhd_tree_inlining_copy_res_decl_for_inlining PARAMS ((tree, tree,
|
||||
tree, void *,
|
||||
int *, void *));
|
||||
int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree));
|
||||
int lhd_tree_inlining_start_inlining PARAMS ((tree));
|
||||
void lhd_tree_inlining_end_inlining PARAMS ((tree));
|
||||
|
||||
#define LANG_HOOKS_NAME "GNU unknown"
|
||||
#define LANG_HOOKS_IDENTIFIER_SIZE sizeof (struct lang_identifier)
|
||||
@ -97,6 +99,10 @@ int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree));
|
||||
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_START_INLINING \
|
||||
lhd_tree_inlining_start_inlining
|
||||
#define LANG_HOOKS_TREE_INLINING_END_INLINING \
|
||||
lhd_tree_inlining_end_inlining
|
||||
|
||||
#define LANG_HOOKS_TREE_INLINING_INITIALIZER { \
|
||||
LANG_HOOKS_TREE_INLINING_WALK_SUBTREES, \
|
||||
@ -106,7 +112,9 @@ int lhd_tree_inlining_anon_aggr_type_p PARAMS ((tree));
|
||||
LANG_HOOKS_TREE_INLINING_TREE_CHAIN_MATTERS_P, \
|
||||
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_ANON_AGGR_TYPE_P, \
|
||||
LANG_HOOKS_TREE_INLINING_START_INLINING, \
|
||||
LANG_HOOKS_TREE_INLINING_END_INLINING \
|
||||
} \
|
||||
|
||||
/* Tree dump hooks. */
|
||||
|
@ -240,6 +240,27 @@ lhd_tree_inlining_anon_aggr_type_p (t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_inlining.start_inlining and end_inlining perform any
|
||||
language-specific bookkeeping necessary for processing
|
||||
FN. start_inlining returns non-zero if inlining should proceed, zero if
|
||||
not.
|
||||
|
||||
For instance, the C++ version keeps track of template instantiations to
|
||||
avoid infinite recursion. */
|
||||
|
||||
int
|
||||
lhd_tree_inlining_start_inlining (fn)
|
||||
tree fn ATTRIBUTE_UNUSED;
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
lhd_tree_inlining_end_inlining (fn)
|
||||
tree fn ATTRIBUTE_UNUSED;
|
||||
{
|
||||
}
|
||||
|
||||
/* lang_hooks.tree_dump.dump_tree: Dump language-specific parts of tree
|
||||
nodes. Returns non-zero if it does not want the usual dumping of the
|
||||
second argument. */
|
||||
|
@ -46,6 +46,8 @@ struct lang_hooks_for_tree_inlining
|
||||
void *, int *,
|
||||
void *));
|
||||
int (*anon_aggr_type_p) PARAMS ((union tree_node *));
|
||||
int (*start_inlining) PARAMS ((union tree_node *));
|
||||
void (*end_inlining) PARAMS ((union tree_node *));
|
||||
};
|
||||
|
||||
/* The following hooks are used by tree-dump.c. */
|
||||
|
5
gcc/testsuite/g++.dg/eh/spec1.C
Normal file
5
gcc/testsuite/g++.dg/eh/spec1.C
Normal file
@ -0,0 +1,5 @@
|
||||
// Check that we allow an exception specification on a reference-to-function.
|
||||
// { dg-do compile }
|
||||
|
||||
void f () throw ();
|
||||
void (&fp)() throw () = f;
|
19
gcc/testsuite/g++.dg/inherit/access1.C
Normal file
19
gcc/testsuite/g++.dg/inherit/access1.C
Normal file
@ -0,0 +1,19 @@
|
||||
// Test that we can access a member from an inaccessible base if it has
|
||||
// been promoted with a using-declaration.
|
||||
|
||||
// { dg-do compile }
|
||||
|
||||
struct A
|
||||
{
|
||||
int i;
|
||||
};
|
||||
|
||||
struct B: private A
|
||||
{
|
||||
using A::i;
|
||||
};
|
||||
|
||||
struct C: public B
|
||||
{
|
||||
void f () { B::i = 0; }
|
||||
};
|
22
gcc/testsuite/g++.dg/template/recurse.C
Normal file
22
gcc/testsuite/g++.dg/template/recurse.C
Normal file
@ -0,0 +1,22 @@
|
||||
// Test for handling of excessive template recursion.
|
||||
// { dg-options "-ftemplate-depth-50 -O" }
|
||||
|
||||
template <int I> struct F
|
||||
{
|
||||
int operator()()
|
||||
{
|
||||
F<I+1> f; // { dg-error "" "" }
|
||||
return f()*I;
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct F<52>
|
||||
{
|
||||
int operator()() { return 0; }
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
F<1> f;
|
||||
return f(); // { dg-error "instantiate" "excessive recursion" }
|
||||
}
|
@ -812,6 +812,9 @@ expand_call_inline (tp, walk_subtrees, data)
|
||||
if (!inlinable_function_p (fn, id))
|
||||
return NULL_TREE;
|
||||
|
||||
if (! (*lang_hooks.tree_inlining.start_inlining) (fn))
|
||||
return NULL_TREE;
|
||||
|
||||
/* Set the current filename and line number to the function we are
|
||||
inlining so that when we create new _STMT nodes here they get
|
||||
line numbers corresponding to the function we are calling. We
|
||||
@ -951,6 +954,8 @@ expand_call_inline (tp, walk_subtrees, data)
|
||||
/* Don't walk into subtrees. We've already handled them above. */
|
||||
*walk_subtrees = 0;
|
||||
|
||||
(*lang_hooks.tree_inlining.end_inlining) (fn);
|
||||
|
||||
/* Keep iterating. */
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user