Ping.
On Thu, Sep 05, 2019 at 10:24:55PM -0400, Marek Polacek wrote: > Compiling this testcase results in a bogus "invalid cast" error; this occurs > since the introduction of location wrappers in finish_id_expression. > > Here we are parsing the decltype expression via cp_parser_decltype_expr which > can lead to calling various fold_* and c-family routines. They use > non_lvalue_loc, but that won't create a NON_LVALUE_EXPR wrapper around a > location > wrapper. > > So before the location wrappers addition cp_parser_decltype_expr would return > NON_LVALUE_EXPR <c>. Now it returns VIEW_CONVERT_EXPR<float *>(c), but the > STRIP_ANY_LOCATION_WRAPPER immediately following it strips the location > wrapper, > and suddenly we don't know whether we have an lvalue anymore. And that's sad > because then decltype produces the wrong type, causing nonsense errors. > > Bootstrapped/regtested on x86_64-linux, ok for trunk and 9? > > 2019-09-05 Marek Polacek <pola...@redhat.com> > > PR c++/91678 - wrong error with decltype and location wrapper. > * parser.c (cp_parser_decltype): Use auto_suppress_location_wrappers > sentinel. Don't strip location wrappers. > > * g++.dg/cpp0x/decltype73.C: New test. > > diff --git gcc/cp/parser.c gcc/cp/parser.c > index baa60b8834e..b3c7bff5988 100644 > --- gcc/cp/parser.c > +++ gcc/cp/parser.c > @@ -14729,8 +14729,13 @@ cp_parser_decltype (cp_parser *parser) > /* Do not warn about problems with the expression. */ > ++c_inhibit_evaluation_warnings; > > + /* Don't create wrapper nodes within decltype. non_lvalue_loc won't > + create a NON_LVALUE_EXPR wrapper around a location wrapper, and a > + subsequent STRIP_ANY_LOCATION_WRAPPER would destroy the information > + about lvalueness of the expression. */ > + auto_suppress_location_wrappers sentinel; > + > expr = cp_parser_decltype_expr (parser, > id_expression_or_member_access_p); > - STRIP_ANY_LOCATION_WRAPPER (expr); > > /* Go back to evaluating expressions. */ > --cp_unevaluated_operand; > diff --git gcc/testsuite/g++.dg/cpp0x/decltype73.C > gcc/testsuite/g++.dg/cpp0x/decltype73.C > new file mode 100644 > index 00000000000..cbe94a898e3 > --- /dev/null > +++ gcc/testsuite/g++.dg/cpp0x/decltype73.C > @@ -0,0 +1,4 @@ > +// PR c++/91678 - wrong error with decltype and location wrapper. > +// { dg-do compile { target c++11 } } > + > +float* test(float* c) { return (decltype(c + 0))(float*)c; }