blob: 4f800d5d43be93b6260a085a0c22c345cbd1c562 [file] [log] [blame]
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -cfg-add-implicit-dtors -std=c++11 -verify %s
// We don't inline constructors unless we have destructors turned on.
void clang_analyzer_eval(bool);
class A {
int x;
public:
A();
};
A::A() : x(0) {
clang_analyzer_eval(x == 0); // expected-warning{{TRUE}}
}
class DirectMember {
int x;
public:
DirectMember(int value) : x(value) {}
int getX() { return x; }
};
void testDirectMember() {
DirectMember obj(3);
clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
}
class IndirectMember {
struct {
int x;
};
public:
IndirectMember(int value) : x(value) {}
int getX() { return x; }
};
void testIndirectMember() {
IndirectMember obj(3);
clang_analyzer_eval(obj.getX() == 3); // expected-warning{{TRUE}}
}
struct DelegatingConstructor {
int x;
DelegatingConstructor(int y) { x = y; }
DelegatingConstructor() : DelegatingConstructor(42) {}
};
void testDelegatingConstructor() {
DelegatingConstructor obj;
clang_analyzer_eval(obj.x == 42); // expected-warning{{TRUE}}
}
// ------------------------------------
// False negatives
// ------------------------------------
struct RefWrapper {
RefWrapper(int *p) : x(*p) {}
RefWrapper(int &r) : x(r) {}
int &x;
};
void testReferenceMember() {
int *p = 0;
RefWrapper X(p); // should warn in the constructor
}
void testReferenceMember2() {
int *p = 0;
RefWrapper X(*p); // should warn here
}