re PR c++/19311 (ICE in resolve_overloaded_unification)
authorKriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
Sat, 5 Mar 2005 15:44:22 +0000 (15:44 +0000)
committerKriang Lerdsuwanakij <lerdsuwa@gcc.gnu.org>
Sat, 5 Mar 2005 15:44:22 +0000 (15:44 +0000)
PR c++/19311
* init.c (build_offset_ref): Don't build non-dependent SCOPE_REF.
* pt.c (build_non_dependent_expr): Don't build NON_DEPENDENT_EXPR
for OFFSET_TYPE.
* typeck.c (build_x_unary_op): Don't build non-dependent SCOPE_REF.
Also set PTRMEM_OK_P for NON_DEPENDENT_EXPR.
(build_unary_op): Handle building ADDR_EXPR of OFFSET_REF inside
template.

* g++.dg/template/non-dependent11.C: New test.

From-SVN: r95933

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/cp/pt.c
gcc/cp/typeck.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/non-dependent11.C [new file with mode: 0644]

index 0fc67aad13751a11bd2df14990fbb8b2a2a4fe5c..4c40681333faf4ca55edcc55bdb549e2c0311917 100644 (file)
@@ -1,3 +1,14 @@
+2005-03-05  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/19311
+       * init.c (build_offset_ref): Don't build non-dependent SCOPE_REF.
+       * pt.c (build_non_dependent_expr): Don't build NON_DEPENDENT_EXPR
+       for OFFSET_TYPE.
+       * typeck.c (build_x_unary_op): Don't build non-dependent SCOPE_REF.
+       Also set PTRMEM_OK_P for NON_DEPENDENT_EXPR.
+       (build_unary_op): Handle building ADDR_EXPR of OFFSET_REF inside
+       template.
+
 2005-03-02  Alexandre Oliva  <aoliva@redhat.com>
 
        * name-lookup.c (push_overloaded_decl): Don't error if the new
index 087868674f31c223f85b7960e3198ff7aaabd6d5..d572bca344e92bbedb59d7d4bfd09cec283f4dff 100644 (file)
@@ -1417,14 +1417,6 @@ build_offset_ref (tree type, tree name, bool address_p)
       return error_mark_node;
     }
 
-  if (processing_template_decl)
-    {
-      if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR)
-       return build_min (SCOPE_REF, TREE_TYPE (member), type, orig_name);
-      else
-       return build_min (SCOPE_REF, TREE_TYPE (member), type, name);
-    }
-
   if (TREE_CODE (member) == TYPE_DECL)
     {
       TREE_USED (member) = 1;
index 0d83bc1a4d278f164dc63336ab4d27fa26b12ba2..14940b7567110b2ae74ce1f76f808932addeb5a1 100644 (file)
@@ -12376,7 +12376,8 @@ build_non_dependent_expr (tree expr)
   if (TREE_CODE (inner_expr) == OVERLOAD 
       || TREE_CODE (inner_expr) == FUNCTION_DECL
       || TREE_CODE (inner_expr) == TEMPLATE_DECL
-      || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR)
+      || TREE_CODE (inner_expr) == TEMPLATE_ID_EXPR
+      || TREE_CODE (inner_expr) == OFFSET_REF)
     return expr;
   /* There is no need to return a proxy for a variable.  */
   if (TREE_CODE (expr) == VAR_DECL)
index 330e8f1ea1a8683335f17d69e5af2cae63318317..9de7b24d0a2112dffc7564e0e56b74b04540ce29 100644 (file)
@@ -3530,23 +3530,6 @@ build_x_unary_op (enum tree_code code, tree xarg)
       if (type_dependent_expression_p (xarg))
        return build_min_nt (code, xarg, NULL_TREE);
 
-      /* For non-dependent pointer-to-member, the SCOPE_REF will be
-        processed during template substitution.  Just compute the
-        right type here and build an ADDR_EXPR around it for
-        diagnostics.  */
-      if (code == ADDR_EXPR && TREE_CODE (xarg) == SCOPE_REF)
-       {
-         tree type;
-         if (TREE_TYPE (xarg) == unknown_type_node)
-           type = unknown_type_node;
-         else if (TREE_CODE (TREE_TYPE (xarg)) == FUNCTION_TYPE)
-           type = build_pointer_type (TREE_TYPE (xarg));
-         else
-           type = build_ptrmem_type (TREE_OPERAND (xarg, 0),
-                                     TREE_TYPE (xarg));
-         return build_min (code, type, xarg, NULL_TREE);
-       }
-
       xarg = build_non_dependent_expr (xarg);
     }
 
@@ -3610,13 +3593,13 @@ build_x_unary_op (enum tree_code code, tree xarg)
       else if (TREE_CODE (xarg) == TARGET_EXPR)
        warning ("taking address of temporary");
       exp = build_unary_op (ADDR_EXPR, xarg, 0);
-      if (TREE_CODE (exp) == ADDR_EXPR)
-       PTRMEM_OK_P (exp) = ptrmem;
     }
 
   if (processing_template_decl && exp != error_mark_node)
-    return build_min_non_dep (code, exp, orig_expr,
-                             /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
+    exp = build_min_non_dep (code, exp, orig_expr,
+                            /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
+  if (TREE_CODE (exp) == ADDR_EXPR)
+    PTRMEM_OK_P (exp) = ptrmem;
   return exp;
 }
 
@@ -4056,6 +4039,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
         is an error.  */
       else if (TREE_CODE (argtype) != FUNCTION_TYPE
               && TREE_CODE (argtype) != METHOD_TYPE
+              && TREE_CODE (arg) != OFFSET_REF
               && !lvalue_or_else (arg, lv_addressof))
        return error_mark_node;
 
@@ -4070,7 +4054,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
               expression so we can just form an ADDR_EXPR with the
               correct type.  */
            || processing_template_decl)
-         addr = build_address (arg);
+         {
+           addr = build_address (arg);
+           if (TREE_CODE (arg) == OFFSET_REF)
+             PTRMEM_OK_P (addr) = PTRMEM_OK_P (arg);
+         }
        else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
          {
            tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
index 7b5ae183a680f134f43b7e46b8319a4a14f0da0d..fefe2397980e706eea1392972bf2b3c02565f426 100644 (file)
@@ -1,3 +1,8 @@
+2005-03-06  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>
+
+       PR c++/19311
+       * g++.dg/template/non-dependent11.C: New test.
+
 2005-03-05  Uros Bizjak  <uros@kss-loka.si>
 
        * lib/target-supports.exp (check_iconv_available): Fix comment.
diff --git a/gcc/testsuite/g++.dg/template/non-dependent11.C b/gcc/testsuite/g++.dg/template/non-dependent11.C
new file mode 100644 (file)
index 0000000..dff5b90
--- /dev/null
@@ -0,0 +1,18 @@
+// { dg-do compile }
+
+// Origin: Jakub Jelinek <jakub@gcc.gnu.org>
+//        Wolfgang Bangerth <bangerth@ticam.utexas.edu>
+
+// PR c++/19311: Non-dependent address to member as function argument.
+
+template <class R, class T>          void foo (R (T::*x) ()); 
+template <class R, class T, class C> void foo (R (T::*x) (C)); 
+template<int> struct I { 
+  int o (); 
+  int o () const; 
+}; 
+template <int> void bar (void) { 
+  foo <int, I<1> > (&I<1>::o); 
+}