Commit 6439fffd by Kriang Lerdsuwanakij Committed by Kriang Lerdsuwanakij

re PR c++/19311 (ICE in resolve_overloaded_unification)

	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
parent d19e3ef6
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> 2005-03-02 Alexandre Oliva <aoliva@redhat.com>
* name-lookup.c (push_overloaded_decl): Don't error if the new * name-lookup.c (push_overloaded_decl): Don't error if the new
......
...@@ -1417,14 +1417,6 @@ build_offset_ref (tree type, tree name, bool address_p) ...@@ -1417,14 +1417,6 @@ build_offset_ref (tree type, tree name, bool address_p)
return error_mark_node; 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) if (TREE_CODE (member) == TYPE_DECL)
{ {
TREE_USED (member) = 1; TREE_USED (member) = 1;
......
...@@ -12376,7 +12376,8 @@ build_non_dependent_expr (tree expr) ...@@ -12376,7 +12376,8 @@ build_non_dependent_expr (tree expr)
if (TREE_CODE (inner_expr) == OVERLOAD if (TREE_CODE (inner_expr) == OVERLOAD
|| TREE_CODE (inner_expr) == FUNCTION_DECL || TREE_CODE (inner_expr) == FUNCTION_DECL
|| TREE_CODE (inner_expr) == TEMPLATE_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; return expr;
/* There is no need to return a proxy for a variable. */ /* There is no need to return a proxy for a variable. */
if (TREE_CODE (expr) == VAR_DECL) if (TREE_CODE (expr) == VAR_DECL)
......
...@@ -3530,23 +3530,6 @@ build_x_unary_op (enum tree_code code, tree xarg) ...@@ -3530,23 +3530,6 @@ build_x_unary_op (enum tree_code code, tree xarg)
if (type_dependent_expression_p (xarg)) if (type_dependent_expression_p (xarg))
return build_min_nt (code, xarg, NULL_TREE); 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); xarg = build_non_dependent_expr (xarg);
} }
...@@ -3610,13 +3593,13 @@ build_x_unary_op (enum tree_code code, tree xarg) ...@@ -3610,13 +3593,13 @@ build_x_unary_op (enum tree_code code, tree xarg)
else if (TREE_CODE (xarg) == TARGET_EXPR) else if (TREE_CODE (xarg) == TARGET_EXPR)
warning ("taking address of temporary"); warning ("taking address of temporary");
exp = build_unary_op (ADDR_EXPR, xarg, 0); 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) if (processing_template_decl && exp != error_mark_node)
return build_min_non_dep (code, exp, orig_expr, exp = build_min_non_dep (code, exp, orig_expr,
/*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE); /*For {PRE,POST}{INC,DEC}REMENT_EXPR*/NULL_TREE);
if (TREE_CODE (exp) == ADDR_EXPR)
PTRMEM_OK_P (exp) = ptrmem;
return exp; return exp;
} }
...@@ -4056,6 +4039,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) ...@@ -4056,6 +4039,7 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
is an error. */ is an error. */
else if (TREE_CODE (argtype) != FUNCTION_TYPE else if (TREE_CODE (argtype) != FUNCTION_TYPE
&& TREE_CODE (argtype) != METHOD_TYPE && TREE_CODE (argtype) != METHOD_TYPE
&& TREE_CODE (arg) != OFFSET_REF
&& !lvalue_or_else (arg, lv_addressof)) && !lvalue_or_else (arg, lv_addressof))
return error_mark_node; return error_mark_node;
...@@ -4070,7 +4054,11 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) ...@@ -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 expression so we can just form an ADDR_EXPR with the
correct type. */ correct type. */
|| processing_template_decl) || 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) else if (TREE_CODE (TREE_OPERAND (arg, 1)) == BASELINK)
{ {
tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1)); tree fn = BASELINK_FUNCTIONS (TREE_OPERAND (arg, 1));
......
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> 2005-03-05 Uros Bizjak <uros@kss-loka.si>
* lib/target-supports.exp (check_iconv_available): Fix comment. * lib/target-supports.exp (check_iconv_available): Fix comment.
......
// { 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment