From a321abdb59be41dfddd43cb690be9bd0dc393caf Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 27 Apr 2001 10:47:36 +0000 Subject: [PATCH] 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@41625 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 6 +++ gcc/cp/class.c | 74 ++++++++++++++++++++++++++ gcc/cp/cp-tree.h | 1 + gcc/cp/decl.c | 6 +++ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/g++.old-deja/g++.other/defarg9.C | 52 ++++++++++++++++++ 6 files changed, 143 insertions(+) create mode 100644 gcc/testsuite/g++.old-deja/g++.other/defarg9.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c6e06ac..7dc59bf 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2001-04-27 Nathan Sidwell + + * 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 * method.c (use_thunk): Make sure that thunks really are emitted diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 9c713c0..6db4f78 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -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. */ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index ef12e1e..a8b22a4 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -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 */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index ea37eb4..246cbd7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -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) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 3449dde..1f7bb78 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2001-04-27 Nathan Sidwell + + * g++.old-deja/g++.other/defarg9.C: New test. + 2001-04-26 Toon Moene * g77.f-torture/compile/20010426.f: New test. diff --git a/gcc/testsuite/g++.old-deja/g++.other/defarg9.C b/gcc/testsuite/g++.old-deja/g++.other/defarg9.C new file mode 100644 index 0000000..f3b0a48 --- /dev/null +++ b/gcc/testsuite/g++.old-deja/g++.other/defarg9.C @@ -0,0 +1,52 @@ +// Build don't link: +// +// Copyright (C) 2001 Free Software Foundation, Inc. +// Contributed by Nathan Sidwell 24 April 2001 + +// 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) +{ +} -- 2.7.4