[clang] b3c1403 - [clang] Fix std::tm etc. mangling on Solaris (#106353)

via cfe-commits cfe-commits at lists.llvm.org
Mon Oct 7 10:05:29 PDT 2024


Author: Rainer Orth
Date: 2024-10-07T19:05:23+02:00
New Revision: b3c1403dc00a41c8222d4b1dd82cbb7c56fd61ae

URL: https://github.com/llvm/llvm-project/commit/b3c1403dc00a41c8222d4b1dd82cbb7c56fd61ae
DIFF: https://github.com/llvm/llvm-project/commit/b3c1403dc00a41c8222d4b1dd82cbb7c56fd61ae.diff

LOG: [clang] Fix std::tm etc. mangling on Solaris (#106353)

Recently, Solaris bootstrap got broken because Solaris uses a
non-standard mangling of `std::tm` and a few others. This was fixed with
a hack in PR #100724. The Solaris ABI requires mangling `std::tm` as
`tm` and similarly for `std::div_t`, `std::ldiv_t`, and `std::lconv`,
which is what this patch implements. The hack needs to stay in place to
allow building with older versions of `clang`.

Tested on `amd64-pc-solaris2.11`, `sparcv9-sun-solaris2.11` (2-stage
builds with both `clang-19` and `gcc-14` as build compiler), and
`x86_64-pc-linux-gnu`.

Added: 
    clang/test/AST/solaris-tm.cpp

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/Lex/PPMacroExpansion.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 5cc9c8047a70ef..3d03766d55a8aa 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -510,6 +510,10 @@ OpenACC Specific Changes
 Target Specific Changes
 -----------------------
 
+- Clang now implements the Solaris-specific mangling of ``std::tm`` as
+  ``tm``, same for ``std::div_t``, ``std::ldiv_t``, and
+  ``std::lconv``, for Solaris ABI compatibility. (#GH33114)
+
 AMDGPU Support
 ^^^^^^^^^^^^^^
 

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 769a863c2b6764..777cdca1a0c0d7 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -1164,8 +1164,25 @@ void CXXNameMangler::mangleUnscopedName(GlobalDecl GD, const DeclContext *DC,
   //                  ::= St <unqualified-name>   # ::std::
 
   assert(!isa<LinkageSpecDecl>(DC) && "unskipped LinkageSpecDecl");
-  if (isStdNamespace(DC))
+  if (isStdNamespace(DC)) {
+    if (getASTContext().getTargetInfo().getTriple().isOSSolaris()) {
+      const NamedDecl *ND = cast<NamedDecl>(GD.getDecl());
+      if (const RecordDecl *RD = dyn_cast<RecordDecl>(ND)) {
+        // Issue #33114: Need non-standard mangling of std::tm etc. for
+        // Solaris ABI compatibility.
+        //
+        // <substitution> ::= tm # ::std::tm, same for the others
+        if (const IdentifierInfo *II = RD->getIdentifier()) {
+          StringRef type = II->getName();
+          if (llvm::is_contained({"div_t", "ldiv_t", "lconv", "tm"}, type)) {
+            Out << type.size() << type;
+            return;
+          }
+        }
+      }
+    }
     Out << "St";
+  }
 
   mangleUnqualifiedName(GD, DC, AdditionalAbiTags);
 }

diff  --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 2b62f573857ee8..27d09b4c8ee744 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1604,10 +1604,12 @@ static bool isTargetVariantEnvironment(const TargetInfo &TI,
   return false;
 }
 
-#if defined(__sun__) && defined(__svr4__)
+#if defined(__sun__) && defined(__svr4__) && defined(__clang__) &&             \
+    __clang__ < 20
 // GCC mangles std::tm as tm for binary compatibility on Solaris (Issue
 // #33114).  We need to match this to allow the std::put_time calls to link
-// (PR #99075).
+// (PR #99075).  clang 20 contains a fix, but the workaround is still needed
+// with older versions.
 asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
     "RSt8ios_basecPKSt2tmPKcSB_ = "
     "_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"

diff  --git a/clang/test/AST/solaris-tm.cpp b/clang/test/AST/solaris-tm.cpp
new file mode 100644
index 00000000000000..e559ece1429af8
--- /dev/null
+++ b/clang/test/AST/solaris-tm.cpp
@@ -0,0 +1,34 @@
+/// Check that std::tm and a few others are mangled as tm on Solaris only.
+/// Issue #33114.
+///
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple amd64-pc-solaris2.11 | FileCheck --check-prefix=CHECK-SOLARIS %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -triple x86_64-unknown-linux-gnu  | FileCheck --check-prefix=CHECK-LINUX %s
+//
+// REQUIRES: x86-registered-target
+
+namespace std {
+  extern "C" {
+    struct tm {
+      int tm_sec;
+    };
+    struct ldiv_t {
+      long quot;
+    };
+  }
+}
+
+// CHECK-SOLARIS: @_Z6tmfunc2tm
+// CHECK-SOLARIS: @_Z9tmccpfunc2tmPKcS1_
+// CHECK-SOLARIS: @_Z7tm2func2tmS_
+// CHECK-LINUX:   @_Z6tmfuncSt2tm
+// CHECK-LINUX:   @_Z9tmccpfuncSt2tmPKcS1_
+// CHECK-LINUX:   @_Z7tm2funcSt2tmS_
+
+void tmfunc (std::tm tm) {}
+void tmccpfunc (std::tm tm, const char *ccp, const char *ccp2) {}
+void tm2func (std::tm tm, std::tm tm2) {}
+
+// CHECK-SOLARIS: @_Z7ldtfunc6ldiv_t
+// CHECK-LINUX:   @_Z7ldtfuncSt6ldiv_t
+
+void ldtfunc (std::ldiv_t ldt) {}


        


More information about the cfe-commits mailing list