Message ID | 20230509163502.3746600-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: noexcept-spec from nested class confusion [PR109761] | expand |
On 5/9/23 12:35, Patrick Palka wrote: > When processing a noexcept-spec from a nested class after completion of > the outer class (since a noexcept-spec is a complete-class context), we > pass 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. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this looK OK > for trunk and release branches? OK. > PR c++/109761 > > gcc/cp/ChangeLog: > > * parser.cc (cp_parser_class_specifier): Adjust call 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. > --- > gcc/cp/parser.cc | 13 ++++++------- > gcc/testsuite/g++.dg/cpp0x/noexcept78.C | 16 ++++++++++++++++ > 2 files changed, 22 insertions(+), 7 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp0x/noexcept78.C > > diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc > index d89553e7da8..7f4bc0f468e 100644 > --- a/gcc/cp/parser.cc > +++ b/gcc/cp/parser.cc > @@ -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 *); > @@ -26458,7 +26458,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 (); > @@ -28240,14 +28240,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)) > diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept78.C b/gcc/testsuite/g++.dg/cpp0x/noexcept78.C > new file mode 100644 > index 00000000000..e8156eb7c6f > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept78.C > @@ -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(); > +}; > +
diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index d89553e7da8..7f4bc0f468e 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -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 *); @@ -26458,7 +26458,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 (); @@ -28240,14 +28240,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)) diff --git a/gcc/testsuite/g++.dg/cpp0x/noexcept78.C b/gcc/testsuite/g++.dg/cpp0x/noexcept78.C new file mode 100644 index 00000000000..e8156eb7c6f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/noexcept78.C @@ -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(); +}; +