-// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -analyzer-inline-max-function-size=6 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=unix.Malloc -analyzer-inline-max-stack-depth=5 -verify %s
#include "Inputs/system-header-simulator.h"
void *realloc(void *ptr, size_t size);
void *reallocf(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
-extern void exit(int) __attribute__ ((__noreturn__));
+
+void exit(int) __attribute__ ((__noreturn__));
+void *memcpy(void * restrict s1, const void * restrict s2, size_t n);
+size_t strlen(const char *);
static void my_malloc1(void **d, size_t size) {
*d = malloc(size);
fooWithEmptyReturn(12);
return *x; // expected-warning {{Use of memory after it is freed}}
}
+
+
+// If we inline any of the malloc-family functions, the checker shouldn't also
+// try to do additional modeling. <rdar://problem/12317671>
+char *strndup(const char *str, size_t n) {
+ if (!str)
+ return 0;
+
+ // DO NOT FIX. This is to test that we are actually using the inlined
+ // behavior!
+ if (n < 5)
+ return 0;
+
+ size_t length = strlen(str);
+ if (length < n)
+ n = length;
+
+ char *result = malloc(n + 1);
+ memcpy(result, str, n);
+ result[n] = '\0';
+ return result;
+}
+
+void useStrndup(size_t n) {
+ if (n == 0)
+ (void)strndup(0, 20); // no-warning
+ else if (n < 5)
+ (void)strndup("hi there", n); // no-warning
+ else
+ (void)strndup("hi there", n); // expected-warning{{leak}}
+}