]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Standard mangling abbreviations & modules
authorNathan Sidwell <nathan@acm.org>
Thu, 3 Mar 2022 00:42:23 +0000 (19:42 -0500)
committerNathan Sidwell <nathan@acm.org>
Fri, 4 Mar 2022 19:59:28 +0000 (14:59 -0500)
The std manglings for things like std::string should not apply if
we're not in the global module.

gcc/cp/
* mangle.cc (is_std_substitution): Check global module.
(is_std_substitution_char): Return bool.
gcc/testsuite/
* g++.dg/modules/std-subst-2.C: New.
* g++.dg/modules/std-subst-3.C: New.
* g++.dg/modules/std-subst-4_a.C: New.
* g++.dg/modules/std-subst-4_b.C: New.
* g++.dg/modules/std-subst-4_c.C: New.

gcc/cp/mangle.cc
gcc/testsuite/g++.dg/modules/std-subst-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/std-subst-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/std-subst-4_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/std-subst-4_b.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/std-subst-4_c.C [new file with mode: 0644]

index 6657ce4d983447c53017264766cdfd9d34fc5e57..dbcec0a55bc3ff230185bfcc43f99f4f89776827 100644 (file)
@@ -180,9 +180,9 @@ static tree maybe_template_info (const tree);
 
 static inline tree canonicalize_for_substitution (tree);
 static void add_substitution (tree);
-static inline int is_std_substitution (const tree,
+static inline bool is_std_substitution (const tree,
                                       const substitution_identifier_index_t);
-static inline int is_std_substitution_char (const tree,
+static inline bool is_std_substitution_char (const tree,
                                            const substitution_identifier_index_t);
 static int find_substitution (tree);
 static void mangle_call_offset (const tree, const tree);
@@ -467,9 +467,10 @@ add_substitution (tree node)
 
 /* Helper function for find_substitution.  Returns nonzero if NODE,
    which may be a decl or a CLASS_TYPE, is a template-id with template
-   name of substitution_index[INDEX] in the ::std namespace.  */
+   name of substitution_index[INDEX] in the ::std namespace, with
+   global module attachment.  */
 
-static inline int
+static bool
 is_std_substitution (const tree node,
                     const substitution_identifier_index_t index)
 {
@@ -488,13 +489,22 @@ is_std_substitution (const tree node,
     }
   else
     /* These are not the droids you're looking for.  */
-    return 0;
+    return false;
+
+  if (!DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl)))
+    return false;
+
+  if (!(TYPE_LANG_SPECIFIC (type) && TYPE_TEMPLATE_INFO (type)))
+    return false;
 
-  return (DECL_NAMESPACE_STD_P (CP_DECL_CONTEXT (decl))
-         && TYPE_LANG_SPECIFIC (type)
-         && TYPE_TEMPLATE_INFO (type)
-         && (DECL_NAME (TYPE_TI_TEMPLATE (type))
-             == subst_identifiers[index]));
+  tree tmpl = TYPE_TI_TEMPLATE (type);
+  if (DECL_NAME (tmpl) != subst_identifiers[index])
+    return false;
+
+  if (modules_p () && get_originating_module (tmpl, true) >= 0)
+    return false;
+
+  return true;
 }
 
 /* Return the ABI tags (the TREE_VALUE of the "abi_tag" attribute entry) for T,
@@ -526,7 +536,7 @@ get_abi_tags (tree t)
    ::std::identifier<char>, where identifier is
    substitution_index[INDEX].  */
 
