Thread safety analysis: Fix crash for function pointers
authorAaron Puchert <aaronpuchert@alice-dsl.net>
Wed, 19 Sep 2018 00:19:38 +0000 (00:19 +0000)
committerAaron Puchert <aaronpuchert@alice-dsl.net>
Wed, 19 Sep 2018 00:19:38 +0000 (00:19 +0000)
For function pointers, the FunctionDecl of the callee is unknown, so
getDirectCallee will return nullptr. We have to catch that case to avoid
crashing. We assume there is no attribute then.

llvm-svn: 342519

clang/lib/Analysis/ThreadSafetyCommon.cpp
clang/test/SemaCXX/warn-thread-safety-analysis.cpp

index fced17f..ac76580 100644 (file)
@@ -354,15 +354,17 @@ til::SExpr *SExprBuilder::translateCallExpr(const CallExpr *CE,
                                             const Expr *SelfE) {
   if (CapabilityExprMode) {
     // Handle LOCK_RETURNED
-    const FunctionDecl *FD = CE->getDirectCallee()->getMostRecentDecl();
-    if (LockReturnedAttr* At = FD->getAttr<LockReturnedAttr>()) {
-      CallingContext LRCallCtx(Ctx);
-      LRCallCtx.AttrDecl = CE->getDirectCallee();
-      LRCallCtx.SelfArg  = SelfE;
-      LRCallCtx.NumArgs  = CE->getNumArgs();
-      LRCallCtx.FunArgs  = CE->getArgs();
-      return const_cast<til::SExpr *>(
-          translateAttrExpr(At->getArg(), &LRCallCtx).sexpr());
+    if (const FunctionDecl *FD = CE->getDirectCallee()) {
+      FD = FD->getMostRecentDecl();
+      if (LockReturnedAttr *At = FD->getAttr<LockReturnedAttr>()) {
+        CallingContext LRCallCtx(Ctx);
+        LRCallCtx.AttrDecl = CE->getDirectCallee();
+        LRCallCtx.SelfArg = SelfE;
+        LRCallCtx.NumArgs = CE->getNumArgs();
+        LRCallCtx.FunArgs = CE->getArgs();
+        return const_cast<til::SExpr *>(
+            translateAttrExpr(At->getArg(), &LRCallCtx).sexpr());
+      }
     }
   }
 
index deaa7d1..0be2668 100644 (file)
@@ -2323,6 +2323,7 @@ Foo& getBarFoo(Bar &bar, int c) { return bar.getFoo2(c); }
 void test() {
   Foo foo;
   Foo *fooArray;
+  Foo &(*fooFuncPtr)();
   Bar bar;
   int a;
   int b;
@@ -2359,6 +2360,10 @@ void test() {
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Lock();
   (a > 0 ? fooArray[1] : fooArray[b]).a = 0;
   (a > 0 ? fooArray[1] : fooArray[b]).mu_.Unlock();
+
+  fooFuncPtr().mu_.Lock();
+  fooFuncPtr().a = 0;
+  fooFuncPtr().mu_.Unlock();
 }