[analyzer] Malloc checker: rework realloc handling:

1) Support the case when realloc fails to reduce False Positives. (We
essentially need to restore the state of the pointer being reallocated.)

2) Realloc behaves differently under special conditions (from pointer is
null, size is 0). When detecting these cases, we should consider
under-constrained states (size might or might not be 0). The
old version handled this in a very hacky way. The code did not
differentiate between definite and possible (no consideration for
under-constrained states). Further, after processing each special case,
the realloc processing function did not return but chained to the next
special case processing. So you could end up in an execution in which
you first see the states in which size is 0 and realloc ~ free(),
followed by the states corresponding to size is not 0 followed by the
evaluation of the regular realloc behavior.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150402 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/Analysis/malloc.c b/test/Analysis/malloc.c
index 0321f52..d1d850c 100644
--- a/test/Analysis/malloc.c
+++ b/test/Analysis/malloc.c
@@ -32,6 +32,32 @@
   int *q = realloc(p,0); // no-warning
 }
 
+void reallocNotNullPtr(unsigned sizeIn) {
+  unsigned size = 12;
+  char *p = (char*)malloc(size);
+  if (p) {
+    char *q = (char*)realloc(p, sizeIn);
+    char x = *q; // expected-warning {{Allocated memory never released.}}
+  }
+}
+
+int *realloctest1() {
+  int *q = malloc(12);
+  q = realloc(q, 20);
+  return q; // no warning - returning the allocated value
+}
+
+// p should be freed if realloc fails.
+void reallocFails() {
+  char *p = malloc(12);
+  char *r = realloc(p, 12+1);
+  if (!r) {
+    free(p);
+  } else {
+    free(r);
+  }
+}
+
 // This case tests that storing malloc'ed memory to a static variable which is
 // then returned is not leaked.  In the absence of known contracts for functions
 // or inter-procedural analysis, this is a conservative answer.
@@ -391,17 +417,6 @@
 
 // Below are the known false positives.
 
-// TODO: There should be no warning here.
-void reallocFails(int *g, int f) {
-  char *p = malloc(12);
-  char *r = realloc(p, 12+1);
-  if (!r) {
-    free(p); // expected-warning {{Try to free a memory block that has been released}}
-  } else {
-    free(r);
-  }
-}
-
 // TODO: There should be no warning here. This one might be difficult to get rid of.
 void dependsOnValueOfPtr(int *g, unsigned f) {
   int *p;