]> granicus.if.org Git - clang/commitdiff
[analyzer] Fix false warning about memory leak for QApplication::postEvent
authorAnna Zaks <ganna@apple.com>
Wed, 6 Jan 2016 00:32:56 +0000 (00:32 +0000)
committerAnna Zaks <ganna@apple.com>
Wed, 6 Jan 2016 00:32:56 +0000 (00:32 +0000)
According to Qt documentation Qt takes care of memory allocated for QEvent:
http://doc.qt.io/qt-4.8/qcoreapplication.html#postEvent

A patch by Evgeniy Dushistov!

Differential Revision: http://reviews.llvm.org/D14170

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

lib/StaticAnalyzer/Checkers/MallocChecker.cpp
test/Analysis/Inputs/qt-simulator.h [new file with mode: 0644]
test/Analysis/qt_malloc.cpp [new file with mode: 0644]

index 713d9fe285a5e1e8c4166c74c71bb02d507a18df..ce2c19409dc1e91703bf135e179aca45037ef0a3 100644 (file)
@@ -2508,6 +2508,16 @@ bool MallocChecker::mayFreeAnyEscapedMemoryOrIsModeledExplicitly(
     return true;
   }
 
+  if (FName == "postEvent" &&
+      FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
+    return true;
+  }
+
+  if (FName == "postEvent" &&
+      FD->getQualifiedNameAsString() == "QCoreApplication::postEvent") {
+    return true;
+  }
+
   // Handle cases where we know a buffer's /address/ can escape.
   // Note that the above checks handle some special cases where we know that
   // even though the address escapes, it's still our responsibility to free the
diff --git a/test/Analysis/Inputs/qt-simulator.h b/test/Analysis/Inputs/qt-simulator.h
new file mode 100644 (file)
index 0000000..d1d6c03
--- /dev/null
@@ -0,0 +1,16 @@
+#pragma clang system_header
+
+struct QObject {
+};
+
+struct QEvent {
+  enum Type { None };
+  QEvent(Type) {}
+};
+
+struct QCoreApplication : public QObject {
+  static void postEvent(QObject *receiver, QEvent *event);
+  static QCoreApplication *instance();
+};
+
+struct QApplication : public QCoreApplication {};
diff --git a/test/Analysis/qt_malloc.cpp b/test/Analysis/qt_malloc.cpp
new file mode 100644 (file)
index 0000000..d29835f
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.deadcode.UnreachableCode,alpha.core.CastSize,unix.Malloc,cplusplus -analyzer-store=region -verify %s
+// expected-no-diagnostics
+#include "Inputs/qt-simulator.h"
+
+void send(QObject *obj)
+{
+  QEvent *e1 = new QEvent(QEvent::None);
+  static_cast<QApplication *>(QCoreApplication::instance())->postEvent(obj, e1);
+  QEvent *e2 = new QEvent(QEvent::None);
+  QCoreApplication::instance()->postEvent(obj, e2);
+  QEvent *e3 = new QEvent(QEvent::None);
+  QCoreApplication::postEvent(obj, e3);
+  QEvent *e4 = new QEvent(QEvent::None);
+  QApplication::postEvent(obj, e4);
+}