re PR c++/37016 (member function pointer failure with optimization)
authorJason Merrill <jason@redhat.com>
Wed, 6 Aug 2008 02:25:20 +0000 (22:25 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 6 Aug 2008 02:25:20 +0000 (22:25 -0400)
        PR c++/37016
        * decl.c (build_ptrmemfunc_type): Don't require structural
        comparison of PMF types.
        * tree.c (cp_build_qualified_type_real): Don't clear
        a valid TYPE_PTRMEMFUNC_TYPE.
        * typeck.c (cp_build_unary_op): Still do build_ptrmemfunc in
        templates.

From-SVN: r138756

gcc/cp/ChangeLog
gcc/cp/decl.c
gcc/cp/tree.c
gcc/cp/typeck.c

index 8ff23cd..8ece21d 100644 (file)
@@ -1,3 +1,13 @@
+2008-08-05  Jason Merrill  <jason@redhat.com>
+
+       PR c++/37016
+       * decl.c (build_ptrmemfunc_type): Don't require structural 
+       comparison of PMF types.
+       * tree.c (cp_build_qualified_type_real): Don't clear
+       a valid TYPE_PTRMEMFUNC_TYPE.
+       * typeck.c (cp_build_unary_op): Still do build_ptrmemfunc in 
+       templates.
+
 2008-08-04  Jason Merrill  <jason@redhat.com>
 
        PR c++/36963
index 1ed98ee..69fa647 100644 (file)
@@ -6961,16 +6961,17 @@ build_ptrmemfunc_type (tree type)
       TYPE_MAIN_VARIANT (t) = unqualified_variant;
       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (unqualified_variant);
       TYPE_NEXT_VARIANT (unqualified_variant) = t;
+      TREE_TYPE (TYPE_BINFO (t)) = t;
     }
 
   /* Cache this pointer-to-member type so that we can find it again
      later.  */
   TYPE_SET_PTRMEMFUNC_TYPE (type, t);
 
-  /* Managing canonical types for the RECORD_TYPE behind a
-     pointer-to-member function is a nightmare, so use structural
-     equality for now.  */
-  SET_TYPE_STRUCTURAL_EQUALITY (t);
+  if (TYPE_STRUCTURAL_EQUALITY_P (type))
+    SET_TYPE_STRUCTURAL_EQUALITY (t);
+  else if (TYPE_CANONICAL (type) != type)
+    TYPE_CANONICAL (t) = build_ptrmemfunc_type (TYPE_CANONICAL (type));
 
   return t;
 }
index 4114f86..ff19cd6 100644 (file)
@@ -873,7 +873,8 @@ cp_build_qualified_type_real (tree type,
      between the unqualified and qualified types.  */
   if (result != type
       && TREE_CODE (type) == POINTER_TYPE
-      && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)
+      && TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE
+      && TYPE_LANG_SPECIFIC (result) == TYPE_LANG_SPECIFIC (type))
     TYPE_LANG_SPECIFIC (result) = NULL;
 
   return result;
index feb6b5f..fd3dba9 100644 (file)
@@ -4642,15 +4642,7 @@ cp_build_unary_op (enum tree_code code, tree xarg, int noconvert,
 
       /* In a template, we are processing a non-dependent expression
         so we can just form an ADDR_EXPR with the correct type.  */
-      if (processing_template_decl)
-       {
-         val = build_address (arg);
-         if (TREE_CODE (arg) == OFFSET_REF)
-           PTRMEM_OK_P (val) = PTRMEM_OK_P (arg);
-         return val;
-       }
-
-      if (TREE_CODE (arg) != COMPONENT_REF)
+      if (processing_template_decl || TREE_CODE (arg) != COMPONENT_REF)
        {
          val = build_address (arg);
          if (TREE_CODE (arg) == OFFSET_REF)