]> granicus.if.org Git - clang/commitdiff
[ThreadSafetyAnalysis] Fix isCapabilityExpr
authorYi Kong <yikong@google.com>
Thu, 14 Dec 2017 22:24:45 +0000 (22:24 +0000)
committerYi Kong <yikong@google.com>
Thu, 14 Dec 2017 22:24:45 +0000 (22:24 +0000)
There are many more expr types that can be a capability expr, like
CXXThisExpr, CallExpr, MemberExpr. Instead of enumerating all of them,
just check typeHasCapability for any type given.

Also add & and * operators to allowed unary operators.

Differential Revision: https://reviews.llvm.org/D41224

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320753 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDeclAttr.cpp
test/Sema/attr-capabilities.cpp [new file with mode: 0644]
test/SemaCXX/warn-thread-safety-parsing.cpp

index 36fb6afa2467e77bffccb5e056154ed1e614aea3..676d00357c960fe542da51cadb597dd1ef9abb4c 100644 (file)
@@ -540,14 +540,13 @@ static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
   // a DeclRefExpr is found, its type should be checked to determine whether it
   // is a capability or not.
 
-  if (const auto *E = dyn_cast<DeclRefExpr>(Ex))
-    return typeHasCapability(S, E->getType());
-  else if (const auto *E = dyn_cast<CastExpr>(Ex))
+  if (const auto *E = dyn_cast<CastExpr>(Ex))
     return isCapabilityExpr(S, E->getSubExpr());
   else if (const auto *E = dyn_cast<ParenExpr>(Ex))
     return isCapabilityExpr(S, E->getSubExpr());
   else if (const auto *E = dyn_cast<UnaryOperator>(Ex)) {
-    if (E->getOpcode() == UO_LNot)
+    if (E->getOpcode() == UO_LNot || E->getOpcode() == UO_AddrOf ||
+        E->getOpcode() == UO_Deref)
       return isCapabilityExpr(S, E->getSubExpr());
     return false;
   } else if (const auto *E = dyn_cast<BinaryOperator>(Ex)) {
@@ -557,7 +556,7 @@ static bool isCapabilityExpr(Sema &S, const Expr *Ex) {
     return false;
   }
 
-  return false;
+  return typeHasCapability(S, Ex->getType());
 }
 
 /// \brief Checks that all attribute arguments, starting from Sidx, resolve to
diff --git a/test/Sema/attr-capabilities.cpp b/test/Sema/attr-capabilities.cpp
new file mode 100644 (file)
index 0000000..5bae94e
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
+
+class __attribute__((shared_capability("mutex"))) Mutex {
+ public:
+  void func1() __attribute__((assert_capability(this)));
+  void func2() __attribute__((assert_capability(!this)));
+
+  const Mutex& operator!() const { return *this; }
+};
+
+class NotACapability {
+ public:
+  void func1() __attribute__((assert_capability(this)));  // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'NotACapability *'}}
+  void func2() __attribute__((assert_capability(!this)));  // expected-warning {{'assert_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'bool'}}
+
+  const NotACapability& operator!() const { return *this; }
+};
index b66c027e52a8f5478053ed0c7790c2f65c7225d4..ac357e8dae375c6bf94b859b06a438da5ce57171 100644 (file)
@@ -351,7 +351,8 @@ int gb_var_arg_5 GUARDED_BY(&mu1);
 int gb_var_arg_6 GUARDED_BY(muRef);
 int gb_var_arg_7 GUARDED_BY(muDoubleWrapper.getWrapper()->getMu());
 int gb_var_arg_8 GUARDED_BY(muPointer);
-
+int gb_var_arg_9 GUARDED_BY(!&mu1);
+int gb_var_arg_10 GUARDED_BY(!&*&mu1);
 
 // illegal attribute arguments
 int gb_var_arg_bad_1 GUARDED_BY(1); // \