1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s
2 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -analyzer-checker=core,unix.cstring,unix.Malloc,alpha.unix.cstring,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s
3 // RUN: %clang_analyze_cc1 -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s
4 // RUN: %clang_analyze_cc1 -DUSE_BUILTINS -DVARIANT -analyzer-checker=core,unix.cstring,alpha.unix.cstring,unix.Malloc,debug.ExprInspection -analyzer-store=region -verify -analyzer-config eagerly-assume=false %s
5 // 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 -analyzer-config eagerly-assume=false %s
6 
7 #include "Inputs/system-header-simulator-cxx.h"
8 #include "Inputs/system-header-simulator-for-malloc.h"
9 
10 // This provides us with four possible mempcpy() definitions.
11 // See also comments in bstring.c.
12 
13 #ifdef USE_BUILTINS
14 #define BUILTIN(f) __builtin_##f
15 #else /* USE_BUILTINS */
16 #define BUILTIN(f) f
17 #endif /* USE_BUILTINS */
18 
19 #ifdef VARIANT
20 
21 #define __mempcpy_chk BUILTIN(__mempcpy_chk)
22 void *__mempcpy_chk(void *__restrict__ s1, const void *__restrict__ s2,
23                     size_t n, size_t destlen);
24 
25 #define mempcpy(a,b,c) __mempcpy_chk(a,b,c,(size_t)-1)
26 
27 #else /* VARIANT */
28 
29 #define mempcpy BUILTIN(mempcpy)
30 void *mempcpy(void *__restrict__ s1, const void *__restrict__ s2, size_t n);
31 
32 #endif /* VARIANT */
33 
34 void clang_analyzer_eval(int);
35 
testStdCopyInvalidatesBuffer(std::vector<int> v)36 int *testStdCopyInvalidatesBuffer(std::vector<int> v) {
37   int n = v.size();
38   int *buf = (int *)malloc(n * sizeof(int));
39 
40   buf[0] = 66;
41 
42   // Call to copy should invalidate buf.
43   std::copy(v.begin(), v.end(), buf);
44 
45   int i = buf[0];
46 
47   clang_analyzer_eval(i == 66); // expected-warning {{UNKNOWN}}
48 
49   return buf;
50 }
51 
testStdCopyBackwardInvalidatesBuffer(std::vector<int> v)52 int *testStdCopyBackwardInvalidatesBuffer(std::vector<int> v) {
53   int n = v.size();
54   int *buf = (int *)malloc(n * sizeof(int));
55 
56   buf[0] = 66;
57 
58   // Call to copy_backward should invalidate buf.
59   std::copy_backward(v.begin(), v.end(), buf + n);
60 
61   int i = buf[0];
62 
63   clang_analyzer_eval(i == 66); // expected-warning {{UNKNOWN}}
64 
65   return buf;
66 }
67 
68 namespace pr34460 {
69 short a;
70 class b {
71   int c;
72   long g;
d()73   void d() {
74     int e = c;
75     f += e;
76     mempcpy(f, &a, g);
77   }
78   unsigned *f;
79 };
80 }
81 
82 void *memset(void *dest, int ch, std::size_t count);
83 namespace memset_non_pod {
84 class Base {
85 public:
86   int b_mem;
Base()87   Base() : b_mem(1) {}
88 };
89 
90 class Derived : public Base {
91 public:
92   int d_mem;
Derived()93   Derived() : d_mem(2) {}
94 };
95 
memset1_inheritance()96 void memset1_inheritance() {
97   Derived d;
98   memset(&d, 0, sizeof(Derived));
99   clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
100   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
101 }
102 
103 #ifdef SUPPRESS_OUT_OF_BOUND
memset2_inheritance_field()104 void memset2_inheritance_field() {
105   Derived d;
106   memset(&d.d_mem, 0, sizeof(Derived));
107   clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
108   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
109 }
110 
memset3_inheritance_field()111 void memset3_inheritance_field() {
112   Derived d;
113   memset(&d.b_mem, 0, sizeof(Derived));
114   clang_analyzer_eval(d.b_mem == 0); // expected-warning{{TRUE}}
115   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{TRUE}}
116 }
117 #endif
118 
memset4_array_nonpod_object()119 void memset4_array_nonpod_object() {
120   Derived array[10];
121   clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
122   clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}}
123   memset(&array[1], 0, sizeof(Derived));
124   clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{UNKNOWN}}
125   clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{UNKNOWN}}
126 }
127 
memset5_array_nonpod_object()128 void memset5_array_nonpod_object() {
129   Derived array[10];
130   clang_analyzer_eval(array[1].b_mem == 1); // expected-warning{{UNKNOWN}}
131   clang_analyzer_eval(array[1].d_mem == 2); // expected-warning{{UNKNOWN}}
132   memset(array, 0, sizeof(array));
133   clang_analyzer_eval(array[1].b_mem == 0); // expected-warning{{TRUE}}
134   clang_analyzer_eval(array[1].d_mem == 0); // expected-warning{{TRUE}}
135 }
136 
memset6_new_array_nonpod_object()137 void memset6_new_array_nonpod_object() {
138   Derived *array = new Derived[10];
139   clang_analyzer_eval(array[2].b_mem == 1); // expected-warning{{UNKNOWN}}
140   clang_analyzer_eval(array[2].d_mem == 2); // expected-warning{{UNKNOWN}}
141   memset(array, 0, 10 * sizeof(Derived));
142   clang_analyzer_eval(array[2].b_mem == 0); // expected-warning{{TRUE}}
143   clang_analyzer_eval(array[2].d_mem == 0); // expected-warning{{TRUE}}
144   delete[] array;
145 }
146 
memset7_placement_new()147 void memset7_placement_new() {
148   Derived *d = new Derived();
149   clang_analyzer_eval(d->b_mem == 1); // expected-warning{{TRUE}}
150   clang_analyzer_eval(d->d_mem == 2); // expected-warning{{TRUE}}
151 
152   memset(d, 0, sizeof(Derived));
153   clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}}
154   clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
155 
156   Derived *d1 = new (d) Derived();
157   clang_analyzer_eval(d1->b_mem == 1); // expected-warning{{TRUE}}
158   clang_analyzer_eval(d1->d_mem == 2); // expected-warning{{TRUE}}
159 
160   memset(d1, 0, sizeof(Derived));
161   clang_analyzer_eval(d->b_mem == 0); // expected-warning{{TRUE}}
162   clang_analyzer_eval(d->d_mem == 0); // expected-warning{{TRUE}}
163 }
164 
165 class BaseVirtual {
166 public:
167   int b_mem;
get()168   virtual int get() { return 1; }
169 };
170 
171 class DerivedVirtual : public BaseVirtual {
172 public:
173   int d_mem;
174 };
175 
176 #ifdef SUPPRESS_OUT_OF_BOUND
memset8_virtual_inheritance_field()177 void memset8_virtual_inheritance_field() {
178   DerivedVirtual d;
179   memset(&d.b_mem, 0, sizeof(Derived));
180   clang_analyzer_eval(d.b_mem == 0); // expected-warning{{UNKNOWN}}
181   clang_analyzer_eval(d.d_mem == 0); // expected-warning{{UNKNOWN}}
182 }
183 #endif
184 } // namespace memset_non_pod
185 
186 #ifdef SUPPRESS_OUT_OF_BOUND
memset1_new_array()187 void memset1_new_array() {
188   int *array = new int[10];
189   memset(array, 0, 10 * sizeof(int));
190   clang_analyzer_eval(array[2] == 0); // expected-warning{{TRUE}}
191   memset(array + 1, 'a', 10 * sizeof(9));
192   clang_analyzer_eval(array[2] == 0); // expected-warning{{UNKNOWN}}
193   delete[] array;
194 }
195 #endif
196