This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH for 3.4/4.0] Fix PR19311 (ICE overload resolutionfor pmf function argument)


Mark Mitchell wrote:

Kriang Lerdsuwanakij wrote:

Hi

These patches fix PR19311 regression in 3.4/4.0.  Function overloading
logic for pointer-to-member function argument fails to deal with
NON_DEPENDENT_EXPR and produces ICE.

The regression was caused by my work to build non-dependent SCOPE_REF.
The intention was to have enough type to catch invalid usage of pmf
during parsing rather than during instantiation. The SCOPE_REF tree
was used to also allow access checking when the template is instantiated.
However access checking of non-dependent SCOPE_REF has been broken
for quite a long time (see PR16617).


The patch for 4.0 has one additional hunk for unary_complex_lvalue.


I don't understand that hunk; why do we need to make the transformations in unary_complex_lvalue when in a template?

After your patch, do we ever still set PTRMEM_OK_P on an ADDR_EXPR? If not, you need to update PTRMEM_OK_P and the documentation for it.

Other than that, the patch looks OK to me. If you can answer the questions above, I'll approve the patch.

I believe the condition type_dependent_expression_p I put inside
unary_complex_lvalue is safe since only the type information is used
for operator overloading which can affect the transformation result.
About PTRMEM_OK_P, it is still set inside build_x_unary_op.

I have an alternate version in the attachment, applicable to 3.4 and
mainline in case you prefer this one.  In this version, rather than
changing unary_complex_lvalue, I change its caller, build_unary_op,
to deal with ADDR_EXPR to OFFSET_REF in template.  PTRMEM_OK_P is also
correctly set.  It's tested, no regression.

--Kriang
2005-01-??  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-01-??  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

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


diff -cprN gcc-main-save/gcc/cp/init.c gcc-main-new/gcc/cp/init.c
*** gcc-main-save/gcc/cp/init.c	Thu Jan 20 00:04:24 2005
--- gcc-main-new/gcc/cp/init.c	Sun Jan 16 22:57:10 2005
*************** build_offset_ref (tree type, tree name, 
*** 1417,1430 ****
        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;
--- 1417,1422 ----
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Thu Jan 20 00:04:24 2005
--- gcc-main-new/gcc/cp/pt.c	Sun Jan 16 22:57:56 2005
*************** build_non_dependent_expr (tree expr)
*** 12372,12378 ****
    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)
      return expr;
    /* There is no need to return a proxy for a variable.  */
    if (TREE_CODE (expr) == VAR_DECL)
--- 12372,12379 ----
    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) == OFFSET_REF)
      return expr;
    /* There is no need to return a proxy for a variable.  */
    if (TREE_CODE (expr) == VAR_DECL)
diff -cprN gcc-main-save/gcc/cp/typeck.c gcc-main-new/gcc/cp/typeck.c
*** gcc-main-save/gcc/cp/typeck.c	Thu Jan 20 00:04:24 2005
--- gcc-main-new/gcc/cp/typeck.c	Thu Jan 20 00:06:43 2005
*************** build_x_unary_op (enum tree_code code, t
*** 3547,3569 ****
        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);
      }
  
--- 3547,3552 ----
*************** build_x_unary_op (enum tree_code code, t
*** 3627,3639 ****
        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);
    return exp;
  }
  
--- 3610,3622 ----
        else if (TREE_CODE (xarg) == TARGET_EXPR)
  	warning ("taking address of temporary");
        exp = build_unary_op (ADDR_EXPR, xarg, 0);
      }
  
    if (processing_template_decl && exp != error_mark_node)
!     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;
  }
  
*************** build_unary_op (enum tree_code code, tre
*** 4073,4078 ****
--- 4056,4062 ----
  	 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;
  
*************** build_unary_op (enum tree_code code, tre
*** 4087,4093 ****
  	       expression so we can just form an ADDR_EXPR with the
  	       correct type.  */
  	    || processing_template_decl)
! 	  addr = build_address (arg);
  	else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
  	  {
  	    tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
--- 4071,4081 ----
  	       expression so we can just form an ADDR_EXPR with the
  	       correct type.  */
  	    || processing_template_decl)
! 	  {
! 	    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));
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/non-dependent11.C gcc-main-new/gcc/testsuite/g++.dg/template/non-dependent11.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/non-dependent11.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/non-dependent11.C	Sun Jan 16 23:04:04 2005
***************
*** 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); 
+ }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]