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