1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config ipa=inlining -analyzer-config c++-allocator-inlining=true -verify -analyzer-config eagerly-assume=false %s
3 void clang_analyzer_eval(bool);
4 void clang_analyzer_checkInlined(bool);
6 typedef __typeof__(sizeof(int)) size_t;
7 extern "C" void *malloc(size_t);
9 // This is the standard placement new.
10 inline void* operator new(size_t, void* __p
) throw()
12 clang_analyzer_checkInlined(true);// expected-warning{{TRUE}}
19 int getZero() { return 0; }
20 virtual int getNum() { return 0; }
24 clang_analyzer_eval(a
.getZero() == 0); // expected-warning{{TRUE}}
25 clang_analyzer_eval(a
.getNum() == 0); // expected-warning{{UNKNOWN}}
28 clang_analyzer_eval(copy
.getZero() == 0); // expected-warning{{TRUE}}
29 clang_analyzer_eval(copy
.getNum() == 0); // expected-warning{{TRUE}}
33 class One
: public A
{
35 virtual int getNum() { return 1; }
38 void testPathSensitivity(int x
) {
54 // This should be true on both branches.
55 clang_analyzer_eval(ptr
->getNum() == x
); // expected-warning {{TRUE}}
59 namespace PureVirtualParent
{
62 virtual int pureVirtual() const = 0;
63 int callVirtual() const {
68 class Child
: public Parent
{
70 virtual int pureVirtual() const {
71 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
79 clang_analyzer_eval(x
.pureVirtual() == 42); // expected-warning{{TRUE}}
80 clang_analyzer_eval(x
.callVirtual() == 42); // expected-warning{{TRUE}}
89 virtual int impl() const = 0;
91 Parent() : m_parent(0) {}
94 int interface() const {
95 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
100 class Child
: public Parent
{
102 virtual int impl() const {
103 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
104 return m_parent
+ m_child
;
108 Child() : m_child(0) {}
117 // Don't crash when inlining and devirtualizing.
122 class Grandchild
: public Child
{};
124 void testDevirtualizeToMiddle() {
128 // Don't crash when inlining and devirtualizing.
133 namespace PR13569_virtual
{
137 virtual int impl() const = 0;
139 Parent() : m_parent(0) {}
142 int interface() const {
143 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
148 class Child
: virtual public Parent
{
150 virtual int impl() const {
151 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
152 return m_parent
+ m_child
;
156 Child() : m_child(0) {}
165 // Don't crash when inlining and devirtualizing.
170 class Grandchild
: virtual public Child
{};
172 void testDevirtualizeToMiddle() {
176 // Don't crash when inlining and devirtualizing.
181 namespace Invalidation
{
183 void touch(int &x
) const {
187 void touch2(int &x
) const;
189 virtual void touchV(int &x
) const {
193 virtual void touchV2(int &x
) const;
196 // We were accidentally not invalidating under inlining
197 // at one point for virtual methods with visible definitions.
203 return a
+ b
+ c
+ d
; // no-warning
208 namespace DefaultArgs
{
209 int takesDefaultArgs(int i
= 42) {
213 void testFunction() {
214 clang_analyzer_eval(takesDefaultArgs(1) == -1); // expected-warning{{TRUE}}
215 clang_analyzer_eval(takesDefaultArgs() == -42); // expected-warning{{TRUE}}
220 static const int value
= 40 + 2;
221 int get(int i
= value
) {
228 clang_analyzer_eval(obj
.get(1) == 1); // expected-warning{{TRUE}}
229 clang_analyzer_eval(obj
.get() == 42); // expected-warning{{TRUE}}
230 clang_analyzer_eval(Secret::value
== 42); // expected-warning{{TRUE}}
239 int enumUser(ABC input
= B
) {
240 return static_cast<int>(input
);
244 clang_analyzer_eval(enumUser(C
) == 2); // expected-warning{{TRUE}}
245 clang_analyzer_eval(enumUser() == 1); // expected-warning{{TRUE}}
249 int exprUser(int input
= 2 * 4) {
253 int complicatedExprUser(int input
= 2 * Secret::value
) {
258 clang_analyzer_eval(exprUser(1) == 1); // expected-warning{{TRUE}}
259 clang_analyzer_eval(exprUser() == 8); // expected-warning{{TRUE}}
261 clang_analyzer_eval(complicatedExprUser(1) == 1); // expected-warning{{TRUE}}
262 clang_analyzer_eval(complicatedExprUser() == 84); // expected-warning{{TRUE}}
265 int defaultReference(const int &input
= 42) {
268 int defaultReferenceZero(const int &input
= 0) {
272 void testReference() {
273 clang_analyzer_eval(defaultReference(1) == -1); // expected-warning{{TRUE}}
274 clang_analyzer_eval(defaultReference() == -42); // expected-warning{{TRUE}}
276 clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
277 clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
280 double defaultFloatReference(const double &i
= 42) {
283 double defaultFloatReferenceZero(const double &i
= 0) {
287 void testFloatReference() {
288 clang_analyzer_eval(defaultFloatReference(1) == -1); // expected-warning{{UNKNOWN}}
289 clang_analyzer_eval(defaultFloatReference() == -42); // expected-warning{{UNKNOWN}}
291 clang_analyzer_eval(defaultFloatReferenceZero(1) == -1); // expected-warning{{UNKNOWN}}
292 clang_analyzer_eval(defaultFloatReferenceZero() == 0); // expected-warning{{UNKNOWN}}
295 char defaultString(const char *s
= "abc") {
300 clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
301 clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
304 const void * const void_string
= "abc";
306 void testBitcastedString() {
307 clang_analyzer_eval(0 != void_string
); // expected-warning{{TRUE}}
308 clang_analyzer_eval('b' == ((char *)void_string
)[1]); // expected-warning{{TRUE}}
312 namespace OperatorNew
{
317 IntWrapper(int input
) : value(input
) {
318 clang_analyzer_checkInlined(true); // expected-warning{{TRUE}}
323 IntWrapper
*obj
= new IntWrapper(42);
324 clang_analyzer_eval(obj
->value
== 42); // expected-warning{{TRUE}}
328 void testPlacement() {
329 IntWrapper
*obj
= static_cast<IntWrapper
*>(malloc(sizeof(IntWrapper
)));
330 IntWrapper
*alias
= new (obj
) IntWrapper(42);
332 clang_analyzer_eval(alias
== obj
); // expected-warning{{TRUE}}
334 clang_analyzer_eval(obj
->value
== 42); // expected-warning{{TRUE}}
335 // Because malloc() was never free()d:
336 // expected-warning@-2{{Potential leak of memory pointed to by 'alias'}}
341 namespace VirtualWithSisterCasts
{
342 // This entire set of tests exercises casts from sister classes and
343 // from classes outside the hierarchy, which can very much confuse
344 // code that uses DynamicTypeInfo or needs to construct CXXBaseObjectRegions.
345 // These examples used to cause crashes in +Asserts builds.
352 virtual int foo() { return 42; }
359 struct Grandchild
: public A
{};
363 void testDowncast(Parent
*b
) {
364 A
*a
= (A
*)(void *)b
;
365 clang_analyzer_eval(a
->foo() == 42); // expected-warning{{UNKNOWN}}
368 clang_analyzer_eval(a
->x
== 42); // expected-warning{{TRUE}}
371 void testRelated(B
*b
) {
372 A
*a
= (A
*)(void *)b
;
373 clang_analyzer_eval(a
->foo() == 42); // expected-warning{{UNKNOWN}}
376 clang_analyzer_eval(a
->x
== 42); // expected-warning{{TRUE}}
379 void testUnrelated(Unrelated
*b
) {
380 A
*a
= (A
*)(void *)b
;
381 clang_analyzer_eval(a
->foo() == 42); // expected-warning{{UNKNOWN}}
384 clang_analyzer_eval(a
->x
== 42); // expected-warning{{TRUE}}
387 void testCastViaNew(B
*b
) {
388 Grandchild
*g
= new (b
) Grandchild();
389 clang_analyzer_eval(g
->foo() == 42); // expected-warning{{TRUE}}
392 clang_analyzer_eval(g
->x
== 42); // expected-warning{{TRUE}}
397 namespace QualifiedCalls
{
398 void test(One
*object
) {
399 // This uses the One class from the top of the file.
400 clang_analyzer_eval(object
->getNum() == 1); // expected-warning{{UNKNOWN}}
401 clang_analyzer_eval(object
->One::getNum() == 1); // expected-warning{{TRUE}}
402 clang_analyzer_eval(object
->A::getNum() == 0); // expected-warning{{TRUE}}
404 // getZero is non-virtual.
405 clang_analyzer_eval(object
->getZero() == 0); // expected-warning{{TRUE}}
406 clang_analyzer_eval(object
->One::getZero() == 0); // expected-warning{{TRUE}}
407 clang_analyzer_eval(object
->A::getZero() == 0); // expected-warning{{TRUE}}
412 namespace rdar12409977
{
417 struct Parent
: public Base
{
418 virtual Parent
*vGetThis();
419 Parent
*getThis() { return vGetThis(); }
422 struct Child
: public Parent
{
423 virtual Child
*vGetThis() { return this; }
430 // Originally, calling a devirtualized method with a covariant return type
431 // caused a crash because the return value had the wrong type. When we then
432 // go to layer a CXXBaseObjectRegion on it, the base isn't a direct base of
433 // the object region and we get an assertion failure.
434 clang_analyzer_eval(obj
.getThis()->x
== 42); // expected-warning{{TRUE}}
439 void one_argument(int a
) { }
440 void call_with_less() {
441 reinterpret_cast<void (*)()>(one_argument
)(); // expected-warning{{Function taking 1 argument is called with fewer (0)}}