cp-tree.h (adjust_clone_args): Prototype new function.
cp: * cp-tree.h (adjust_clone_args): Prototype new function. * class.c (adjust_clone_args): New function. * decl.c (start_function): Call it for in charge ctors. testsuite: * g++.old-deja/g++.other/defarg9.C: New test. From-SVN: r41625
This commit is contained in:
parent
6e0263244c
commit
5f6eeeb362
@ -1,3 +1,9 @@
|
||||
2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cp-tree.h (adjust_clone_args): Prototype new function.
|
||||
* class.c (adjust_clone_args): New function.
|
||||
* decl.c (start_function): Call it for in charge ctors.
|
||||
|
||||
2001-04-26 Mark Mitchell <mark@codesourcery.com>
|
||||
|
||||
* method.c (use_thunk): Make sure that thunks really are emitted
|
||||
|
@ -4407,6 +4407,80 @@ clone_function_decl (fn, update_method_vec_p)
|
||||
DECL_ABSTRACT (fn) = 1;
|
||||
}
|
||||
|
||||
/* DECL is an in charge constructor, which is being defined. This will
|
||||
have had an in class declaration, from whence clones were
|
||||
declared. An out-of-class definition can specify additional default
|
||||
arguments. As it is the clones that are involved in overload
|
||||
resolution, we must propagate the information from the DECL to its
|
||||
clones. */
|
||||
|
||||
void
|
||||
adjust_clone_args (decl)
|
||||
tree decl;
|
||||
{
|
||||
tree clone;
|
||||
|
||||
for (clone = TREE_CHAIN (decl); clone && DECL_CLONED_FUNCTION (clone);
|
||||
clone = TREE_CHAIN (clone))
|
||||
{
|
||||
tree orig_clone_parms = TYPE_ARG_TYPES (TREE_TYPE (clone));
|
||||
tree orig_decl_parms = TYPE_ARG_TYPES (TREE_TYPE (decl));
|
||||
tree decl_parms, clone_parms;
|
||||
|
||||
clone_parms = orig_clone_parms;
|
||||
|
||||
/* Skip the 'this' parameter. */
|
||||
orig_clone_parms = TREE_CHAIN (orig_clone_parms);
|
||||
orig_decl_parms = TREE_CHAIN (orig_decl_parms);
|
||||
|
||||
if (DECL_HAS_IN_CHARGE_PARM_P (decl))
|
||||
orig_decl_parms = TREE_CHAIN (orig_decl_parms);
|
||||
if (DECL_HAS_VTT_PARM_P (decl))
|
||||
orig_decl_parms = TREE_CHAIN (orig_decl_parms);
|
||||
|
||||
clone_parms = orig_clone_parms;
|
||||
if (DECL_HAS_VTT_PARM_P (clone))
|
||||
clone_parms = TREE_CHAIN (clone_parms);
|
||||
|
||||
for (decl_parms = orig_decl_parms; decl_parms;
|
||||
decl_parms = TREE_CHAIN (decl_parms),
|
||||
clone_parms = TREE_CHAIN (clone_parms))
|
||||
{
|
||||
my_friendly_assert (same_type_p (TREE_TYPE (decl_parms),
|
||||
TREE_TYPE (clone_parms)), 20010424);
|
||||
|
||||
if (TREE_PURPOSE (decl_parms) && !TREE_PURPOSE (clone_parms))
|
||||
{
|
||||
/* A default parameter has been added. Adjust the
|
||||
clone's parameters. */
|
||||
tree exceptions = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (clone));
|
||||
tree basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (clone));
|
||||
tree type;
|
||||
|
||||
clone_parms = orig_decl_parms;
|
||||
|
||||
if (DECL_HAS_VTT_PARM_P (clone))
|
||||
{
|
||||
clone_parms = tree_cons (TREE_PURPOSE (orig_clone_parms),
|
||||
TREE_VALUE (orig_clone_parms),
|
||||
clone_parms);
|
||||
TREE_TYPE (clone_parms) = TREE_TYPE (orig_clone_parms);
|
||||
}
|
||||
type = build_cplus_method_type (basetype,
|
||||
TREE_TYPE (TREE_TYPE (clone)),
|
||||
clone_parms);
|
||||
if (exceptions)
|
||||
type = build_exception_variant (type, exceptions);
|
||||
TREE_TYPE (clone) = type;
|
||||
|
||||
clone_parms = NULL_TREE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
my_friendly_assert (!clone_parms, 20010424);
|
||||
}
|
||||
}
|
||||
|
||||
/* For each of the constructors and destructors in T, create an
|
||||
in-charge and not-in-charge variant. */
|
||||
|
||||
|
@ -3759,6 +3759,7 @@ extern tree build_expr_type_conversion PARAMS ((int, tree, int));
|
||||
extern tree type_promotes_to PARAMS ((tree));
|
||||
extern tree perform_qualification_conversions PARAMS ((tree, tree));
|
||||
extern void clone_function_decl PARAMS ((tree, int));
|
||||
extern void adjust_clone_args PARAMS ((tree));
|
||||
|
||||
/* decl.c */
|
||||
/* resume_binding_level */
|
||||
|
@ -13345,6 +13345,12 @@ start_function (declspecs, declarator, attrs, flags)
|
||||
}
|
||||
}
|
||||
|
||||
if (DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl1))
|
||||
/* This is a constructor, we must ensure that any default args
|
||||
introduced by this definition are propagated to the clones
|
||||
now. The clones are used directly in overload resolution. */
|
||||
adjust_clone_args (decl1);
|
||||
|
||||
/* Sometimes we don't notice that a function is a static member, and
|
||||
build a METHOD_TYPE for it. Fix that up now. */
|
||||
if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)
|
||||
|
@ -1,3 +1,7 @@
|
||||
2001-04-27 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.old-deja/g++.other/defarg9.C: New test.
|
||||
|
||||
2001-04-26 Toon Moene <toon@moene.indiv.nluug.nl>
|
||||
|
||||
* g77.f-torture/compile/20010426.f: New test.
|
||||
|
52
gcc/testsuite/g++.old-deja/g++.other/defarg9.C
Normal file
52
gcc/testsuite/g++.old-deja/g++.other/defarg9.C
Normal file
@ -0,0 +1,52 @@
|
||||
// Build don't link:
|
||||
//
|
||||
// Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 24 April 2001 <nathan@codesourcery.com>
|
||||
|
||||
// Bug 2608. A default parameter introduced in the definition of a
|
||||
// ctor never made it into the clones, leading to later overload
|
||||
// resolution failures. This is related to bug 2356.
|
||||
|
||||
struct A
|
||||
{
|
||||
A (int, int);
|
||||
};
|
||||
|
||||
A::A (int d, int = 0)
|
||||
{
|
||||
if (d)
|
||||
{
|
||||
A a (0);
|
||||
}
|
||||
}
|
||||
|
||||
void get_width ()
|
||||
{
|
||||
A a (1);
|
||||
}
|
||||
|
||||
struct B : A
|
||||
{
|
||||
B ();
|
||||
};
|
||||
B::B ()
|
||||
:A (1)
|
||||
{
|
||||
}
|
||||
|
||||
struct C : virtual A
|
||||
{
|
||||
C (int, int);
|
||||
};
|
||||
C::C (int, int = 0)
|
||||
:A (1)
|
||||
{
|
||||
}
|
||||
struct D: C
|
||||
{
|
||||
D ();
|
||||
};
|
||||
D::D ()
|
||||
:A (0), C (0)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user