c++: noexcept-spec from nested class confusion [PR109761]

When late processing a noexcept-spec from a nested class after completion
of the outer class (since it's a complete-class context), we pass the wrong
class context to noexcept_override_late_checks -- the outer class type
instead of the nested class type -- which leads to bogus errors in the
below test.

This patch fixes this by making noexcept_override_late_checks obtain the
class context directly via DECL_CONTEXT instead of via an additional
parameter.

	PR c++/109761

gcc/cp/ChangeLog:

	* parser.cc (cp_parser_class_specifier): Don't pass a class
	context to noexcept_override_late_checks.
	(noexcept_override_late_checks): Remove 'type' parameter
	and use DECL_CONTEXT of 'fndecl' instead.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/noexcept78.C: New test.

(cherry picked from commit c13906f258fb34b3e0c90ddc8d9191dd72f3da0e)
This commit is contained in:
Patrick Palka 2023-05-09 15:06:34 -04:00
parent 986e38bcb0
commit dc399dfe12
2 changed files with 22 additions and 7 deletions

View File

@ -251,7 +251,7 @@ static cp_token_cache *cp_token_cache_new
static tree cp_parser_late_noexcept_specifier
(cp_parser *, tree);
static void noexcept_override_late_checks
(tree, tree);
(tree);
static void cp_parser_initial_pragma
(cp_token *);
@ -26426,7 +26426,7 @@ cp_parser_class_specifier (cp_parser* parser)
/* The finish_struct call above performed various override checking,
but it skipped unparsed noexcept-specifier operands. Now that we
have resolved them, check again. */
noexcept_override_late_checks (type, decl);
noexcept_override_late_checks (decl);
/* Remove any member-function parameters from the symbol table. */
pop_injected_parms ();
@ -28208,14 +28208,13 @@ cp_parser_late_noexcept_specifier (cp_parser *parser, tree default_arg)
}
/* Perform late checking of overriding function with respect to their
noexcept-specifiers. TYPE is the class and FNDECL is the function
that potentially overrides some virtual function with the same
signature. */
noexcept-specifiers. FNDECL is the member function that potentially
overrides some virtual function with the same signature. */
static void
noexcept_override_late_checks (tree type, tree fndecl)
noexcept_override_late_checks (tree fndecl)
{
tree binfo = TYPE_BINFO (type);
tree binfo = TYPE_BINFO (DECL_CONTEXT (fndecl));
tree base_binfo;
if (DECL_STATIC_FUNCTION_P (fndecl))

View File

@ -0,0 +1,16 @@
// PR c++/109761
// { dg-do compile { target c++11 } }
struct base {
virtual void foo() noexcept { }
virtual ~base() { }
};
struct outer : base {
struct nested {
void foo() noexcept(noexcept(g())); // { dg-bogus "looser" }
~nested() noexcept(noexcept(g())); // { dg-bogus "looser" }
};
static void g();
};