From 92886d3e86cb7b2f83cfc9724cb527ab8032aed8 Mon Sep 17 00:00:00 2001 From: Patrick Palka Date: Wed, 13 Apr 2016 00:06:51 +0000 Subject: [PATCH] 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 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/tree.c | 8 +------- gcc/cp/typeck.c | 6 ++---- gcc/testsuite/ChangeLog | 8 ++++++++ gcc/testsuite/g++.dg/template/pr70610-2.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/template/pr70610-3.C | 21 +++++++++++++++++++++ gcc/testsuite/g++.dg/template/pr70610-4.C | 19 +++++++++++++++++++ gcc/testsuite/g++.dg/template/pr70610.C | 21 +++++++++++++++++++++ 8 files changed, 101 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/pr70610-2.C create mode 100644 gcc/testsuite/g++.dg/template/pr70610-3.C create mode 100644 gcc/testsuite/g++.dg/template/pr70610-4.C create mode 100644 gcc/testsuite/g++.dg/template/pr70610.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 823ab1110ab..5696eea0e7e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2016-04-12 Patrick Palka + + 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 * class.c (is_really_empty_class): A zero-length array is empty. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index 5d9de344e7c..df2981fd3f4 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -224,13 +224,7 @@ lvalue_kind (const_tree ref) return lvalue_kind (BASELINK_FUNCTIONS (CONST_CAST_TREE (ref))); case NON_DEPENDENT_EXPR: - /* We just return clk_ordinary for NON_DEPENDENT_EXPR in C++98, but - 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)); + return lvalue_kind (TREE_OPERAND (ref, 0)); default: if (!TREE_TYPE (ref)) diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 9e61090f57b..cef5604bd0b 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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, orig_ifexp, orig_op1, orig_op2); - /* In C++11, remember that the result is an lvalue or xvalue. - In C++98, lvalue_kind can just assume lvalue in a template. */ - if (cxx_dialect >= cxx11 - && lvalue_or_rvalue_with_address_p (expr) + /* Remember that the result is an lvalue or xvalue. */ + if (lvalue_or_rvalue_with_address_p (expr) && !lvalue_or_rvalue_with_address_p (min)) TREE_TYPE (min) = cp_build_reference_type (TREE_TYPE (min), !real_lvalue_p (expr)); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 56527dba2fe..75c4fa810cc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,11 @@ +2016-04-12 Patrick Palka + + 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 * c-c++-common/cilk-plus/SE/ef_error2.c (func2): Use vectorlength diff --git a/gcc/testsuite/g++.dg/template/pr70610-2.C b/gcc/testsuite/g++.dg/template/pr70610-2.C new file mode 100644 index 00000000000..3368a5e5d89 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr70610-2.C @@ -0,0 +1,21 @@ +// 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 +void +foo () +{ + A () + A (); +} + +int +main () +{ + foo (); +} diff --git a/gcc/testsuite/g++.dg/template/pr70610-3.C b/gcc/testsuite/g++.dg/template/pr70610-3.C new file mode 100644 index 00000000000..4be458cca59 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr70610-3.C @@ -0,0 +1,21 @@ +// 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 +void +foo () +{ + bar (a + 1, b + 2); +} + +int +main () +{ + foo (); +} diff --git a/gcc/testsuite/g++.dg/template/pr70610-4.C b/gcc/testsuite/g++.dg/template/pr70610-4.C new file mode 100644 index 00000000000..127abdc44e3 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr70610-4.C @@ -0,0 +1,19 @@ +// PR c++/70610 +// { dg-do link } + +struct A { void operator+ (const A &) { }; }; + +void operator+ (const A &, A &); + +template +void +foo () +{ + A () + A (); +} + +int +main () +{ + foo (); +} diff --git a/gcc/testsuite/g++.dg/template/pr70610.C b/gcc/testsuite/g++.dg/template/pr70610.C new file mode 100644 index 00000000000..c7dde1c5cec --- /dev/null +++ b/gcc/testsuite/g++.dg/template/pr70610.C @@ -0,0 +1,21 @@ +// PR c++/70610 +// { dg-do link } + +struct A { }; + +void operator+ (A &); +void operator+ (const A &) { } + + +template +void +foo () +{ + +A (); +} + +int +main () +{ + foo (); +} -- 2.30.2