summaryrefslogtreecommitdiffstats
path: root/clang/test
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test')
-rw-r--r--clang/test/Analysis/bstring.cpp124
-rw-r--r--clang/test/Analysis/null-deref-ps-region.c2
-rw-r--r--clang/test/Analysis/string.c293
3 files changed, 410 insertions, 9 deletions
diff --git a/clang/test/Analysis/bstring.cpp b/clang/test/Analysis/bstring.cpp
index fea76cc082f..19978f913cb 100644
--- a/clang/test/Analysis/bstring.cpp
+++ b/clang/test/Analysis/bstring.cpp
@@ -1,7 +1,8 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
-// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify %s
+// RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -verify %s
#include "Inputs/system-header-simulator-cxx.h"
#include "Inputs/system-header-simulator-for-malloc.h"
@@ -77,3 +78,118 @@ class b {
unsigned *f;
};
}
+
+void *memset(void *dest, int ch, std::size_t count);
+namespace memset_non_pod {
+class Base {
+public:
+ int b_mem;
+ Base() : b_mem(1) {}
+};
+
+class Derived : public Base {
+public:
+ int d_mem;
+ Derived() : d_mem(2) {}
+};
+
+void memset1_inheritance() {
+ Derived d;
+ memset(&d, 0, sizeof(Derived));
+ clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
+}
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset2_inheritance_field() {
+ Derived d;
+ memset(&d.d_mem, 0, sizeof(Derived));
+ clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
+}
+
+void memset3_inheritance_field() {
+ Derived d;
+ memset(&d.b_mem, 0, sizeof(Derived));
+ clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
+}
+#endif
+
+void memset4_array_nonpod_object() {
+ Derived array[10];
+ clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}}
+ memset(&array[1], 0, sizeof(Derived));
+ clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{UNKNOWN}}
+}
+
+void memset5_array_nonpod_object() {
+ Derived array[10];
+ clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}}
+ memset(array, 0, sizeof(array));
+ clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{TRUE}}
+}
+
+void memset6_new_array_nonpod_object() {
+ Derived *array = new Derived[10];
+ clang_analyzer_eval(array[2].b_mem == 1); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(array[2].d_mem == 2); // expected-warning{{UNKNOWN}}
+ memset(array, 0, 10 * sizeof(Derived));
+ clang_analyzer_eval(array[2].b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(array[2].d_mem == 0); // expected-warning{{TRUE}}
+ delete[] array;
+}
+
+void memset7_placement_new() {
+ Derived *d = new Derived();
+ clang_analyzer_eval(d->b_mem == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d->d_mem == 2); // expected-warning{{TRUE}}
+
+ memset(d, 0, sizeof(Derived));
+ clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
+
+ Derived *d1 = new (d) Derived();
+ clang_analyzer_eval(d1->b_mem == 1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d1->d_mem == 2); // expected-warning{{TRUE}}
+
+ memset(d1, 0, sizeof(Derived));
+ clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
+}
+
+class BaseVirtual {
+public:
+ int b_mem;
+ virtual int get() { return 1; }
+};
+
+class DerivedVirtual : public BaseVirtual {
+public:
+ int d_mem;
+};
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset8_virtual_inheritance_field() {
+ DerivedVirtual d;
+ memset(&d.b_mem, 0, sizeof(Derived));
+ clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
+}
+#endif
+} // namespace memset_non_pod
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset1_new_array() {
+ int *array = new int[10];
+ memset(array, 0, 10 * sizeof(int));
+ clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
+ memset(array + 1, 'a', 10 * sizeof(9));
+ clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}}
+ delete[] array;
+}
+#endif
diff --git a/clang/test/Analysis/null-deref-ps-region.c b/clang/test/Analysis/null-deref-ps-region.c
index c46ca6c52ae..f5e6956ff72 100644
--- a/clang/test/Analysis/null-deref-ps-region.c
+++ b/clang/test/Analysis/null-deref-ps-region.c
@@ -22,7 +22,7 @@ void f14(int *a) {
void foo() {
int *x = malloc(sizeof(int));
memset(x, 0, sizeof(int));
- int n = 1 / *x; // FIXME: no-warning
+ int n = 1 / *x; // expected-warning {{Division by zero}}
free(x);
}
diff --git a/clang/test/Analysis/string.c b/clang/test/Analysis/string.c
index 57cc4e3cdb8..72a08cc850b 100644
--- a/clang/test/Analysis/string.c
+++ b/clang/test/Analysis/string.c
@@ -1,7 +1,8 @@
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
-// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=alpha.security.taint,core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
+// RUN: %clang_analyze_cc1 -DSUPPRESS_OUT_OF_BOUND -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring.BufferOverlap,alpha.unix.cstring.NotNullTerminated,debug.ExprInspection -analyzer-store=region -Wno-null-dereference -verify %s
//===----------------------------------------------------------------------===
// Declarations
@@ -1160,6 +1161,206 @@ void strsep_changes_input_string() {
}
//===----------------------------------------------------------------------===
+// memset()
+//===----------------------------------------------------------------------===
+
+void *memset(void *dest, int ch, size_t count);
+
+void *malloc(size_t size);
+void free(void *);
+
+void memset1_char_array_null() {
+ char str[] = "abcd";
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
+ memset(str, '\0', 2);
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
+}
+
+void memset2_char_array_null() {
+ char str[] = "abcd";
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
+ memset(str, '\0', strlen(str) + 1);
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(str[2] == 0); // expected-warning{{TRUE}}
+}
+
+void memset3_char_malloc_null() {
+ char *str = (char *)malloc(10 * sizeof(char));
+ memset(str + 1, '\0', 8);
+ clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}}
+ free(str);
+}
+
+void memset4_char_malloc_null() {
+ char *str = (char *)malloc(10 * sizeof(char));
+ //void *str = malloc(10 * sizeof(char));
+ memset(str, '\0', 10);
+ clang_analyzer_eval(str[1] == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
+ free(str);
+}
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset5_char_malloc_overflow_null() {
+ char *str = (char *)malloc(10 * sizeof(char));
+ memset(str, '\0', 12);
+ clang_analyzer_eval(str[1] == 0); // expected-warning{{UNKNOWN}}
+ free(str);
+}
+#endif
+
+void memset6_char_array_nonnull() {
+ char str[] = "abcd";
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
+ memset(str, '0', 2);
+ clang_analyzer_eval(str[0] == 'a'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{UNKNOWN}}
+}
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset8_char_array_nonnull() {
+ char str[5] = "abcd";
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
+ memset(str, '0', 10);
+ clang_analyzer_eval(str[0] != '0'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) < 10); // expected-warning{{FALSE}}
+}
+#endif
+
+struct POD_memset {
+ int num;
+ char c;
+};
+
+void memset10_struct() {
+ struct POD_memset pod;
+ char *str = (char *)&pod;
+ pod.num = 1;
+ pod.c = 1;
+ clang_analyzer_eval(pod.num == 0); // expected-warning{{FALSE}}
+ memset(str, 0, sizeof(struct POD_memset));
+ clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}}
+}
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset11_struct_field() {
+ struct POD_memset pod;
+ pod.num = 1;
+ pod.c = '1';
+ memset(&pod.num, 0, sizeof(struct POD_memset));
+
+ clang_analyzer_eval(pod.num == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(pod.c == '\0'); // expected-warning{{TRUE}}
+}
+
+void memset12_struct_field() {
+ struct POD_memset pod;
+ pod.num = 1;
+ pod.c = '1';
+ memset(&pod.c, 0, sizeof(struct POD_memset));
+ clang_analyzer_eval(pod.num == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(pod.c == 0); // expected-warning{{UNKNOWN}}
+}
+
+union U_memset {
+ int i;
+ double d;
+ char c;
+};
+
+void memset13_union_field() {
+ union U_memset u;
+ u.i = 5;
+ memset(&u.i, '\0', sizeof(union U_memset));
+ // Note: This should be TRUE, analyzer can't handle union perfectly now.
+ clang_analyzer_eval(u.d == 0); // expected-warning{{UNKNOWN}}
+}
+#endif
+
+void memset14_region_cast() {
+ char *str = (char *)malloc(10 * sizeof(int));
+ int *array = (int *)str;
+ memset(array, 0, 10 * sizeof(int));
+ clang_analyzer_eval(str[10] == '\0'); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
+ free(str);
+}
+
+void memset15_region_cast() {
+ char *str = (char *)malloc(10 * sizeof(int));
+ int *array = (int *)str;
+ memset(array, 0, 5 * sizeof(int));
+ clang_analyzer_eval(str[10] == '\0'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen((char *)array) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{TRUE}}
+ free(str);
+}
+
+int memset20_scalar() {
+ int *x = malloc(sizeof(int));
+ *x = 10;
+ memset(x, 0, sizeof(int));
+ int num = 1 / *x; // expected-warning{{Division by zero}}
+ free(x);
+ return num;
+}
+
+int memset21_scalar() {
+ int *x = malloc(sizeof(int));
+ memset(x, 0, 1);
+ int num = 1 / *x;
+ free(x);
+ return num;
+}
+
+void memset22_array() {
+ int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
+ clang_analyzer_eval(array[1] == 2); // expected-warning{{TRUE}}
+ memset(array, 0, sizeof(array));
+ clang_analyzer_eval(array[1] == 0); // expected-warning{{TRUE}}
+}
+
+void memset23_array_pod_object() {
+ struct POD_memset array[10];
+ array[1].num = 10;
+ array[1].c = 'c';
+ clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}}
+ memset(&array[1], 0, sizeof(struct POD_memset));
+ clang_analyzer_eval(array[1].num == 0); // expected-warning{{UNKNOWN}}
+}
+
+void memset24_array_pod_object() {
+ struct POD_memset array[10];
+ array[1].num = 10;
+ array[1].c = 'c';
+ clang_analyzer_eval(array[1].num == 10); // expected-warning{{TRUE}}
+ memset(array, 0, sizeof(array));
+ clang_analyzer_eval(array[1].num == 0); // expected-warning{{TRUE}}
+}
+
+void memset25_symbol(char c) {
+ char array[10] = {1};
+ if (c != 0)
+ return;
+
+ memset(array, c, 10);
+
+ clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}}
+}
+
+void memset26_upper_UCHAR_MAX() {
+ char array[10] = {1};
+
+ memset(array, 1024, 10);
+
+ clang_analyzer_eval(strlen(array) == 0); // expected-warning{{TRUE}}
+ clang_analyzer_eval(array[4] == 0); // expected-warning{{TRUE}}
+}
+
+//===----------------------------------------------------------------------===
// FIXMEs
//===----------------------------------------------------------------------===
@@ -1186,3 +1387,87 @@ void strncpy_exactly_matching_buffer2(char *y) {
// This time, we know that y fits in x anyway.
clang_analyzer_eval(strlen(x) <= 3); // expected-warning{{UNKNOWN}}
}
+
+void memset7_char_array_nonnull() {
+ char str[5] = "abcd";
+ clang_analyzer_eval(strlen(str) == 4); // expected-warning{{TRUE}}
+ memset(str, '0', 5);
+ // FIXME: This should be TRUE.
+ clang_analyzer_eval(str[0] == '0'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen(str) >= 5); // expected-warning{{TRUE}}
+}
+
+void memset16_region_cast() {
+ char *str = (char *)malloc(10 * sizeof(int));
+ int *array = (int *)str;
+ memset(array, '0', 10 * sizeof(int));
+ // FIXME: This should be TRUE.
+ clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen((char *)array) >= 10 * sizeof(int)); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) >= 10 * sizeof(int)); // expected-warning{{TRUE}}
+ free(str);
+}
+
+#ifdef SUPPRESS_OUT_OF_BOUND
+void memset17_region_cast() {
+ char *str = (char *)malloc(10 * sizeof(int));
+ int *array = (int *)str;
+ memset(array, '0', 12 * sizeof(int));
+ clang_analyzer_eval(str[10] == '0'); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(strlen((char *)array) >= 12 * sizeof(int)); // expected-warning{{TRUE}}
+ clang_analyzer_eval(strlen(str) >= 12 * sizeof(int)); // expected-warning{{TRUE}}
+ free(str);
+}
+
+void memset18_memset_multiple_times() {
+ char *str = (char *)malloc(10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
+
+ memset(str + 2, '\0', 10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(str[1] == '\0'); // expected-warning{{UNKNOWN}}
+
+ memset(str, '0', 10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
+ // FIXME: This should be TRUE.
+ clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}}
+
+ free(str);
+}
+
+void memset19_memset_multiple_times() {
+ char *str = (char *)malloc(10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) == 0); // expected-warning{{UNKNOWN}}
+
+ memset(str, '0', 10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{TRUE}}
+ // FIXME: This should be TRUE.
+ clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}}
+
+ memset(str + 2, '\0', 10 * sizeof(char));
+ clang_analyzer_eval(strlen(str) >= 10); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(str[1] == '0'); // expected-warning{{UNKNOWN}}
+
+ free(str);
+}
+#endif
+
+// The analyzer does not support binding a symbol with default binding.
+void memset27_symbol(char c) {
+ char array[10] = {0};
+ if (c < 10)
+ return;
+
+ memset(array, c, 10);
+
+ clang_analyzer_eval(strlen(array) >= 10); // expected-warning{{TRUE}}
+ // FIXME: This should be TRUE.
+ clang_analyzer_eval(array[4] >= 10); // expected-warning{{UNKNOWN}}
+}
+
+void memset28() {
+ short x;
+ memset(&x, 1, sizeof(short));
+ // This should be true.
+ clang_analyzer_eval(x == 0x101); // expected-warning{{UNKNOWN}}
+}
OpenPOWER on IntegriCloud