blob: da44a795c109e1c5026c5bcf1d2b744bd22b2eea [file] [log] [blame]
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-ipa=inlining -cfg-add-implicit-dtors -Wno-null-dereference -verify %s
void clang_analyzer_eval(bool);
struct Wrapper {
__strong id obj;
};
void test() {
Wrapper w;
// force a diagnostic
*(char *)0 = 1; // expected-warning{{Dereference of null pointer}}
}
struct IntWrapper {
int x;
};
void testCopyConstructor() {
IntWrapper a;
a.x = 42;
IntWrapper b(a);
clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
}
struct NonPODIntWrapper {
int x;
virtual int get();
};
void testNonPODCopyConstructor() {
NonPODIntWrapper a;
a.x = 42;
NonPODIntWrapper b(a);
clang_analyzer_eval(b.x == 42); // expected-warning{{TRUE}}
}
namespace ConstructorVirtualCalls {
class A {
public:
int *out1, *out2, *out3;
virtual int get() { return 1; }
A(int *out1) {
*out1 = get();
}
};
class B : public A {
public:
virtual int get() { return 2; }
B(int *out1, int *out2) : A(out1) {
*out2 = get();
}
};
class C : public B {
public:
virtual int get() { return 3; }
C(int *out1, int *out2, int *out3) : B(out1, out2) {
*out3 = get();
}
};
void test() {
int a, b, c;
C obj(&a, &b, &c);
clang_analyzer_eval(a == 1); // expected-warning{{TRUE}}
clang_analyzer_eval(b == 2); // expected-warning{{TRUE}}
clang_analyzer_eval(c == 3); // expected-warning{{TRUE}}
clang_analyzer_eval(obj.get() == 3); // expected-warning{{TRUE}}
// Sanity check for devirtualization.
A *base = &obj;
clang_analyzer_eval(base->get() == 3); // expected-warning{{TRUE}}
}
}