This revision was automatically updated to reflect the committed changes.
Szelethus marked an inline comment as done.
Closed by commit rGa504ddc8bf9d: [analyzer] Initialize regions returned by 
CXXNew to undefined (authored by Szelethus).

Changed prior to commit:
  https://reviews.llvm.org/D135375?vs=465779&id=470821#toc

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D135375/new/

https://reviews.llvm.org/D135375

Files:
  clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
  clang/test/Analysis/NewDelete-checker-test.cpp
  clang/test/Analysis/cxx-member-initializer-const-field.cpp
  clang/test/Analysis/new-ctor-conservative.cpp
  clang/test/Analysis/new-ctor-recursive.cpp
  clang/test/Analysis/new.cpp
  clang/test/Analysis/placement-new.cpp
  clang/test/Analysis/reinterpret-cast.cpp
  clang/test/Analysis/uninit-const.cpp

Index: clang/test/Analysis/uninit-const.cpp
===================================================================
--- clang/test/Analysis/uninit-const.cpp
+++ clang/test/Analysis/uninit-const.cpp
@@ -21,9 +21,11 @@
 
 int f10(void) {
   int *ptr;
-
-  ptr = new int; //
-  if(*ptr) {
+                 // FIXME: The message is misleading -- we should state that
+                 // a pointer to an uninitialized value is stored.
+  ptr = new int; // expected-note{{Storing uninitialized value}}
+  if(*ptr) { // expected-warning{{Branch condition evaluates to a garbage value [core.uninitialized.Branch]}}
+             // expected-note@-1 {{Branch condition evaluates to a garbage value}}
     doStuff4(*ptr);
   }
   delete ptr;
@@ -32,10 +34,12 @@
 
 int f9(void) {
   int *ptr;
-
-  ptr = new int; //
-
-  doStuff_uninit(ptr); // no warning
+                 // FIXME: The message is misleading -- we should state that
+                 // a pointer to an uninitialized value is stored.
+  ptr = new int; // expected-note{{Storing uninitialized value}}
+                 // expected-note@-1{{Value assigned to 'ptr'}}
+  doStuff_uninit(ptr); // expected-warning{{1st function call argument is a pointer to uninitialized value [core.CallAndMessage]}}
+                       // expected-note@-1{{1st function call argument is a pointer to uninitialized value}}
   delete ptr;
   return 0;
 }
Index: clang/test/Analysis/reinterpret-cast.cpp
===================================================================
--- clang/test/Analysis/reinterpret-cast.cpp
+++ clang/test/Analysis/reinterpret-cast.cpp
@@ -77,15 +77,11 @@
   class Derived : public Base {};
 
   void test() {
-	Derived* p;
-	*(reinterpret_cast<void**>(&p)) = new C;
-	p->f();
-
-    // We should still be able to do some reasoning about bindings.
-    p->x = 42;
-    clang_analyzer_eval(p->x == 42); // expected-warning{{TRUE}}
+    Derived* p;
+    *(reinterpret_cast<void**>(&p)) = new C;
+    p->f(); // expected-warning{{Called function pointer is an uninitialized pointer value [core.CallAndMessage]}}
   };
-}
+} // namespace PR15345
 
 int trackpointer_std_addressof() {
   int x;
Index: clang/test/Analysis/placement-new.cpp
===================================================================
--- clang/test/Analysis/placement-new.cpp
+++ clang/test/Analysis/placement-new.cpp
@@ -112,6 +112,10 @@
 namespace testHeapAllocatedBuffer {
 void g2() {
   char *buf = new char[2];     // expected-note {{'buf' initialized here}}
+                               // FIXME: The message is misleading -- we should
+                               // state that a pointer to an uninitialized value
+                               // is stored.
+                               // expected-note@-4{{Storing uninitialized value}}
   long *lp = ::new (buf) long; // expected-warning{{Storage provided to placement new is only 2 bytes, whereas the allocated type requires 8 bytes}} expected-note 1 {{}}
   (void)lp;
 }
Index: clang/test/Analysis/new.cpp
===================================================================
--- clang/test/Analysis/new.cpp
+++ clang/test/Analysis/new.cpp
@@ -177,15 +177,10 @@
   clang_analyzer_eval(p.y == 2); // expected-warning{{TRUE}}
 }
 
-//--------------------------------
-// Incorrectly-modelled behavior
-//--------------------------------
-
 int testNoInitialization() {
   int *n = new int;
 
-  // Should warn that *n is uninitialized.
-  if (*n) { // no-warning
+  if (*n) { // expected-warning{{Branch condition evaluates to a garbage value [core.uninitialized.Branch]}}
     delete n;
     return 0;
   }
@@ -193,6 +188,10 @@
   return 1;
 }
 
+//===----------------------------------------------------------------------===//
+// Incorrectly-modelled behavior.
+//===----------------------------------------------------------------------===//
+
 int testNoInitializationPlacement() {
   int n;
   new (&n) int;
Index: clang/test/Analysis/new-ctor-recursive.cpp
===================================================================
--- clang/test/Analysis/new-ctor-recursive.cpp
+++ clang/test/Analysis/new-ctor-recursive.cpp
@@ -51,11 +51,9 @@
 
 void testThatCharConstructorIndeedYieldsGarbage() {
   S *s = new S(ConstructionKind::Garbage);
-  clang_analyzer_eval(s->x == 0); // expected-warning{{UNKNOWN}}
-  clang_analyzer_eval(s->x == 1); // expected-warning{{UNKNOWN}}
-  // FIXME: This should warn, but MallocChecker doesn't default-bind regions
-  // returned by standard operator new to garbage.
-  s->x += 1; // no-warning
+  clang_analyzer_eval(s->x == 0); // expected-warning{{The left operand of '==' is a garbage value [core.UndefinedBinaryOperatorResult]}}
+  clang_analyzer_eval(s->x == 1);
+  s->x += 1;
   delete s;
 }
 
Index: clang/test/Analysis/new-ctor-conservative.cpp
===================================================================
--- clang/test/Analysis/new-ctor-conservative.cpp
+++ clang/test/Analysis/new-ctor-conservative.cpp
@@ -14,9 +14,12 @@
   clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
 }
 
-void checkNewPOD() {
+void checkNewPODunit() {
   int *i = new int;
-  clang_analyzer_eval(*i == 0); // expected-warning{{UNKNOWN}}
+  clang_analyzer_eval(*i == 0); // expected-warning{{The left operand of '==' is a garbage value [core.UndefinedBinaryOperatorResult]}}
+}
+
+void checkNewPOD() {
   int *j = new int();
   clang_analyzer_eval(*j == 0); // expected-warning{{TRUE}}
   int *k = new int(5);
Index: clang/test/Analysis/cxx-member-initializer-const-field.cpp
===================================================================
--- clang/test/Analysis/cxx-member-initializer-const-field.cpp
+++ clang/test/Analysis/cxx-member-initializer-const-field.cpp
@@ -10,7 +10,7 @@
   WithConstructor(int *x) : ptr(x) {}
 
   static auto compliant() {
-    WithConstructor c(new int);
+    WithConstructor c(new int{});
     return *(c.ptr); // no warning
   }
 
@@ -28,7 +28,7 @@
   int *const ptr = nullptr;
 
   static int compliant() {
-    RegularAggregate c{new int};
+    RegularAggregate c{new int{}};
     return *(c.ptr); // no warning
   }
 
Index: clang/test/Analysis/NewDelete-checker-test.cpp
===================================================================
--- clang/test/Analysis/NewDelete-checker-test.cpp
+++ clang/test/Analysis/NewDelete-checker-test.cpp
@@ -385,7 +385,11 @@
 public:
   int *x;
   DerefClass() {}
-  ~DerefClass() {*x = 1;}
+  ~DerefClass() {
+    int i = 0;
+    x = &i;
+    *x = 1;
+  }
 };
 
 void testDoubleDeleteClassInstance() {
Index: clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
===================================================================
--- clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -10,15 +10,16 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
-#include "clang/Analysis/ConstructionContext.h"
 #include "clang/AST/DeclCXX.h"
-#include "clang/AST/StmtCXX.h"
 #include "clang/AST/ParentMap.h"
+#include "clang/AST/StmtCXX.h"
+#include "clang/Analysis/ConstructionContext.h"
 #include "clang/Basic/PrettyStackTrace.h"
 #include "clang/StaticAnalyzer/Core/CheckerManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
+#include "clang/StaticAnalyzer/Core/PathSensitive/SVals.h"
 
 using namespace clang;
 using namespace ento;
@@ -953,6 +954,11 @@
     // skip it for now.
     ProgramStateRef State = I->getState();
     SVal RetVal = State->getSVal(CNE, LCtx);
+    // [basic.stc.dynamic.allocation] (on the return value of an allocation
+    // function):
+    // "The order, contiguity, and initial value of storage allocated by
+    // successive calls to an allocation function are unspecified."
+    State = State->bindDefaultInitial(RetVal, UndefinedVal{}, LCtx);
 
     // If this allocation function is not declared as non-throwing, failures
     // /must/ be signalled by exceptions, and thus the return value will never
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to