]> granicus.if.org Git - clang/commitdiff
[analyzer] pr38838, pr39976: Fix crash on diagnosing before implicit destructor.
authorArtem Dergachev <artem.dergachev@gmail.com>
Thu, 10 Jan 2019 23:44:44 +0000 (23:44 +0000)
committerArtem Dergachev <artem.dergachev@gmail.com>
Thu, 10 Jan 2019 23:44:44 +0000 (23:44 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@350907 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/PathDiagnostic.cpp
test/Analysis/diagnostics/dtors.cpp [new file with mode: 0644]

index 691176dfc1ff2073f384861f25a2517afb008be5..3e93bb6a7c4fc7fa76346a0067925458b950dc48 100644 (file)
@@ -723,6 +723,8 @@ PathDiagnosticLocation::create(const ProgramPoint& P,
   } else if (Optional<PostInitializer> PIP = P.getAs<PostInitializer>()) {
     return PathDiagnosticLocation(PIP->getInitializer()->getSourceLocation(),
                                   SMng);
+  } else if (Optional<PreImplicitCall> PIC = P.getAs<PreImplicitCall>()) {
+    return PathDiagnosticLocation(PIC->getLocation(), SMng);
   } else if (Optional<PostImplicitCall> PIE = P.getAs<PostImplicitCall>()) {
     return PathDiagnosticLocation(PIE->getLocation(), SMng);
   } else if (Optional<CallEnter> CE = P.getAs<CallEnter>()) {
diff --git a/test/Analysis/diagnostics/dtors.cpp b/test/Analysis/diagnostics/dtors.cpp
new file mode 100644 (file)
index 0000000..094917e
--- /dev/null
@@ -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