This is an archive of the discontinued LLVM Phabricator instance.

PR58819: Correct linkage and mangling of lambdas in inline static member initializers
ClosedPublic

Authored by dblaikie on Nov 17 2022, 5:07 PM.

Details

Summary

https://llvm.org/pr58819 - clang is giving an externally visible lambda in a static data member internal linkage and the wrong linkage name.

Looks like we should be classifying this case the same as a non-static data member, so far as I can tell from the ABI docs and template examples (seems like the non-template inline-defined case should be the same).

This is a change in ABI, but not sure it qualifies as an ABI break as far as Apple and Sony are concerned - do you folks want this change? (it should fix the example in the bug where a static member in such a lambda ends up bifurcated, and I don't /think/ it'll break existing code since the symbol was previously internal anyway)

Looks like GCC has got this mangling slightly wrong (so we'd still end up with GCC+Clang bifurcation of the local static in the lambda, function address inequality, etc) in that they miss the variable name in the mangling in the non-template case. GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107741

Diff Detail

Event Timeline

dblaikie created this revision.Nov 17 2022, 5:07 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 17 2022, 5:07 PM
dblaikie requested review of this revision.Nov 17 2022, 5:07 PM
Herald added a project: Restricted Project. · View Herald TranscriptNov 17 2022, 5:07 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript

If this is specifically for C++17, I believe Sony doesn't officially support that yet although I am checking.

It looks like this is only part of the fix for #58819? The original report also had a static int n with an internal-linkage name.

If this is specifically for C++17, I believe Sony doesn't officially support that yet although I am checking.

Cool, thanks!

It looks like this is only part of the fix for #58819? The original report also had a static int n with an internal-linkage name.

Nah, it's the full fix - but the static member handling works correctly once you fix the type mangling itself, so the bug is in the type linkage/mangling, the static member was just the canary in the coal mine/a more visible effect of the bug. I could add test coverage for it, but by default I prefer to test more narrowly.

mgorny added a subscriber: mgorny.Nov 21 2022, 8:43 PM

From Gentoo perspective, correct is better, correct and matching GCC is the best (we support mixing compilers to some degree). I think it'd be best to wait for confirmation on GCC end.

From Gentoo perspective, correct is better, correct and matching GCC is the best (we support mixing compilers to some degree). I think it'd be best to wait for confirmation on GCC end.

fair - if you know anyone over there who might be able to take a look/an interest, would be great if you could ping them/point them in that direction!

GCC bug hasn't got much traction, so I pinged it.

But probably still the right thing to continue with this fix, I think.

@rjmccall Could you give a quick glance/confirm my ABI understanding/diagnosis/direction here?

The relevant text of the current Itanium ABI (which was updated in https://github.com/itanium-cxx-abi/cxx-abi/commit/d8e9d102c83f177970f0db6cc8bee170f2779bc1)

In the following contexts, however, the one-definition rule requires closure types in different translation units to "correspond":

  • default arguments appearing in class definitions
  • default member initializers
  • the bodies of inline or templated functions
  • the initializers of inline or templated variables

Could you update the references to the ABI document to use the new text?

Given the new rules, I think ContextKind::StaticDataMember shouldn't exist? It's not one of the given categories; should be subsumed by the existing categories.

dblaikie updated this revision to Diff 508842.Mar 27 2023, 4:52 PM

Remove StaticDataMember and classify static member variables of templates as variable templates

dblaikie updated this revision to Diff 508847.Mar 27 2023, 5:01 PM

Rename VariableTemplate classification to TemplatedVariable to match ABI wording

The relevant text of the current Itanium ABI (which was updated in https://github.com/itanium-cxx-abi/cxx-abi/commit/d8e9d102c83f177970f0db6cc8bee170f2779bc1)

In the following contexts, however, the one-definition rule requires closure types in different translation units to "correspond":

  • default arguments appearing in class definitions
  • default member initializers
  • the bodies of inline or templated functions
  • the initializers of inline or templated variables

Could you update the references to the ABI document to use the new text?

Oh, yeah - good call. Done.

Given the new rules, I think ContextKind::StaticDataMember shouldn't exist? It's not one of the given categories; should be subsumed by the existing categories.

Fair - I assume the "initializers of inline or templated variables" is intended to cover the case of static member variables of class templates, though they aren't technically variable templates presumably they are "templated variables".

So I renamed the VariableTemplate kind to TemplatedVariable to match the ABI wording/semantics a bit better.

This revision is now accepted and ready to land.Mar 30 2023, 11:03 AM