diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-08-31 18:19:18 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-08-31 18:19:18 +0000 |
commit | d65f1c8d6ebdd070db205f958d647d88b93fcf5b (patch) | |
tree | db951f63ac27dd5201555dd56816856ae326d852 /clang | |
parent | facebca6ba52a8c186d39ed76f5acf00f0876573 (diff) | |
download | bcm5719-llvm-d65f1c8d6ebdd070db205f958d647d88b93fcf5b.tar.gz bcm5719-llvm-d65f1c8d6ebdd070db205f958d647d88b93fcf5b.zip |
[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.
llvm-svn: 163012
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp | 10 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp | 5 | ||||
-rw-r--r-- | clang/test/Analysis/retain-release.mm | 19 |
3 files changed, 29 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp index 6292a472512..05de7b81118 100644 --- a/clang/lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp +++ b/clang/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<SourceRange, 4> Ranges; diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index 6710bfd3a5b..94e905cbf12 100644 --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/clang/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/clang/test/Analysis/retain-release.mm b/clang/test/Analysis/retain-release.mm index 01727ea6443..d92237b185a 100644 --- a/clang/test/Analysis/retain-release.mm +++ b/clang/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; +} + |