summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaDeclAttr.cpp9
-rw-r--r--clang/test/Sema/attr-capabilities.cpp17
-rw-r--r--clang/test/SemaCXX/warn-thread-safety-parsing.cpp3
3 files changed, 23 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 36fb6afa246..676d00357c9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/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<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/clang/test/Sema/attr-capabilities.cpp b/clang/test/Sema/attr-capabilities.cpp
new file mode 100644
index 00000000000..5bae94edaa4
--- /dev/null
+++ b/clang/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/clang/test/SemaCXX/warn-thread-safety-parsing.cpp b/clang/test/SemaCXX/warn-thread-safety-parsing.cpp
index b66c027e52a..ac357e8dae3 100644
--- a/clang/test/SemaCXX/warn-thread-safety-parsing.cpp
+++ b/clang/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); // \
OpenPOWER on IntegriCloud