From: ppalka Date: Wed, 13 Apr 2016 00:06:51 +0000 (+0000) Subject: Fix PR c++/70610 (wrong overload resolution during template processing) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=9231d5c2e59de6dee624da919cef6c570e02b798;p=thirdparty%2Fgcc.git 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@234926 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 823ab1110ab3..5696eea0e7eb 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 5d9de344e7c8..df2981fd3f42 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 9e61090f57bf..cef5604bd0b4 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 56527dba2fe5..75c4fa810ccb 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 000000000000..3368a5e5d892 --- /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 000000000000..4be458cca59a --- /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 000000000000..127abdc44e36 --- /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 000000000000..c7dde1c5cec2 --- /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 (); +}