================
@@ -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

Reply via email to