[gcc r13-6788] c++: DMI in template with virtual base [PR106890]

Jason Merrill jason@gcc.gnu.org
Tue Mar 21 15:09:09 GMT 2023


https://gcc.gnu.org/g:041a164ec9b467f9ac2f15980f83f17e3f8ea150

commit r13-6788-g041a164ec9b467f9ac2f15980f83f17e3f8ea150
Author: Jason Merrill <jason@redhat.com>
Date:   Sat Mar 18 08:27:26 2023 -0400

    c++: DMI in template with virtual base [PR106890]
    
    When parsing a default member init we just build a CONVERT_EXPR for
    converting to a virtual base, and then expand that into the more complex
    form when we actually use the DMI in a constructor.  But that wasn't working
    for the template case where we are considering the conversion at the point
    that the constructor needs the DMI instantiation, so it seemed like we were
    in a constructor already.  And then when the other constructor tries to
    reuse the instantiation, it sees uses of the first constructor's parameters,
    and dies.  So ensure that we get the CONVERT_EXPR in this case, too.
    
            PR c++/106890
    
    gcc/cp/ChangeLog:
    
            * init.cc (maybe_instantiate_nsdmi_init): Don't leave
            current_function_decl set to a constructor.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp0x/nsdmi-template25.C: New test.

Diff:
---
 gcc/cp/init.cc                                | 14 ++++++++++++++
 gcc/testsuite/g++.dg/cpp0x/nsdmi-template25.C | 18 ++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index 90302372340..c5a55dae563 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -613,6 +613,18 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
 	      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);
@@ -629,6 +641,8 @@ maybe_instantiate_nsdmi_init (tree member, tsubst_flags_t complain)
 	  if (init != error_mark_node)
 	    hash_map_safe_put<hm_ggc> (nsdmi_inst, member, init);
 
+	  current_function_decl = cfd;
+	  current_binding_level = cbl;
 	  if (pushed)
 	    {
 	      pop_deferring_access_checks ();
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-template25.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template25.C
new file mode 100644
index 00000000000..368e745540e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-template25.C
@@ -0,0 +1,18 @@
+// PR c++/106890
+// { dg-do compile { target c++11 } }
+
+struct A
+{
+  int p;
+};
+
+template<typename T>
+struct B : virtual public A
+{
+  B() { }
+  B(int) { }
+
+  int k = this->p;
+};
+
+template struct B<int>;


More information about the Gcc-cvs mailing list