I'm not 100% sure this is the correct approach, or whether I've picked
the right sense of "dependent" to check here; any thoughts?

Bootstrapped and regtested on x86_64-pc-linux-gnu, OK for trunk?

-- >8 --

When finding the minimal visibility of a template, any reference to a
dependent local variable will cause the instantiation to be marked as
internal linkage.  However, when processing the template decl we don't
yet know whether that should actually be the case, as a given
instantiation may not require referencing the local decl in its
mangling.  So this patch bails on dependent declarations.

        PR c++/122253

gcc/cp/ChangeLog:

        * decl2.cc (min_vis_expr_r): Don't mark as VISIBILITY_ANON for a
        !TREE_PUBLIC dependent decl.

gcc/testsuite/ChangeLog:

        * g++.dg/modules/internal-16.C: New test.

Signed-off-by: Nathaniel Shead <[email protected]>
---
 gcc/cp/decl2.cc                            |  5 ++++-
 gcc/testsuite/g++.dg/modules/internal-16.C | 23 ++++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/g++.dg/modules/internal-16.C

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index 0073f83a10c..572037acd38 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2885,7 +2885,10 @@ min_vis_expr_r (tree *tp, int */*walk_subtrees*/, void 
*data)
          break;
        }
     addressable:
-      if (! TREE_PUBLIC (t))
+      if (!TREE_PUBLIC (t)
+         /* We don't really know whether a use of a dependent decl will
+            actually appear in our mangling.  */
+         && !dependent_type_p (TREE_TYPE (t)))
        tpvis = VISIBILITY_ANON;
       else
        tpvis = DECL_VISIBILITY (t);
diff --git a/gcc/testsuite/g++.dg/modules/internal-16.C 
b/gcc/testsuite/g++.dg/modules/internal-16.C
new file mode 100644
index 00000000000..a891082cc1b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/internal-16.C
@@ -0,0 +1,23 @@
+// PR c++/122253
+// { dg-additional-options "-fmodules -Wtemplate-names-tu-local" }
+
+export module M;
+
+template <int> struct ic {};
+struct S { constexpr operator int() const { return 42; } };
+
+template <typename T> inline void a(T) {
+  T s;
+  ic<s>{};
+}
+
+template <typename T> inline auto b(T x) {
+  return [&](auto y) {
+    return [=](auto z) {
+      return ic<(int)x + (int)y + (int)z>{};
+    };
+  };
+}
+
+template void a(S);
+ic<42 * 3> x = b(S{})(S{})(S{});
-- 
2.51.0

Reply via email to