forked from OSchip/llvm-project
65 lines
1.7 KiB
C++
65 lines
1.7 KiB
C++
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w %s
|
|
|
|
extern bool clang_analyzer_eval(bool);
|
|
|
|
struct Trivial {
|
|
Trivial(int x) : value(x) {}
|
|
int value;
|
|
};
|
|
|
|
struct NonTrivial : public Trivial {
|
|
NonTrivial(int x) : Trivial(x) {}
|
|
~NonTrivial();
|
|
};
|
|
|
|
|
|
Trivial getTrivial() {
|
|
return Trivial(42); // no-warning
|
|
}
|
|
|
|
const Trivial &getTrivialRef() {
|
|
return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'Trivial' returned to caller}}
|
|
}
|
|
|
|
|
|
NonTrivial getNonTrivial() {
|
|
return NonTrivial(42); // no-warning
|
|
}
|
|
|
|
const NonTrivial &getNonTrivialRef() {
|
|
return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'NonTrivial' returned to caller}}
|
|
}
|
|
|
|
namespace rdar13265460 {
|
|
struct TrivialSubclass : public Trivial {
|
|
TrivialSubclass(int x) : Trivial(x), anotherValue(-x) {}
|
|
int anotherValue;
|
|
};
|
|
|
|
TrivialSubclass getTrivialSub() {
|
|
TrivialSubclass obj(1);
|
|
obj.value = 42;
|
|
obj.anotherValue = -42;
|
|
return obj;
|
|
}
|
|
|
|
void testImmediate() {
|
|
TrivialSubclass obj = getTrivialSub();
|
|
|
|
clang_analyzer_eval(obj.value == 42); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(obj.anotherValue == -42); // expected-warning{{TRUE}}
|
|
|
|
clang_analyzer_eval(getTrivialSub().value == 42); // expected-warning{{TRUE}}
|
|
clang_analyzer_eval(getTrivialSub().anotherValue == -42); // expected-warning{{TRUE}}
|
|
}
|
|
|
|
void testMaterializeTemporaryExpr() {
|
|
const TrivialSubclass &ref = getTrivialSub();
|
|
clang_analyzer_eval(ref.value == 42); // expected-warning{{TRUE}}
|
|
|
|
const Trivial &baseRef = getTrivialSub();
|
|
clang_analyzer_eval(baseRef.value == 42); // expected-warning{{TRUE}}
|
|
}
|
|
}
|
|
|