This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++ PATCH] Fix bug 2608, a regression
- To: gcc-patches at gcc dot gnu dot org
- Subject: [C++ PATCH] Fix bug 2608, a regression
- From: Nathan Sidwell <nathan at codesourcery dot com>
- Date: Fri, 27 Apr 2001 11:50:17 +0100
- Organization: Codesourcery LLC
Hi,
I've installed this patch on both mainline and branch as it fixes
a 2.95 regression.
Unfortunately, we use clones directly in overload resolution. This means
that constructor default args introduced in the definition must be
propagated to the clones.
built & tested on i686-pc-linux-gnu, approved by Mark.
nathan
--
Dr Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC
'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
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.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/class.c,v
retrieving revision 1.375
diff -c -3 -p -r1.375 class.c
*** class.c 2001/04/20 15:29:09 1.375
--- class.c 2001/04/27 10:20:48
*************** clone_function_decl (fn, update_method_v
*** 4407,4412 ****
--- 4407,4486 ----
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. */
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.604
diff -c -3 -p -r1.604 cp-tree.h
*** cp-tree.h 2001/04/26 20:05:33 1.604
--- cp-tree.h 2001/04/27 10:20:53
*************** extern tree build_expr_type_conversion
*** 3759,3764 ****
--- 3759,3765 ----
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 */
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/decl.c,v
retrieving revision 1.776
diff -c -3 -p -r1.776 decl.c
*** decl.c 2001/04/25 08:31:17 1.776
--- decl.c 2001/04/27 10:21:05
*************** start_function (declspecs, declarator, a
*** 13345,13350 ****
--- 13345,13356 ----
}
}
+ 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)
// 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)
{
}