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 # ::std:: assert(!isa(DC) && "unskipped LinkageSpecDecl"); - if (isStdNamespace(DC)) + if (isStdNamespace(DC)) { + if (getASTContext().getTargetInfo().getTriple().isOSSolaris()) { + const NamedDecl *ND = cast(GD.getDecl()); + if (const RecordDecl *RD = dyn_cast(ND)) { + // Issue #33114: Need non-standard mangling of std::tm etc. for + // Solaris ABI compatibility. + // + // ::= 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) {}