-
Notifications
You must be signed in to change notification settings - Fork 14.4k
[clang] Fix -Wuninitialized for values passed by const pointers #147221
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -438,13 +438,10 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) { | |||||||||||||||
return; | ||||||||||||||||
} | ||||||||||||||||
bool isTrivialBody = hasTrivialBody(CE); | ||||||||||||||||
// If a value is passed by const pointer to a function, | ||||||||||||||||
// we should not assume that it is initialized by the call, and we | ||||||||||||||||
// conservatively do not assume that it is used. | ||||||||||||||||
// If a value is passed by const reference to a function, | ||||||||||||||||
// it should already be initialized. | ||||||||||||||||
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); | ||||||||||||||||
I != E; ++I) { | ||||||||||||||||
// A value passed by const pointer or reference to a function should already | ||||||||||||||||
// be initialized. | ||||||||||||||||
for (CallExpr::arg_iterator I = CE->arg_begin(), E = CE->arg_end(); I != E; | ||||||||||||||||
++I) { | ||||||||||||||||
if ((*I)->isGLValue()) { | ||||||||||||||||
if ((*I)->getType().isConstQualified()) | ||||||||||||||||
classify((*I), isTrivialBody ? Ignore : ConstRefUse); | ||||||||||||||||
|
@@ -453,7 +450,7 @@ void ClassifyRefs::VisitCallExpr(CallExpr *CE) { | |||||||||||||||
const auto *UO = dyn_cast<UnaryOperator>(Ex); | ||||||||||||||||
if (UO && UO->getOpcode() == UO_AddrOf) | ||||||||||||||||
Ex = UO->getSubExpr(); | ||||||||||||||||
classify(Ex, Ignore); | ||||||||||||||||
classify(Ex, Use); | ||||||||||||||||
Comment on lines
451
to
+453
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe the intent of this code is that if the address of a local variable is passed to a const pointer, that local variable is neither considered used nor initialized. When a local variable is passed directly to a call, no special handling should be required, because an lvalue-to-rvalue conversion will be performed, which will be classified as a use. So I think the correct fix is instead:
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That said, rather than treating this case as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your suggestion does not cover the case:
Note that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
TBH, I don't think we need a separate diagnostic for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Correct. We intentionally don't warn on that -- a "const reference use" is neither treated as initializing nor as using the local variable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
What is the basis of this intention? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Warning on such uses was found to lead to false positives. Such as all the cases you found in libc++'s test suite :) The point is, for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With my suggested approach plus changing the kind from |
||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
} | ||||||||||||||||
|
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.
Could this use
CE->arguments()
in a range based for loop instead?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'd prefer not to do that to keep the fix as atomic as possible and to avoid concealing the actual behavior change among unrelated NFC changes.