-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[stdlib] Fix nullability logic of memcmp
#41797
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
Conversation
@compnerd Sorry for pinging you immediately. I regard this as a rather severe bug that should be quickly validated and back-port to earlier release branches. Is there anyone to trigger CI for building a Windows toolchain? |
Can you please explain why this is such a critical issue? That explanation also belongs in the commit message. The commit message currently conveys the exact opposite - that this isn't a big deal. It elides the nullability, that means that it makes a stronger guarantee - that the in parameters are never NULL. |
Notice that Swift depends on nullability attributes to decide the interface of C API, so this will certainly cause type mismatch. I don't expect non- |
To be specific, you can have a look at what I've met with SR-15946 |
Right, there will be a mismatch depending on which module is included, but, I don't see how that is a "severe" issue. Either signature will work, though you would need to update the code if the module used changes. I agree that this is a bug, but of a rather low importance. |
@swift-ci please test |
@swift-ci please build toolchain Windows platform |
The complete toolchain test is necessary since this can have fallout further from the swift compiler. |
Sad that I was hitting this edge case. I regarded it as important because we’re shipping it as a part of |
@swift-ci please test Linux platform |
That would be a poor way to define as "important". I've hit plenty of bugs in the standard library, and thus impacts everyone, but that doesn't necessarily make it a severe bug. Particularly in this case, in the incorrect case, it forces the nullability into the Swift side to be explicit, so IMO it really is not a severe bug. |
@swift-ci please test Linux platform |
1 similar comment
@swift-ci please test Linux platform |
memcmp
on Windowsmemcmp
on Windows
Thinking about this more carefully, I think that this is a bad idea. Perhaps |
No it won’t. Try |
The last parameter being |
Clang never knows about this, and we’re relying on Clang to import the symbol. There’s no reason to respect SAL here. |
We shouldn’t do anything to diverge the symbol from clang’s knowledge of ucrt headers. |
Anyone to merge? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm admittedly late to the party here, so I don't have the full history of why it was written this way to begin with, but I would recommend removing this platform conditional entirely, and keeping only the declaration without nullability annotation:
extern int memcmp(const void *, const void *, __swift_size_t);
The C standard specifies that it is undefined behavior to pass null pointers to memcmp
, so regardless of runtime implementation circumstances, it's wrong to declare its arguments as nullable. It is safe to redeclare a function that has nullability attributes in one declaration and leave the nullability out of the redeclaration; _Nullable
is a clang extension, after all, and if the redeclaration were disallowed then adopting _Nullable
would break standard source code. Having the one redeclaration of memcmp
is more correct and will save us having to micromanage this platform conditional in the future.
@jckarter Darwin, Android, OpenBSD and UCRT headers don’t have nullability attributes on the target, but other platform like Glibc explicitly marks it as non-nullable. The nullability mark will not change anything from C’s side. However, a conflicting redeclaration here will cause Swift to infer the wrong parameter type, resulting in failures like SR-15946, so it’s necessary to match this line exactly to the system header. |
If we really want to remove the conditional here, we should first remove it from the header interface — seemingly impossible without rewriting a bunch of stuffs. |
Also notice these lines on the top: #if __has_feature(nullability)
#pragma clang assume_nonnull begin
#endif It makes Clang assuming non-null as default, which is exactly the opposite to how Swift parse external headers. To remove the conditional, we must move this |
In an
Beyond the scope of this particular PR, |
However, extern int memcmp (const void *__s1, const void *__s2, size_t __n)
__THROW __attribute_pure__ __nonnull ((1, 2)); It is explicitly non-null, so unavoidably we need to make it an exception. |
@jckarter Since the diversity is actually introduced by Glibc, I reverted the logic here to make it clear and robust. |
Here is what we will get if we default it to
|
memcmp
on Windowsmemcmp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks good, thanks! We'll still probably have to face the inconsistency in Glibc's behavior at some point (maybe we can use APINotes to override the system header's nullability to make it consistent?) but this seems like it's more likely to be robust for bringing up new platforms in the meantime.
Interesting idea, but this can be potentially source-breaking, so it needs further investigation; |
@swift-ci Please test |
It seems macros from Glibc is not available in the overlay, and I didn’t find a solution without modifying the interface (eg. importing other header files), so a workaround is to identify GNU/Linux. This will work until the day we gain Musl support. |
a368554
to
b913a9f
Compare
@swift-ci Please test |
@stevapple Thanks for looking into it. We don't need to figure out a solution to the memcmp type issue as part of this fix, to be clear. |
Fix the nullability judging logic for
extern int memcmp
inLibcShims.h
.Should resolve SR-15946.