In C++, objects being returned on the stack are actually copy-constructed into the return value. That means that when a temporary is returned, it still has to be destroyed, i.e. the returned expression will be wrapped in an ExprWithCleanups node. Our "returning stack memory" checker needs to look through this node to see if we really are returning an object by value. PR13722 llvm-svn: 162817
31 lines
782 B
C++
31 lines
782 B
C++
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -analyzer-ipa=inlining -verify -w %s
|
|
|
|
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 'struct 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 'struct NonTrivial' returned to caller}}
|
|
}
|
|
|