[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 Alexandre Oliva changed: What|Removed |Added Status|ASSIGNED|RESOLVED Resolution|--- |FIXED --- Comment #6 from Alexandre Oliva --- Fixed
[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 --- Comment #5 from Alexandre Oliva --- Author: aoliva Date: Tue Mar 6 06:25:12 2018 New Revision: 258271 URL: https://gcc.gnu.org/viewcvs?rev=258271=gcc=rev Log: [C++] [PR84231] overload on cond_expr in template A non-type-dependent COND_EXPR within a template is reconstructed with the original operands, after one with non-dependent proxies is built to determine its result type. This is problematic because the operands of a COND_EXPR determined to be an rvalue may have been converted to denote their rvalue nature. The reconstructed one, however, won't have such conversions, so lvalue_kind may not recognize it as an rvalue, which may lead to e.g. incorrect overload resolution decisions. If we mistake such a COND_EXPR for an lvalue, overload resolution might regard a conversion sequence that binds it to a non-const reference as viable, and then select that over one that binds it to a const reference. Only after template substitution would we rebuild the COND_EXPR, realize it is an rvalue, and conclude the reference binding is ill-formed, but at that point we'd have long discarded any alternate candidates we could have used. This patch modifies the logic that determines whether a (non-type-dependent) COND_EXPR in a template is an lvalue, to rely on its type, more specifically, on the presence of a REFERENCE_TYPE wrapper. In order to avoid a type bootstrapping problem, the REFERENCE_TYPE that wraps the type of some such COND_EXPRs is introduced earlier, so that we don't have to test for lvalueness of the expression using the very code that we wish to change. for gcc/cp/ChangeLog PR c++/84231 * tree.c (lvalue_kind): Use presence/absence of REFERENCE_TYPE only while processing template decls. * typeck.c (build_x_conditional_expr): Move wrapping of reference type around type... * call.c (build_conditional_expr_1): ... here. Rename is_lvalue to is_glvalue. * parser.c (cp_parser_fold_expression): Catch REFERENCE_REF_P INDIRECT_REF of COND_EXPR too. for gcc/testsuite/ChangeLog PR c++/84231 * g++.dg/pr84231.C: New. Added: trunk/gcc/testsuite/g++.dg/pr84231.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/call.c trunk/gcc/cp/parser.c trunk/gcc/cp/tree.c trunk/gcc/cp/typeck.c trunk/gcc/testsuite/ChangeLog
[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 Alexandre Oliva changed: What|Removed |Added Status|NEW |ASSIGNED --- Comment #4 from Alexandre Oliva --- Patch posted: https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00478.html
[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 --- Comment #3 from Alexandre Oliva --- The difference arises because, when resolving the % overload in normal_function, the result operands of the ternary operator have gained rvalue-forcing NOP_EXPRs, which makes their lvalue_kind clk_none, so the ref-binding is a bad conversion and the non-const template is not viable, but within function_template, the rvalue-forcing casts aren't there, so lvalue_kind for the ternary operator results is clk_ordinary, and reference_binding is regarded as acceptable, and so both operator%s are viable, and the one without const is later selected as a better match. I suppose the parsing of the ternary operator should behave the same way, given that nothing is dependent in the expression. But when processing_template_decl, build_x_conditional_expr creates a COND_EXPR node with the original operands. Oops.
[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 Alexandre Oliva changed: What|Removed |Added CC||aoliva at gcc dot gnu.org Assignee|unassigned at gcc dot gnu.org |aoliva at gcc dot gnu.org --- Comment #2 from Alexandre Oliva --- Mine
[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84231 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2018-02-06 CC||nathan at gcc dot gnu.org Target Milestone|--- |8.0 Ever confirmed|0 |1 --- Comment #1 from Jonathan Wakely --- Bisection suggests r255605 although it doesn't look very relevant.