On 2/13/24 20:34, Nathaniel Shead wrote:
On Tue, Feb 13, 2024 at 06:08:42PM -0500, Jason Merrill wrote:
On 2/11/24 08:26, Nathaniel Shead wrote:

Currently inline vars imported from modules aren't correctly finalised,
which means that import_export_decl gets called at the end of TU
processing despite not being meant to for these kinds of declarations.

I disagree that it's not meant to; inline variables are vague linkage just
like template instantiations, so the bug seems to be that import_export_decl
doesn't accept them.  And on the other side, that make_rtl_for_nonlocal_decl
doesn't defer them like instantations.

Jason


True, that's a good point. I think I confused myself here.

Here's a fixed patch that looks a lot cleaner. Bootstrapped and
regtested (so far just dg.exp and modules.exp) on x86_64-pc-linux-gnu,
OK for trunk if full regtest succeeds?

OK.

-- >8 --

Inline variables are vague-linkage, and may or may not need to be
emitted in any TU that they are part of, similarly to e.g. template
instantiations.

Currently 'import_export_decl' assumes that inline variables have
already been emitted when it comes to end-of-TU processing, and so
crashes when importing non-trivially-initialised variables from a
module, as they have not yet been finalised.

This patch fixes this by ensuring that inline variables are always
deferred till end-of-TU processing, unifying the behaviour for module
and non-module code.

        PR c++/113708

gcc/cp/ChangeLog:

        * decl.cc (make_rtl_for_nonlocal_decl): Defer inline variables.
        * decl2.cc (import_export_decl): Support inline variables.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/init-7_a.H: New test.
        * g++.dg/modules/init-7_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
  gcc/cp/decl.cc                          | 4 ++++
  gcc/cp/decl2.cc                         | 7 +++++--
  gcc/testsuite/g++.dg/modules/init-7_a.H | 6 ++++++
  gcc/testsuite/g++.dg/modules/init-7_b.C | 6 ++++++
  4 files changed, 21 insertions(+), 2 deletions(-)
  create mode 100644 gcc/testsuite/g++.dg/modules/init-7_a.H
  create mode 100644 gcc/testsuite/g++.dg/modules/init-7_b.C

diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 3e41fd4fa31..969513c069a 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -7954,6 +7954,10 @@ make_rtl_for_nonlocal_decl (tree decl, tree init, const 
char* asmspec)
        && DECL_IMPLICIT_INSTANTIATION (decl))
      defer_p = 1;
+ /* Defer vague-linkage variables. */
+  if (DECL_INLINE_VAR_P (decl))
+    defer_p = 1;
+
    /* If we're not deferring, go ahead and assemble the variable.  */
    if (!defer_p)
      rest_of_decl_compilation (decl, toplev, at_eof);
diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index f569d4045ec..1dddbaab38b 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -3360,7 +3360,9 @@ import_export_decl (tree decl)
* implicit instantiations of function templates - * inline function
+     * inline functions
+
+     * inline variables
* implicit instantiations of static data members of class
         templates
@@ -3383,6 +3385,7 @@ import_export_decl (tree decl)
                || DECL_DECLARED_INLINE_P (decl));
    else
      gcc_assert (DECL_IMPLICIT_INSTANTIATION (decl)
+               || DECL_INLINE_VAR_P (decl)
                || DECL_VTABLE_OR_VTT_P (decl)
                || DECL_TINFO_P (decl));
    /* Check that a definition of DECL is available in this translation
@@ -3511,7 +3514,7 @@ import_export_decl (tree decl)
           this entity as undefined in this translation unit.  */
        import_p = true;
      }
-  else if (DECL_FUNCTION_MEMBER_P (decl))
+  else if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (decl))
      {
        if (!DECL_DECLARED_INLINE_P (decl))
        {
diff --git a/gcc/testsuite/g++.dg/modules/init-7_a.H 
b/gcc/testsuite/g++.dg/modules/init-7_a.H
new file mode 100644
index 00000000000..7a0bb721c30
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/init-7_a.H
@@ -0,0 +1,6 @@
+// PR c++/113708
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+inline int f() { return 42; }
+inline int a = f();
diff --git a/gcc/testsuite/g++.dg/modules/init-7_b.C 
b/gcc/testsuite/g++.dg/modules/init-7_b.C
new file mode 100644
index 00000000000..58bb0620ca5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/init-7_b.C
@@ -0,0 +1,6 @@
+// PR c++/113708
+// { dg-module-do link }
+// { dg-additional-options "-fmodules-ts" }
+
+import "init-7_a.H";
+int main() { a; }

Reply via email to