forked from OSchip/llvm-project
[analyzer] pr38838, pr39976: Fix crash on diagnosing before implicit destructor.
We need to be able to emit the diagnostic at PreImplicitCall, and the patch implements this functionality. However, for now the need for emitting such diagnostics is not all that great: it is only necessary to not crash when emitting a false positive due to an unrelated issue of having dead symbol collection not working properly. Coming up with a non-false-positive test seems impossible with the current set of checkers, though it is likely to be needed for good things as well in the future. Differential Revision: https://reviews.llvm.org/D56042 rdar://problem/46911462 llvm-svn: 350907
This commit is contained in:
parent
e73c7a1ab2
commit
fc72007f43
|
@ -723,6 +723,8 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
|
||||||
} else if (Optional<PostInitializer> PIP = P.getAs<PostInitializer>()) {
|
} else if (Optional<PostInitializer> PIP = P.getAs<PostInitializer>()) {
|
||||||
return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),
|
return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),
|
||||||
SMng);
|
SMng);
|
||||||
|
} else if (Optional<PreImplicitCall> PIC = P.getAs<PreImplicitCall>()) {
|
||||||
|
return PathDiagnosticLocation(PIC->getLocation(), SMng);
|
||||||
} else if (Optional<PostImplicitCall> PIE = P.getAs<PostImplicitCall>()) {
|
} else if (Optional<PostImplicitCall> PIE = P.getAs<PostImplicitCall>()) {
|
||||||
return PathDiagnosticLocation(PIE->getLocation(), SMng);
|
return PathDiagnosticLocation(PIE->getLocation(), SMng);
|
||||||
} else if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
|
} else if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// RUN: %clang_analyze_cc1 -w -analyzer-checker=core,cplusplus -verify %s
|
||||||
|
|
||||||
|
// expected-no-diagnostics
|
||||||
|
|
||||||
|
namespace no_crash_on_delete_dtor {
|
||||||
|
// We were crashing when producing diagnostics for this code.
|
||||||
|
struct S {
|
||||||
|
void foo();
|
||||||
|
~S();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct smart_ptr {
|
||||||
|
int x;
|
||||||
|
S *s;
|
||||||
|
smart_ptr(S *);
|
||||||
|
S *get() {
|
||||||
|
return (x || 0) ? nullptr : s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void bar(smart_ptr p) {
|
||||||
|
delete p.get();
|
||||||
|
p.get()->foo();
|
||||||
|
}
|
||||||
|
} // namespace no_crash_on_delete_dtor
|
Loading…
Reference in New Issue