OSDN Git Service

PR c++/19311
authorlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 5 Mar 2005 15:44:22 +0000 (15:44 +0000)
committerlerdsuwa <lerdsuwa@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 5 Mar 2005 15:44:22 +0000 (15:44 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@95933 138bc75d-0d04-0410-961f-82ee72b054a4

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 0fc67aa..4c40681 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 0878686..d572bca 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 0d83bc1..14940b7 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 330e8f1..9de7b24 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 7b5ae18..fefe239 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); 
+}