This is an archive of the discontinued LLVM Phabricator instance.

[NFC] Fix potential dereferencing of nullptr.
ClosedPublic

Authored by schittir on Jun 18 2023, 7:55 PM.

Details

Summary

Replace getAs with castAs and add assert if needed.

Diff Detail

Event Timeline

schittir created this revision.Jun 18 2023, 7:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 18 2023, 7:55 PM
schittir requested review of this revision.Jun 18 2023, 7:55 PM
Herald added a project: Restricted Project. · View Herald TranscriptJun 18 2023, 7:55 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript
Fznamznon added inline comments.
clang/lib/Parse/ParseStmt.cpp
887

The assert that looks like assert(x && "x should not be null") seems strange. Failed assert(x) implies that x should not be null. If there is a message, a message saying what is wrong and why is much more useful.

clang/lib/Sema/SemaExprObjC.cpp
2441

That seems to be a strange place before and after changes. With or without change, when ReceiverType.isNull() is true we just end up passing nullptr as receiverTypeInfo to the BuildClassMessage which doesn't seem to be checking its non-nullness before dereferencing it, even though its description says that receiverTypeInfo can be null.
I guess it is fine to pass nullptr to a function whose description says so, but the non-nullness check inside of it should be probably a bit more obvious than it is right now.

schittir added inline comments.Jun 20 2023, 9:08 AM
clang/lib/Parse/ParseStmt.cpp
887

Would you suggest removing the message and changing it to

assert(DeepestParsedCaseStmt);

I am not sure what message would be useful here.

clang/lib/Sema/SemaExprObjC.cpp
2441

I see your point about passing ReceiverTypeInfo as nullptr to BuildClassMessage method - it seems ok to do that.
Would it make sense to add an assert(ReceiverTypeInfo); inside the method as way of making the non-nullness check more obvious?

aaron.ballman added inline comments.Jun 21 2023, 5:36 AM
clang/lib/Parse/ParseStmt.cpp
886–887

The assert doesn't add much value, this seems to be a false positive in the analysis.

If we have no top-level case statement yet, then we get into the if branch on line 884, but that then sets DeepestParsedCaseStmt on line 890, and that must be non-null because we verified that Case is valid above on line 876. So by the time we get into the else branch, DeepestParsedCaseStmt must be nonnull.

I don't think changes are needed here at all; WDYT?

clang/lib/Sema/SemaExprObjC.cpp
2441

I think there's a different assertion needed here. The invariant that BuildClassMessage() has is that the first argument (the TypeSourceInfo * needs to be nonnull if the third argument (the SourceLocation) is invalid. So I think this assert should be:

assert(((isSuperReceiver && Loc.isValid()) || receiverTypeInfo) &&
       "Either the super receiver location needs to be valid or the receiver needs valid type source information");
clang/lib/Sema/SemaType.cpp
2711–2712

Slightly better fix so we don't do "isa" followed by "cast".

schittir updated this revision to Diff 533386.Jun 21 2023, 1:55 PM
schittir marked 3 inline comments as done.

Changes to address comments.

clang/lib/Parse/ParseStmt.cpp
886–887

This makes sense. I didn't thoroughly consider the Case.isInvalid() check above in my analysis. Thank you for catching this! I removed this change.

This revision is now accepted and ready to land.Jun 22 2023, 4:14 AM
This revision was automatically updated to reflect the committed changes.

Thank you @aaron.ballman and @Fznamznon for reviewing! I landed this patch with commit d2fafa79ef08f9ef9cd0108a6caa7fc61a31bdeb