This is an archive of the discontinued LLVM Phabricator instance.

[libc++] [ABI BREAK] Conform lognormal_distribution::param_type.
ClosedPublic

Authored by Quuxplusone on Dec 28 2021, 3:07 PM.

Details

Summary

Fixes https://github.com/llvm/llvm-project/issues/52906

Unless I'm mistaken, this

  • preserves the size and layout of lognormal_distribution<T>; but
  • shrinks the size of lognormal_distribution<T>::param_type (this is the ABI break).

Diff Detail

Event Timeline

Quuxplusone requested review of this revision.Dec 28 2021, 3:07 PM
Quuxplusone created this revision.
Herald added 1 blocking reviewer(s): Restricted Project. · View Herald TranscriptDec 28 2021, 3:07 PM

SGTM, but I'm not too familiar with this part of the library.

libcxx/include/__random/lognormal_distribution.h
39

If I'm correct we go from 3 * sizeof(result_type) + sizeof(bool) to 2 * sizeof(result_type). So it would be possible use an ABI macro. Right?

libcxx/include/__random/lognormal_distribution.h
39

Yes, it is definitely possible to preserve the old code under a macro. The PR summary indicates my opinion on this.

ldionne requested changes to this revision.Jan 3 2022, 7:00 AM

These changes are hard. We don't have any way to tell whether it's going to bite someone, and chances are that it won't hurt anyone. But if it does, it's exactly the kind of thing that's going to be a huge pain to debug, and it's also going to be unfixable from their end once they find out what the issue is.

For these reasons, and because the behavior we're fixing is bad but also not like fixing basic functionality, I think it would be better to hide this behind an ABI macro.

libcxx/test/std/numerics/rand/rand.dis/rand.dist.norm/rand.dist.norm.lognormal/eval_param.PR52906.pass.cpp
15

Please link to the bug report (using llvm.org/PRXYZ)

22
This revision now requires changes to proceed.Jan 3 2022, 7:00 AM

For these reasons, and because the behavior we're fixing is bad but also not like fixing basic functionality

What I mean here is that their code probably worked previously, and they had never noticed this bug. It's not like if lognormal_distribution had never worked properly and we were suddenly making it work -- I think an ABI break would be legit, cause nobody could really have been using it in the first place. Now this is sneakier.

Quuxplusone edited the summary of this revision. (Show Details)

Add a release note; add a macro to revert to the old behavior. The wording is copied from the release note above the new one, because I think "remove the bad UB code in LLVM 15" sounds like a great plan.

libcxx/include/__random/lognormal_distribution.h
275–291

I was so tempted to make these hidden friends in the new code, but I didn't. ;)

The green code here is the same as what I was proposing in the previous diff. The changes between the #if and the #else blocks are minor, but many and scattered throughout, so I think this "one giant #if-#else" is the correct strategy here.

ldionne accepted this revision.Jan 10 2022, 10:33 AM
ldionne added a subscriber: Restricted Project.

Okay, so the strategy here is:

  1. We don't think this is going to break anyone.
  2. We make the change unconditionally, and *perhaps* break some people, who will revert the change with the macro.
  3. These people will comment here and we can adjust what we do based on that feedback.

I'm fine with this approach since I don't think anybody's going to be impacted -- IOW this is a small risk for an interesting benefit. FWIW, "these people" are most likely vendors who will discover any potential breakage through their users complaining over the next year or so, if that happens at all. If it does, we will make this a proper ABI macro and only enable it in the ABI-unstable build.

Pinging libc++ vendors to see if they have an opinion. @Quuxplusone please feel free to ship this at the end of this week if nobody has raised any concerns.

This revision is now accepted and ready to land.Jan 10 2022, 10:33 AM
@ldionne wrote:

If it does, we will make this a proper ABI macro and only enable it in the ABI-unstable build.

I agree with everything you said except this sentence. I don't believe we know a realistic path to ever make "ABIv2" the default, which means that if we do this patch only in ABIv2, then we're not doing it by default for "new customers" (so to speak). And I think this UB is a big enough deal that it needs to be fixed-by-default for new customers. If anyone complains about the new lognormal_distribution (which I think we both believe is highly unlikely), then I think we would have to investigate some way to keep this patch enabled by default for ABIv1 users, but disabled for those specific vendors who complained — which I think means simply "do exactly this PR, but commit to supporting the _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION macro forever."
(TLDR: I do not think it should be acceptable to enable _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION by default in ABIv1, even if we get a few complaints. But again, we'll probably get zero complaints and so it'll be moot, which is great.)

ldionne added a comment.EditedJan 10 2022, 10:51 AM
@ldionne wrote:

If it does, we will make this a proper ABI macro and only enable it in the ABI-unstable build.

I agree with everything you said except this sentence. I don't believe we know a realistic path to ever make "ABIv2" the default, which means that if we do this patch only in ABIv2, then we're not doing it by default for "new customers" (so to speak). And I think this UB is a big enough deal that it needs to be fixed-by-default for new customers. If anyone complains about the new lognormal_distribution (which I think we both believe is highly unlikely), then I think we would have to investigate some way to keep this patch enabled by default for ABIv1 users, but disabled for those specific vendors who complained — which I think means simply "do exactly this PR, but commit to supporting the _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION macro forever."
(TLDR: I do not think it should be acceptable to enable _LIBCPP_ABI_OLD_LOGNORMAL_DISTRIBUTION by default in ABIv1, even if we get a few complaints. But again, we'll probably get zero complaints and so it'll be moot, which is great.)

I knew you (or someone else) was going to suggest that, which is why I worded my comment above to unambiguously suggest that the default was going to be "no ABI break". I think there's definitely logic in what you suggest, however the default so far has always be that non-benign [1] ABI breaking changes were opted-into, not opted-out. We could discuss changing that policy, but it's a much much larger discussion. It would indeed make some sense that the library be "unstable" by default, but that we provide mechanisms for vendors to keep their flavour of the library ABI stable. But that's an entirely new dynamic for the project and we would need vendors to be organized and to pay attention to what's shipped on their systems a lot more than they need to be today.

[1]: By a non-benign change, I mean a change that affects some people. For example, if we break the ABI in such a tiny way that nobody ever notices cause nobody was ever depending on that ABI, it's a benign change and I'm supportive of not even having a macro for it. That would just make our lives harder without benefit.

Pinging libc++ vendors to see if they have an opinion. @Quuxplusone please feel free to ship this at the end of this week if nobody has raised any concerns.

I'll try to remember to land this on Monday.