[Bug c++/84231] [8 Regression] cannot bind non-const lvalue reference of type ‘const char*&’ to an rvalue of type ‘const char*’

2018-03-05 Thread aoliva at gcc dot gnu.org
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*’

2018-03-05 Thread aoliva at gcc dot gnu.org
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*’

2018-02-08 Thread aoliva at gcc dot gnu.org
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*’

2018-02-07 Thread aoliva at gcc dot gnu.org
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*’

2018-02-07 Thread aoliva at gcc dot gnu.org
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*’

2018-02-06 Thread redi at gcc dot gnu.org
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.