================
@@ -40,9 +40,12 @@ void UndefinedAssignmentChecker::checkBind(SVal location,
SVal val,
// Do not report assignments of uninitialized values inside swap functions.
// This should allow to swap partially uninitialized structs
if (const FunctionDecl *EnclosingFunctionDecl =
- dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
- if (C.getCalleeName(EnclosingFunctionDecl) == "swap")
+ dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl())) {
+ if (C.getCalleeName(EnclosingFunctionDecl) == "swap") {
+ C.generateSink(C.getState(), C.getPredecessor());
----------------
steakhal wrote:
It turns out I can't just sink here, because that would reduce coverage in
tests:
```c++
void swap(struct MyStr *To, struct MyStr *From) {
// This is not really a swap but close enough for our test.
To->x = From->x;
To->y = From->y; // expected-note{{Uninitialized value stored to field 'y'}}
}
int test_undefined_member_assignment_in_swap(struct MyStr *s2) {
struct MyStr s1;
s1.x = 5;
swap(s2, &s1); // expected-note{{Calling 'swap'}}
// expected-note@-1{{Returning from 'swap'}}
return s2->y; // expected-warning{{Undefined or garbage value returned to
caller}}
// expected-note@-1{{Undefined or garbage value returned to
caller}}
}
```
Namely, the `Undefined or garbage value returned to caller` wouldn't be
detected, because we would sink inside `swap`, and never reach the `return
s2->y;`.
Before I inserted the sink, the checker would just not report inside `swap`,
but lead the execution path to `return s2->y;` and detect the use of undef
there.
I figure, this unusual but fine. If the hardened Store can handle the bind,
that still resolves the crash, so I think I'll opt for only doing that.
https://github.com/llvm/llvm-project/pull/178923
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits