Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] Handle tm mangling on Solaris in PPMacroExpansion.cpp #100724

Merged
merged 1 commit into from
Jul 26, 2024

Conversation

rorth
Copy link
Collaborator

@rorth rorth commented Jul 26, 2024

The introduction of std::put_time in
fad17b4 broke the Solaris build:

Undefined			first referenced
 symbol  			    in file
_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKSt2tmPKcSB_ lib/libclangLex.a(PPMacroExpansion.cpp.o)
ld: fatal: symbol referencing errors

As discussed in PR #99075, the problem is that GCC mangles std::tm as tm on Solaris for binary compatility, while clang doesn't (Issue #33114).

As a stop-gap measure, this patch introduces an asm level alias to the same effect.

Tested on sparcv9-sun-solaris2.11, amd64-pc-solaris2.11, and x86_64-pc-linux-gnu.

The introduction of `std::put_time` in
fad17b4 broke the Solaris build:
```
Undefined			first referenced
 symbol  			    in file
_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKSt2tmPKcSB_ lib/libclangLex.a(PPMacroExpansion.cpp.o)
ld: fatal: symbol referencing errors
```
As discussed in PR llvm#99075, the problem is that GCC mangles `std::tm` as
`tm` on Solaris for binary compatility, while `clang` doesn't (Issue

As a stop-gap measure, this patch introduces an `asm` level alias to the
same effect.

Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.
@rorth rorth added clang Clang issues not falling into any other category platform:solaris labels Jul 26, 2024
@rorth rorth requested review from nico and AaronBallman July 26, 2024 09:46
@llvmbot llvmbot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Jul 26, 2024
@llvmbot
Copy link
Collaborator

llvmbot commented Jul 26, 2024

@llvm/pr-subscribers-clang

Author: Rainer Orth (rorth)

Changes

The introduction of std::put_time in
fad17b4 broke the Solaris build:

Undefined			first referenced
 symbol  			    in file
_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_RSt8ios_basecPKSt2tmPKcSB_ lib/libclangLex.a(PPMacroExpansion.cpp.o)
ld: fatal: symbol referencing errors

As discussed in PR #99075, the problem is that GCC mangles std::tm as tm on Solaris for binary compatility, while clang doesn't (Issue #33114).

As a stop-gap measure, this patch introduces an asm level alias to the same effect.

Tested on sparcv9-sun-solaris2.11, amd64-pc-solaris2.11, and x86_64-pc-linux-gnu.


Full diff: https://github.com/llvm/llvm-project/pull/100724.diff

1 Files Affected:

  • (modified) clang/lib/Lex/PPMacroExpansion.cpp (+10)
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index 879f01e87806e..1e31fcc3d731e 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1604,6 +1604,16 @@ static bool isTargetVariantEnvironment(const TargetInfo &TI,
   return false;
 }
 