-static inline int
+static bool
 is_std_substitution_char (const tree node,
                          const substitution_identifier_index_t index)
 {
diff --git a/gcc/testsuite/g++.dg/modules/std-subst-2.C b/gcc/testsuite/g++.dg/modules/std-subst-2.C
new file mode 100644 (file)
index 0000000..e7c7706
--- /dev/null
@@ -0,0 +1,13 @@
+// { dg-additional-options "-fmodules-ts" }
+export module FOO;
+// { dg-module-cmi FOO }
+namespace Outer {
+class Y;
+class Inner {
+  class X;
+  void Fn (X &, Y &); // #2
+};
+void Inner::Fn (X &, Y &) {}
+}
+
+// { dg-final { scan-assembler {_ZN5OuterW3FOO5Inner2FnERNS1_1XERNS_S0_1YE:} } }
diff --git a/gcc/testsuite/g++.dg/modules/std-subst-3.C b/gcc/testsuite/g++.dg/modules/std-subst-3.C
new file mode 100644 (file)
index 0000000..75b81ac
--- /dev/null
@@ -0,0 +1,34 @@
+// { dg-additional-options "-fmodules-ts -Wno-pedantic" }
+
+module;
+# 5 __FILE__ 1
+class Pooh;
+class Piglet;
+# 8 "" 2
+
+export module std; // might happen, you can't say it won't!
+// { dg-module-cmi std }
+
+namespace std {
+export template<typename T> class allocator {
+// just for testing, not real!
+void M (T *);
+template <typename U> U *N (T *);
+};
+
+template<typename T> void allocator<T>::M (T *) {}
+template<typename T> template<typename U> U *allocator<T>::N (T *) {
+return nullptr;
+}
+
+template void allocator<int>::M (int *);
+template float *allocator<int>::N<float> (int *);
+}
+
+template void std::allocator<Pooh>::M (Pooh *);
+template Piglet *std::allocator<Pooh>::N<Piglet> (Pooh *);
+
+// { dg-final { scan-assembler {_ZNStW3std9allocatorIiE1MEPi:} } }
+// { dg-final { scan-assembler {_ZNStW3std9allocatorIiE1NIfEEPT_Pi:} } }
+// { dg-final { scan-assembler {_ZNStW3std9allocatorI4PoohE1MEPS1_:} } }
+// { dg-final { scan-assembler {_ZNStW3std9allocatorI4PoohE1NI6PigletEEPT_PS1_:} } }
diff --git a/gcc/testsuite/g++.dg/modules/std-subst-4_a.C b/gcc/testsuite/g++.dg/modules/std-subst-4_a.C
new file mode 100644 (file)
index 0000000..d7520f4
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-additional-options "-fmodules-ts -Wno-pedantic" }
+
+module;
+# 5 __FILE__ 1
+namespace std {
+template <typename A> struct allocator {};
+template <typename C, typename T, typename A>
+class basic_string;
+} // namespace std
+# 12 "" 2
+export module RenameString;
+// { dg-module-cmi RenameString }
+export template <typename C, typename T>
+using str = std::basic_string<C, T, std::allocator<C>>;
diff --git a/gcc/testsuite/g++.dg/modules/std-subst-4_b.C b/gcc/testsuite/g++.dg/modules/std-subst-4_b.C
new file mode 100644 (file)
index 0000000..5bea86f
--- /dev/null
@@ -0,0 +1,14 @@
+// { dg-additional-options -fmodules-ts }
+
+export module Foo;
+// { dg-module-cmi Foo }
+import RenameString;
+
+namespace std {
+template <typename T> struct char_traits {};
+} // namespace std
+
+// use Sb mangling, not Ss as this is not global-module std::char_traits.
+// { dg-final { scan-assembler {_ZW3Foo1fRSbIcStS_11char_traitsIcESaIcEE:} } }
+void f(str<char, std::char_traits<char>> &s) {
+}
diff --git a/gcc/testsuite/g++.dg/modules/std-subst-4_c.C b/gcc/testsuite/g++.dg/modules/std-subst-4_c.C
new file mode 100644 (file)
index 0000000..21beb9b
--- /dev/null
@@ -0,0 +1,16 @@
+// { dg-additional-options "-fmodules-ts -Wno-pedantic" }
+module;
+# 5 __FILE__ 1
+namespace std {
+template <typename A> struct char_traits {};
+} // namespace std
+# 9 "" 2
+export module Bar;
+// { dg-module-cmi Bar }
+import RenameString;
+
+// Use Ss as this is global-module std::char_traits
+void g(str<char, std::char_traits<char>> &s) {
+}
+
+// { dg-final { scan-assembler {_ZW3Bar1gRSs:} } }