]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: noexcept-spec from nested class confusion [PR109761]
authorPatrick Palka <ppalka@redhat.com>
Tue, 9 May 2023 19:06:34 +0000 (15:06 -0400)
committerPatrick Palka <ppalka@redhat.com>
Tue, 9 May 2023 19:06:34 +0000 (15:06 -0400)
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.

gcc/cp/parser.cc
gcc/testsuite/g++.dg/cpp0x/noexcept78.C [new file with mode: 0644]

index d89553e7da81d64a6390c385e009b4ff07b5da58..7f4bc0f468ed8351b8f1a63cc73be6594c59c054 100644 (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 *);
@@ -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 (file)
index 0000000..e8156eb
--- /dev/null
@@ -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();
+};
+