Author: zaks
Date: Tue Jun 18 18:16:15 2013
New Revision: 184256

URL: http://llvm.org/viewvc/llvm-project?rev=184256&view=rev
Log:
[analyzer] Do not report uninitialized value warnings inside swap functions.

This silences warnings that could occur when one is swapping partially 
initialized structs. We suppress
not only the assignments of uninitialized members, but any values inside swap 
because swap could
potentially be used as a subroutine to swap class members.

This silences a warning from std::try::function::swap() on partially 
initialized objects.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
    cfe/trunk/test/Analysis/uninit-vals-ps-region.m

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp?rev=184256&r1=184255&r2=184256&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefResultChecker.cpp Tue Jun 18 
18:16:15 2013
@@ -40,6 +40,15 @@ void UndefResultChecker::checkPostStmt(c
   ProgramStateRef state = C.getState();
   const LocationContext *LCtx = C.getLocationContext();
   if (state->getSVal(B, LCtx).isUndef()) {
+
+    // Do not report assignments of uninitialized values inside swap functions.
+    // This should allow to swap partially uninitialized structs
+    // (radar://14129997)
+    if (const FunctionDecl *EnclosingFunctionDecl =
+        dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
+      if (C.getCalleeName(EnclosingFunctionDecl) == "swap")
+        return;
+
     // Generate an error node.
     ExplodedNode *N = C.generateSink();
     if (!N)

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp?rev=184256&r1=184255&r2=184256&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp 
(original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/UndefinedAssignmentChecker.cpp Tue 
Jun 18 18:16:15 2013
@@ -38,6 +38,14 @@ void UndefinedAssignmentChecker::checkBi
   if (!val.isUndef())
     return;
 
+  // Do not report assignments of uninitialized values inside swap functions.
+  // This should allow to swap partially uninitialized structs
+  // (radar://14129997)
+  if (const FunctionDecl *EnclosingFunctionDecl =
+      dyn_cast<FunctionDecl>(C.getStackFrame()->getDecl()))
+    if (C.getCalleeName(EnclosingFunctionDecl) == "swap")
+      return;
+
   ExplodedNode *N = C.generateSink();
 
   if (!N)

Modified: cfe/trunk/test/Analysis/uninit-vals-ps-region.m
URL: 
http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/uninit-vals-ps-region.m?rev=184256&r1=184255&r2=184256&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/uninit-vals-ps-region.m (original)
+++ cfe/trunk/test/Analysis/uninit-vals-ps-region.m Tue Jun 18 18:16:15 2013
@@ -76,3 +76,18 @@ void PR10163 (void) {
   test_PR10163(x[1]); // expected-warning{{uninitialized value}}
 }
 
+struct MyStr {
+  int x;
+  int y;
+};
+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; // no warning
+}
+int test_undefined_member_assignment_in_swap(struct MyStr *s2) {
+  struct MyStr s1;
+  s1.x = 5;
+  swap(s2, &s1);
+  return s2->y; // expected-warning{{Undefined or garbage value returned to 
caller}}
+}


_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to