]> granicus.if.org Git - clang/commitdiff
[analyzer] RetainCountChecker: don't assume all functions have names.
authorJordan Rose <jordan_rose@apple.com>
Fri, 31 Aug 2012 18:19:18 +0000 (18:19 +0000)
committerJordan Rose <jordan_rose@apple.com>
Fri, 31 Aug 2012 18:19:18 +0000 (18:19 +0000)
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

lib/StaticAnalyzer/Checkers/MallocSizeofChecker.cpp
lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
test/Analysis/retain-release.mm

index 6292a4725128a4ff0b3fa7ece3fc5e919b2d99de..05de7b811182b76623a107aab65fea40e4800e7f 100644 (file)
@@ -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;
index 6710bfd3a5bf7084ece4185997ff5541ea8d8809..94e905cbf1229a0f4c1e3512160603bb73f2397d 100644 (file)
@@ -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);
index 01727ea64434b2b66ed33f3d056830cd3f08e589..d92237b185a24c526983a07188803b6fa3cbf497 100644 (file)
@@ -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;
+}
+