mirror of https://github.com/microsoft/clang.git
[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
This commit is contained in:
parent
8387eb5f32
commit
c8c70b6d6e
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
};
|
|
@ -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); // \
|
||||
|
|
Loading…
Reference in New Issue