Index: lib/StaticAnalyzer/Checkers/MallocChecker.cpp =================================================================== --- lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -2511,6 +2511,11 @@ return true; } + if (FName.endswith("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 Index: test/Analysis/Inputs/qt-simulator.h =================================================================== --- test/Analysis/Inputs/qt-simulator.h +++ test/Analysis/Inputs/qt-simulator.h @@ -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 {}; Index: test/Analysis/qt_malloc.cpp =================================================================== --- test/Analysis/qt_malloc.cpp +++ test/Analysis/qt_malloc.cpp @@ -0,0 +1,9 @@ +// 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 *event = new QEvent(QEvent::None); + static_cast(QCoreApplication::instance())->postEvent(obj, event); +}