https://gcc.gnu.org/g:e60032b382364897a58e67994baac896bcd03327

commit r15-310-ge60032b382364897a58e67994baac896bcd03327
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Tue Apr 30 22:29:57 2024 +1000

    c++/modules: Stream unmergeable temporaries by value again [PR114856]
    
    In r14-9266-g2823b4d96d9ec4 I gave all temporary vars a DECL_CONTEXT,
    including those at namespace or global scope, so that they could be
    properly merged across importers.  However, not all of these temporary
    vars are actually supposed to be mergeable.
    
    For instance, in the attached testcase we have an unnamed temporary var
    used in the NSDMI of a class member, which cannot properly merged -- but
    it also doesn't need to be, as it'll be thrown away when the class type
    itself is merged anyway.
    
    This patch reverts the change made above and instead makes a weaker
    adjustment that only causes temporary vars with linkage have a
    DECL_CONTEXT to merge from.  This way these unnamed, "unmergeable"
    temporaries are properly streamed by value again.
    
            PR c++/114856
    
    gcc/cp/ChangeLog:
    
            * call.cc (make_temporary_var_for_ref_to_temp): Set context for
            temporaries with linkage.
            * init.cc (create_temporary_var): Revert to only set context
            when in a function decl.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/pr114856.h: New test.
            * g++.dg/modules/pr114856_a.H: New test.
            * g++.dg/modules/pr114856_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
    Reviewed-by: Jason Merrill <ja...@redhat.com>
    Reviewed-by: Patrick Palka <ppa...@redhat.com>

Diff:
---
 gcc/cp/call.cc                            |  3 +++
 gcc/cp/init.cc                            |  2 +-
 gcc/testsuite/g++.dg/modules/pr114856.h   | 12 ++++++++++++
 gcc/testsuite/g++.dg/modules/pr114856_a.H |  5 +++++
 gcc/testsuite/g++.dg/modules/pr114856_b.C |  5 +++++
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 7c4ecf08c4bd..e058da7735fa 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -13802,6 +13802,9 @@ make_temporary_var_for_ref_to_temp (tree decl, tree 
type)
       tree name = mangle_ref_init_variable (decl);
       DECL_NAME (var) = name;
       SET_DECL_ASSEMBLER_NAME (var, name);
+
+      /* Set the context to make the variable mergeable in modules.  */
+      DECL_CONTEXT (var) = current_scope ();
     }
   else
     /* Create a new cleanup level if necessary.  */
diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc
index c1b5b7425c9b..7bb98f445c37 100644
--- a/gcc/cp/init.cc
+++ b/gcc/cp/init.cc
@@ -4287,7 +4287,7 @@ create_temporary_var (tree type)
   TREE_USED (decl) = 1;
   DECL_ARTIFICIAL (decl) = 1;
   DECL_IGNORED_P (decl) = 1;
-  DECL_CONTEXT (decl) = current_scope ();
+  DECL_CONTEXT (decl) = current_function_decl;
 
   return decl;
 }
diff --git a/gcc/testsuite/g++.dg/modules/pr114856.h 
b/gcc/testsuite/g++.dg/modules/pr114856.h
new file mode 100644
index 000000000000..b1a3c2cd8341
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr114856.h
@@ -0,0 +1,12 @@
+// PR c++/114856
+
+#include <initializer_list>
+struct A {
+  ~A();
+};
+struct V {
+  V(std::initializer_list<A>);
+};
+struct data {
+  V v{{}};
+};
diff --git a/gcc/testsuite/g++.dg/modules/pr114856_a.H 
b/gcc/testsuite/g++.dg/modules/pr114856_a.H
new file mode 100644
index 000000000000..6195277dbde1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr114856_a.H
@@ -0,0 +1,5 @@
+// PR c++/114856
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+#include "pr114856.h"
diff --git a/gcc/testsuite/g++.dg/modules/pr114856_b.C 
b/gcc/testsuite/g++.dg/modules/pr114856_b.C
new file mode 100644
index 000000000000..f81dc8b81d5d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr114856_b.C
@@ -0,0 +1,5 @@
+// PR c++/114856
+// { dg-additional-options "-fmodules-ts" }
+
+#include "pr114856.h"
+import "pr114856_a.H";

Reply via email to