From c8c70b6d6ed0b2588a66a3e323a83a3c0013cb3b Mon Sep 17 00:00:00 2001 From: Yi Kong Date: Thu, 14 Dec 2017 22:24:45 +0000 Subject: [PATCH] [ThreadSafetyAnalysis] Fix isCapabilityExpr 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 | 9 ++++----- test/Sema/attr-capabilities.cpp | 17 +++++++++++++++++ test/SemaCXX/warn-thread-safety-parsing.cpp | 3 ++- 3 files changed, 23 insertions(+), 6 deletions(-) create mode 100644 test/Sema/attr-capabilities.cpp diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index 36fb6afa24..676d00357c 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -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(Ex)) - return typeHasCapability(S, E->getType()); - else if (const auto *E = dyn_cast(Ex)) + if (const auto *E = dyn_cast(Ex)) return isCapabilityExpr(S, E->getSubExpr()); else if (const auto *E = dyn_cast(Ex)) return isCapabilityExpr(S, E->getSubExpr()); else if (const auto *E = dyn_cast(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(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 index 0000000000..5bae94edaa --- /dev/null +++ b/test/Sema/attr-capabilities.cpp @@ -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; } +}; diff --git a/test/SemaCXX/warn-thread-safety-parsing.cpp b/test/SemaCXX/warn-thread-safety-parsing.cpp index b66c027e52..ac357e8dae 100644 --- a/test/SemaCXX/warn-thread-safety-parsing.cpp +++ b/test/SemaCXX/warn-thread-safety-parsing.cpp @@ -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); // \ -- 2.50.1