+#if defined(__sun__) && defined(__svr4__)
+// 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).
+asm("_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
+    "RSt8ios_basecPKSt2tmPKcSB_ = "
+    "_ZNKSt8time_putIcSt19ostreambuf_iteratorIcSt11char_traitsIcEEE3putES3_"
+    "RSt8ios_basecPK2tmPKcSB_");
+#endif
+
 /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded
 /// as a builtin macro, handle it and return the next token as 'Tok'.
 void Preprocessor::ExpandBuiltinMacro(Token &Tok) {

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for helping out with this odd edge case! I don't suppose there's a way we can shove this hack into CMake (basically, like a kind of linker script hack)? If so, can we apply it broadly enough so that any use of time_put in other TUs will also benefit?

(If there are better alternatives than this approach, I'd love to hear about them, this is a pretty gnarly way to go about working around the issue.)

CC @petrhosek @MaskRay @efriedma-quic

@rorth
Copy link
Collaborator Author

rorth commented Jul 26, 2024

Thank you for helping out with this odd edge case! I don't suppose there's a way we can shove this hack into CMake (basically, like a kind of linker script hack)? If so, can we apply it broadly enough so that any use of time_put in other TUs will also benefit?

This would have to apply to all instances of std::tm, so I cannot say if this is feasible at all. Besides, clang on Solaris supports both Solaris ld and GNU ld, which have different linker script syntax, duplicating the code if in fact both support the renaming.

This all seems like a waste of time to me.

(If there are better alternatives than this approach, I'd love to hear about them, this is a pretty gnarly way to go about working around the issue.)

I believe clang should something like g++ to handle the mangling difference itself. On the g++ side of things, there's the TARGET_CXX_DECL_MANGLING_CONTEXT target hook, implemented for Solaris in gcc/config/sol2-cxx.cc (solaris_cxx_decl_mangling_context) and applied in gcc/cp/mangle.cc (decl_mangling_context) where it is called as targetm.cxx.decl_mangling_context.

As I've mentioned before, I've no idea where to do something similar in clang. I believe that would be clang/lib/CodeGen

Whatever the case, we need at least a short-term solution now: the Solaris buildbots have been broken for two days now.

@AaronBallman
Copy link
Collaborator

Whatever the case, we need at least a short-term solution now: the Solaris buildbots have been broken for two days now.

Agreed that we need something in the short term, I'm just trying to find the cleanest "something" under the assumption that this hack will live for a long time. That's why I was hoping we could shove this into CMake somewhere (it's less in everyone's face than the current approach). If we can't do that, then I can live with this approach.

Note: precommit CI failures look unrelated.

@rorth
Copy link
Collaborator Author

rorth commented Jul 26, 2024

Whatever the case, we need at least a short-term solution now: the Solaris buildbots have been broken for two days now.

Agreed that we need something in the short term, I'm just trying to find the cleanest "something" under the assumption that this hack will live for a long time. That's why I was hoping we could shove this into CMake somewhere (it's less in everyone's face than the current approach). If we can't do that, then I can live with this approach.

I just don't see how this can be done. And TBH rather than pile hack upon hack, I'd rather spend some time on duplicating what GCC already does in Clang. This will require tons and tons of guidance, though.

Note: precommit CI failures look unrelated.

I think so: I've seen the same failure in my Linux/x86_64 but not on Solaris.

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM; if we find a better approach post-commit, this is easy enough to remove. Thanks!

@AaronBallman
Copy link
Collaborator

Whatever the case, we need at least a short-term solution now: the Solaris buildbots have been broken for two days now.

Agreed that we need something in the short term, I'm just trying to find the cleanest "something" under the assumption that this hack will live for a long time. That's why I was hoping we could shove this into CMake somewhere (it's less in everyone's face than the current approach). If we can't do that, then I can live with this approach.

I just don't see how this can be done. And TBH rather than pile hack upon hack, I'd rather spend some time on duplicating what GCC already does in Clang. This will require tons and tons of guidance, though.

I would recommend talking to @efriedma-quic and @rjmccall about potential approaches

@rorth
Copy link
Collaborator Author

rorth commented Jul 26, 2024

Right, as is it's just a ugly hack with the underlying problem like to rear its ugly head again in the future.

@rorth rorth merged commit 599de13 into llvm:main Jul 26, 2024
8 of 11 checks passed
@rorth
Copy link
Collaborator Author

rorth commented Aug 15, 2024

FWIW, the hack even breaks when doing a Debug build: in that case the unresolved reference returns despite the hack.

@efriedma-quic
Copy link
Collaborator

The mangler is in clang/lib/AST/ItaniumMangle.cpp; maybe look at CXXNameMangler::mangleStandardSubstitution.

@cor3ntin
Copy link
Contributor

@efriedma-quic this is about clang missing a symbol, not generated code

@efriedma-quic
Copy link
Collaborator

The failure is essentially a bootstrap failure. (The buildbot in question is not technically bootstrapping, but it's using clang 18 as the host compiler.)

rorth added a commit that referenced this pull request Oct 7, 2024
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`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category platform:solaris
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants