re PR c++/8534 (When compiling qt contradicting aliasing class created for bitfield...
authorMark Mitchell <mark@codesourcery.com>
Mon, 10 Mar 2003 06:22:28 +0000 (06:22 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 10 Mar 2003 06:22:28 +0000 (06:22 +0000)
PR c++/8534
* decl.c (build_ptrmemfunc_type): Do not allow default arugments
in pointer-to-member-function types.

PR c++/8534
* g++.dg/opt/ptrmem1.C: New test.

From-SVN: r64066

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/opt/ptrmem1.C [new file with mode: 0644]

index 48e4f3a173ed521608a7b83eacc6040da97f1e4a..257673fd205b1f58de401cf1df0cf86fd97fdf6b 100644 (file)
@@ -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.
index 639c5d04293aace51589c11dee0b6d835b99e1d5..b3e617f88f45636e9d861033d49023850abc77d0 100644 (file)
@@ -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.  */
index 4c26c4868e7493a4a5b0b3f150d636a391e5e04c..517f3b4193c54bc83fe0fcabf874009f0c1b81a9 100644 (file)
@@ -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 (file)
index 0000000..0a02a53
--- /dev/null
@@ -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;
+}