summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/decl.c38
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/opt/ptrmem1.C12
4 files changed, 61 insertions, 0 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 48e4f3a173e..257673fd205 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2003-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8534
+ * decl.c (build_ptrmemfunc_type): Do not allow default arugments
+ in pointer-to-member-function types.
+
2003-03-10 Gabriel Dos Reis <gdr@integrable-solutions.net>
* expr.c (cplus_expand_constant): Use C90 prototype style.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 639c5d04293..b3e617f88f4 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -9296,11 +9296,49 @@ build_ptrmemfunc_type (tree type)
{
tree field, fields;
tree t;
+ tree method_type;
+ tree arg_type;
tree unqualified_variant = NULL_TREE;
if (type == error_mark_node)
return type;
+ /* If the METHOD_TYPE has any default parameters, make a copy that
+ does not have the default parameters. The pointer-to-member type
+ never has default parameters. */
+ method_type = TREE_TYPE (type);
+ for (arg_type = TYPE_ARG_TYPES (method_type);
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ if (TREE_PURPOSE (arg_type))
+ {
+ /* At least one parameter has a default argument. */
+ tree arg_types = NULL_TREE;
+ tree *arg_type_p = &arg_types;
+
+ /* Copy the parameter types. The "this" parameter will be
+ added by build_cplus_method_type. */
+ for (arg_type = TREE_CHAIN (TYPE_ARG_TYPES (method_type));
+ arg_type;
+ arg_type = TREE_CHAIN (arg_type))
+ {
+ if (arg_type == void_list_node)
+ *arg_type_p = void_list_node;
+ else
+ *arg_type_p = build_tree_list (NULL_TREE,
+ TREE_VALUE (arg_type));
+ arg_type_p = &TREE_CHAIN (*arg_type_p);
+ }
+ /* Build the new METHOD_TYPE. */
+ method_type = build_cplus_method_type (TYPE_METHOD_BASETYPE (method_type),
+ TREE_TYPE (method_type),
+ arg_types);
+ /* Build the new POINTER_TYPE. */
+ type = cp_build_qualified_type (build_pointer_type (method_type),
+ cp_type_quals (type));
+ break;
+ }
+
/* If a canonical type already exists for this type, use it. We use
this method instead of type_hash_canon, because it only does a
simple equality check on the list of field members. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 4c26c4868e7..517f3b4193c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2003-03-09 Mark Mitchell <mark@codesourcery.com>
+
+ PR c++/8534
+ * g++.dg/opt/ptrmem1.C: New test.
+
2003-03-09 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/i386-loop-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/opt/ptrmem1.C b/gcc/testsuite/g++.dg/opt/ptrmem1.C
new file mode 100644
index 00000000000..0a02a53a9bf
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/ptrmem1.C
@@ -0,0 +1,12 @@
+// { dg-options "-O2" }
+
+class QWidget
+{
+ public: void repaint( bool erase = 1 );
+};
+void f (void)
+{
+ typedef void (QWidget::*A)(bool);
+ A b = &QWidget::repaint;
+}
+
OpenPOWER on IntegriCloud