This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH for 3.4/4.0] Fix PR19311 (ICE overload resolutionfor pmf function argument)
- From: Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot net>
- To: Mark Mitchell <mark at codesourcery dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Thu, 20 Jan 2005 21:57:23 +0700
- Subject: Re: [C++ PATCH for 3.4/4.0] Fix PR19311 (ICE overload resolutionfor pmf function argument)
- References: <41EBCDD1.6000706@users.sf.net> <41ED70DD.9080402@codesourcery.com>
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);
+ }