Commit 92886d3e by Patrick Palka

Fix PR c++/70610 (wrong overload resolution during template processing)

gcc/cp/ChangeLog:

	PR c++/70610
	* tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Unconditionally
	recurse into it.
	* typeck.c (build_x_conditional_expr): Unconditionally remember
	that the result is an lvalue or xvalue.

gcc/testsuite/ChangeLog:

	PR c++/70610
	* g++.dg/template/pr70610.C: New test.
	* g++.dg/template/pr70610-2.C: New test.
	* g++.dg/template/pr70610-3.C: New test.
	* g++.dg/template/pr70610-4.C: New test.

From-SVN: r234926
parent d90936ff
2016-04-12 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/70610
* tree.c (lvalue_kind) [NON_DEPENDENT_EXPR]: Unconditionally
recurse into it.
* typeck.c (build_x_conditional_expr): Unconditionally remember
that the result is an lvalue or xvalue.
2016-04-12 Jason Merrill <jason@redhat.com> 2016-04-12 Jason Merrill <jason@redhat.com>
* class.c (is_really_empty_class): A zero-length array is empty. * class.c (is_really_empty_class): A zero-length array is empty.
......
...@@ -224,13 +224,7 @@ lvalue_kind (const_tree ref) ...@@ -224,13 +224,7 @@ lvalue_kind (const_tree ref)
return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref))); return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref)));
case NON_DEPENDENT_EXPR: case NON_DEPENDENT_EXPR:
/* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but return lvalue_kind (TREE_OPERAND (ref, 0));
in C++11 lvalues don't bind to rvalue references, so we need to
work harder to avoid bogus errors (c++/44870). */
if (cxx_dialect < cxx11)
return clk_ordinary;
else
return lvalue_kind (TREE_OPERAND (ref, 0));
default: default:
if (!TREE_TYPE (ref)) if (!TREE_TYPE (ref))
......
...@@ -6275,10 +6275,8 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2, ...@@ -6275,10 +6275,8 @@ build_x_conditional_expr (location_t loc, tree ifexp, tree op1, tree op2,
{ {
tree min = build_min_non_dep (COND_EXPR, expr, tree min = build_min_non_dep (COND_EXPR, expr,
orig_ifexp, orig_op1, orig_op2); orig_ifexp, orig_op1, orig_op2);
/* In C++11, remember that the result is an lvalue or xvalue. /* Remember that the result is an lvalue or xvalue. */
In C++98, lvalue_kind can just assume lvalue in a template. */ if (lvalue_or_rvalue_with_address_p (expr)
if (cxx_dialect >= cxx11
&& lvalue_or_rvalue_with_address_p (expr)
&& !lvalue_or_rvalue_with_address_p (min)) && !lvalue_or_rvalue_with_address_p (min))
TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min), TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min),
!real_lvalue_p (expr)); !real_lvalue_p (expr));
......
2016-04-12 Patrick Palka <ppalka@gcc.gnu.org>
PR c++/70610
* g++.dg/template/pr70610.C: New test.
* g++.dg/template/pr70610-2.C: New test.
* g++.dg/template/pr70610-3.C: New test.
* g++.dg/template/pr70610-4.C: New test.
2016-04-12 Jakub Jelinek <jakub@redhat.com> 2016-04-12 Jakub Jelinek <jakub@redhat.com>
* c-c++-common/cilk-plus/SE/ef_error2.c (func2): Use vectorlength * c-c++-common/cilk-plus/SE/ef_error2.c (func2): Use vectorlength
......
// PR c++/70610
// { dg-do link }
struct A { };
void operator+ (const A &, A &);
void operator+ (A &, const A &);
void operator+ (const A &, const A &) { }
template <typename T>
void
foo ()
{
A () + A ();
}
int
main ()
{
foo<int> ();
}
// PR c++/70610
// { dg-do link }
void bar (const int &, int &);
void bar (int &, const int &);
void bar (const int &, const int &) { }
int a, b;
template <typename T>
void
foo ()
{
bar (a + 1, b + 2);
}
int
main ()
{
foo<int> ();
}
// PR c++/70610
// { dg-do link }
struct A { void operator+ (const A &) { }; };
void operator+ (const A &, A &);
template <typename T>
void
foo ()
{
A () + A ();
}
int
main ()
{
foo<int> ();
}
// PR c++/70610
// { dg-do link }
struct A { };
void operator+ (A &);
void operator+ (const A &) { }
template <typename T>
void
foo ()
{
+A ();
}
int
main ()
{
foo<int> ();
}
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