On 1/21/20 9:08 PM, Marek Polacek wrote:
Here the problem is that if the noexcept specifier is used in the context
of a const member function, const is not considered for the member variables,
leading to a bogus error.  g's const makes its 'this' const, so the first
overload of f should be selected.

In cp_parser_noexcept_specification_opt we inject 'this', but always
unqualified:
25737           if (current_class_type)
25738             inject_this_parameter (current_class_type, TYPE_UNQUALIFIED);
so we need to pass the function's qualifiers down here.  In
cp_parser_direct_declarator it's easy: use the just parsed cv_quals, in
cp_parser_late_noexcept_specifier look at the 'this' parameter to figure it
out.

Bootstrapped/regtested on x86_64-linux, ok for trunk?  Not planning to
backport it to 9, this is not really a regression.

2020-01-21  Marek Polacek  <pola...@redhat.com>

        PR c++/92907 - noexcept does not consider "const" in member functions.
        * parser.c (cp_parser_lambda_declarator_opt): Pass TYPE_UNQUALIFIED
        down to cp_parser_exception_specification_opt.
        (cp_parser_direct_declarator): Pass the function qualifiers to
        cp_parser_exception_specification_opt.
        (cp_parser_class_specifier_1): Pass the function declaration to
        cp_parser_late_noexcept_specifier.
        (cp_parser_late_noexcept_specifier): Add a tree parameter.  Use it to
        pass the qualifiers of the function to
        cp_parser_noexcept_specification_opt.
        (cp_parser_noexcept_specification_opt): New cp_cv_quals parameter.
        Use it in inject_this_parameter.
        (cp_parser_exception_specification_opt): New cp_cv_quals parameter.
        Use it.
        (cp_parser_transaction): Pass TYPE_UNQUALIFIED to
        cp_parser_noexcept_specification_opt.
        (cp_parser_transaction_expression): Likewise.

        * g++.dg/cpp0x/noexcept56.C: New test.
---
  gcc/cp/parser.c                         | 53 +++++++++++++++++--------
  gcc/testsuite/g++.dg/cpp0x/noexcept56.C | 10 +++++
  2 files changed, 46 insertions(+), 17 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept56.C

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index caafbefda8e..e3566f9bd4d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -11008,7 +11008,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, 
tree lambda_expr)
/* Parse optional exception specification. */
        exception_spec
-       = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE);
+       = cp_parser_exception_specification_opt (parser, CP_PARSER_FLAGS_NONE,
+                                                TYPE_UNQUALIFIED);

This seems wrong; a lambda op() is const unless explicitly 'mutable'. A bit further down we have

    quals = (LAMBDA_EXPR_MUTABLE_P (lambda_expr)
             ? TYPE_UNQUALIFIED : TYPE_QUAL_CONST);

You can probably move that up?

Jason

Reply via email to