From a89f719ad3a7134e3eec7c9e03aa0e22031c0de9 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 31 Aug 2012 18:19:18 +0000 Subject: [PATCH] [analyzer] RetainCountChecker: don't assume all functions have names. Fixes a hard-to-reach crash when calling a non-member overloaded operator with arguments that may be callbacks. Future-proofing: don't make the same assumption in MallocSizeofChecker. Aside from possibly respecting attributes in the future, it might be possible to call 'malloc' through a function pointer. I audited all other uses of FunctionDecl::getIdentifier() in the analyzer; they all now correctly test to see if the identifier is present before using it. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163012 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/MallocSizeofChecker.cpp | 10 +++++++--- .../Checkers/RetainCountChecker.cpp | 5 +++-- test/Analysis/retain-release.mm | 19 +++++++++++++++++++ 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp index 6292a47251..05de7b8111 100644 --- a/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp @@ -196,9 +196,13 @@ public: SmallString<64> buf; llvm::raw_svector_ostream OS(buf); - OS << "Result of '" - << i->AllocCall->getDirectCallee()->getIdentifier()->getName() - << "' is converted to a pointer of type '" + OS << "Result of "; + const FunctionDecl *Callee = i->AllocCall->getDirectCallee(); + if (Callee && Callee->getIdentifier()) + OS << '\'' << Callee->getIdentifier()->getName() << '\''; + else + OS << "call"; + OS << " is converted to a pointer of type '" << PointeeType.getAsString() << "', which is incompatible with " << "sizeof operand type '" << SizeofType.getAsString() << "'"; llvm::SmallVector Ranges; diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 6710bfd3a5..94e905cbf1 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -950,8 +950,9 @@ void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S, IdentifierInfo *Name = FC->getDecl()->getIdentifier(); // This callback frees the associated buffer. - if (Name->isStr("CGBitmapContextCreateWithData")) - RE = S->getRetEffect(); + if (Name) + if (Name->isStr("CGBitmapContextCreateWithData")) + RE = S->getRetEffect(); } S = getPersistentSummary(RE, RecEffect, DefEffect); diff --git a/test/Analysis/retain-release.mm b/test/Analysis/retain-release.mm index 01727ea644..d92237b185 100644 --- a/test/Analysis/retain-release.mm +++ b/test/Analysis/retain-release.mm @@ -366,3 +366,22 @@ NSString * radar11152419(NSString *string1, NSString *key1, NSMapTable *map) { return string; } +//===----------------------------------------------------------------------===// +// Don't crash on non-member functions with "callbacks" but without names. +//===----------------------------------------------------------------------===// + +struct IntWrapper { + int arg; +}; + +int operator>> (const IntWrapper &W, int (*f)(int)) { + return f(W.arg); +} + +void testCallback() { + IntWrapper val = { 42 }; + + extern int process(int); + val >> process; +} + -- 2.50.1