public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: gcc-patches@gcc.gnu.org
Cc: Patrick Palka <ppalka@redhat.com>
Subject: [pushed] c++: array DMI and member fn [PR109666]
Date: Mon,  1 May 2023 16:54:54 -0400	[thread overview]
Message-ID: <20230501205454.1627105-1-jason@redhat.com> (raw)

Tested x86_64-pc-linux-gnu, applying to trunk.

Patrick, can you verify that this resolves 109506 and add whatever testcase(s)
seem appropriate from that PR?

-- 8< --

Here it turns out I also needed to adjust cfun when stepping out of the
member function to instantiate the DMI.  But instead of adding that tweak,
let's unify with instantiate_body and just push_to_top_level instead of
trying to do the minimum subset of it.  There was no measurable change in
compile time on stdc++.h.

This should also resolve 109506 without yet another tweak.

	PR c++/109666

gcc/cp/ChangeLog:

	* name-lookup.cc (maybe_push_to_top_level)
	(maybe_pop_from_top_level): Split out...
	* pt.cc (instantiate_body): ...from here.
	* init.cc (maybe_instantiate_nsdmi_init): Use them.
	* name-lookup.h: Declare them..

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/nsdmi-array2.C: New test.
---
 gcc/cp/name-lookup.h                      |  2 ++
 gcc/cp/init.cc                            | 25 ++-------------
 gcc/cp/name-lookup.cc                     | 37 +++++++++++++++++++++++
 gcc/cp/pt.cc                              | 20 ++----------
 gcc/testsuite/g++.dg/cpp0x/nsdmi-array2.C | 15 +++++++++
 5 files changed, 58 insertions(+), 41 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/nsdmi-array2.C

diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index c234cd44356..b3e708561d8 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -466,6 +466,8 @@ extern void push_nested_namespace (tree);
 extern void pop_nested_namespace (tree);
 extern void push_to_top_level (void);
 extern void pop_from_top_level (void);
+extern bool maybe_push_to_top_level (tree);
+extern void maybe_pop_from_top_level (bool);
 extern void push_using_decl_bindings (tree, tree);
 
 /* Lower level interface for modules. */
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 1dd24e30d7c..0b35e1092e9 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -597,32 +597,14 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
 	  bool pushed = false;
 	  tree ctx = type_context_for_name_lookup (member);
 
-	  processing_template_decl_sentinel ptds (/*reset*/false);
+	  bool push_to_top = maybe_push_to_top_level (member);
 	  if (!currently_open_class (ctx))
 	    {
-	      if (!LOCAL_CLASS_P (ctx))
-		push_to_top_level ();
-	      else
-		/* push_to_top_level would lose the necessary function context,
-		   just reset processing_template_decl.  */
-		processing_template_decl = 0;
 	      push_nested_class (ctx);
 	      push_deferring_access_checks (dk_no_deferred);
 	      pushed = true;
 	    }
 
-	  /* If we didn't push_to_top_level, still step out of constructor
-	     scope so build_base_path doesn't try to use its __in_chrg.  */
-	  tree cfd = current_function_decl;
-	  auto cbl = current_binding_level;
-	  if (at_function_scope_p ())
-	    {
-	      current_function_decl
-		= decl_function_context (current_function_decl);
-	      while (current_binding_level->kind != sk_class)
-		current_binding_level = current_binding_level->level_chain;
-	    }
-
 	  inject_this_parameter (ctx, TYPE_UNQUALIFIED);
 
 	  start_lambda_scope (member);
@@ -639,15 +621,12 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
 	  if (init != error_mark_node)
 	    DECL_INITIAL (member) = init;
 
-	  current_function_decl = cfd;
-	  current_binding_level = cbl;
 	  if (pushed)
 	    {
 	      pop_deferring_access_checks ();
 	      pop_nested_class ();
-	      if (!LOCAL_CLASS_P (ctx))
-		pop_from_top_level ();
 	    }
+	  maybe_pop_from_top_level (push_to_top);
 
 	  input_location = sloc;
 	}
diff --git a/gcc/cp/name-lookup.cc b/gcc/cp/name-lookup.cc
index 477cddd7543..7c61bc3bf61 100644
--- a/gcc/cp/name-lookup.cc
+++ b/gcc/cp/name-lookup.cc
@@ -8236,6 +8236,43 @@ pop_from_top_level (void)
   free_saved_scope = s;
 }
 
+/* Like push_to_top_level, but not if D is function-local.  Returns whether we
+   did push to top.  */
+
+bool
+maybe_push_to_top_level (tree d)
+{
+  /* Push if D isn't function-local, or is a lambda function, for which name
+     resolution is already done.  */
+  bool push_to_top
+    = !(current_function_decl
+	&& !LAMBDA_FUNCTION_P (d)
+	&& decl_function_context (d) == current_function_decl);
+
+  if (push_to_top)
+    push_to_top_level ();
+  else
+    {
+      gcc_assert (!processing_template_decl);
+      push_function_context ();
+      cp_unevaluated_operand = 0;
+      c_inhibit_evaluation_warnings = 0;
+    }
+
+  return push_to_top;
+}
+
+/* Return from whatever maybe_push_to_top_level did.  */
+
+void
+maybe_pop_from_top_level (bool push_to_top)
+{
+  if (push_to_top)
+    pop_from_top_level ();
+  else
+    pop_function_context ();
+}
+
 /* Push into the scope of the namespace NS, even if it is deeply
    nested within another namespace.  */
 
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 6df16fef0dd..3f1cf139bbd 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -26815,20 +26815,7 @@ instantiate_body (tree pattern, tree args, tree d, bool nested_p)
   if (current_function_decl)
     save_omp_privatization_clauses (omp_privatization_save);
 
-  bool push_to_top
-    = !(current_function_decl
-	&& !LAMBDA_FUNCTION_P (d)
-	&& decl_function_context (d) == current_function_decl);
-
-  if (push_to_top)
-    push_to_top_level ();
-  else
-    {
-      gcc_assert (!processing_template_decl);
-      push_function_context ();
-      cp_unevaluated_operand = 0;
-      c_inhibit_evaluation_warnings = 0;
-    }
+  bool push_to_top = maybe_push_to_top_level (d);
 
   mark_template_arguments_used (pattern, args);
 
@@ -26942,10 +26929,7 @@ instantiate_body (tree pattern, tree args, tree d, bool nested_p)
   if (!nested_p)
     TI_PENDING_TEMPLATE_FLAG (DECL_TEMPLATE_INFO (d)) = 0;
 
-  if (push_to_top)
-    pop_from_top_level ();
-  else
-    pop_function_context ();
+  maybe_pop_from_top_level (push_to_top);
 
   if (current_function_decl)
     restore_omp_privatization_clauses (omp_privatization_save);
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-array2.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array2.C
new file mode 100644
index 00000000000..5ad60f56510
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-array2.C
@@ -0,0 +1,15 @@
+// PR c++/109666
+// { dg-do compile { target c++11 } }
+
+struct Point {
+  int value_;
+};
+template <int n> struct StaticVector {
+  static StaticVector create() {
+    StaticVector output;
+    return output;
+  }
+  Point _M_elems[n]{};
+
+};
+void f() { StaticVector<3>::create(); }

base-commit: 14e881eb0305090e5b184806b917d492373d32ea
-- 
2.31.1


             reply	other threads:[~2023-05-01 20:55 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-05-01 20:54 Jason Merrill [this message]
2023-12-19 19:08 ` Patrick Palka
2023-12-19 19:47   ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230501205454.1627105-1-jason@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=ppalka@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).