}
bool ThreadSafetyAnalyzer::inCurrentScope(const CapabilityExpr &CapE) {
- const threadSafety::til::SExpr *SExp = CapE.sexpr();
- assert(SExp && "Null expressions should be ignored");
-
- // Global variables are always in scope.
- if (isa<til::LiteralPtr>(SExp))
- return true;
-
- // Members are in scope from methods of the same class.
- if (const auto *P = dyn_cast<til::Project>(SExp)) {
- if (!CurrentMethod)
+ if (!CurrentMethod)
return false;
- const ValueDecl *VD = P->clangDecl();
- return VD->getDeclContext() == CurrentMethod->getDeclContext();
+ if (const auto *P = dyn_cast_or_null<til::Project>(CapE.sexpr())) {
+ const auto *VD = P->clangDecl();
+ if (VD)
+ return VD->getDeclContext() == CurrentMethod->getDeclContext();
}
-
return false;
}
const auto *VD = cast<ValueDecl>(DRE->getDecl()->getCanonicalDecl());
// Function parameters require substitution and/or renaming.
- if (const auto *PV = dyn_cast<ParmVarDecl>(VD)) {
+ if (const auto *PV = dyn_cast_or_null<ParmVarDecl>(VD)) {
unsigned I = PV->getFunctionScopeIndex();
const DeclContext *D = PV->getDeclContext();
if (Ctx && Ctx->FunArgs) {
}
extern const char *deque_log_msg(void) __attribute__((requires_capability(Logger)));
-void logger_entry(void) __attribute__((requires_capability(Logger)))
- __attribute__((requires_capability(!FlightControl))) {
+void logger_entry(void) __attribute__((requires_capability(Logger))) {
const char *msg;
while ((msg = deque_log_msg())) {
}
}
-void spawn_fake_logger_thread(void) __attribute__((requires_capability(!FlightControl))) {
+void spawn_fake_logger_thread(void) {
acquire(Logger);
logger_entry();
release(Logger);
}
-int main(void) __attribute__((requires_capability(!FlightControl))) {
+int main(void) {
spawn_fake_flight_control_thread();
spawn_fake_logger_thread();
} // end namespace SimpleTest
-Mutex globalMutex;
-
-namespace ScopeTest {
-
-void f() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex);
-void fq() EXCLUSIVE_LOCKS_REQUIRED(!::globalMutex);
-
-namespace ns {
- Mutex globalMutex;
- void f() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex);
- void fq() EXCLUSIVE_LOCKS_REQUIRED(!ns::globalMutex);
-}
-
-void testGlobals() EXCLUSIVE_LOCKS_REQUIRED(!ns::globalMutex) {
- f(); // expected-warning {{calling function 'f' requires negative capability '!globalMutex'}}
- fq(); // expected-warning {{calling function 'fq' requires negative capability '!globalMutex'}}
- ns::f();
- ns::fq();
-}
-
-void testNamespaceGlobals() EXCLUSIVE_LOCKS_REQUIRED(!globalMutex) {
- f();
- fq();
- ns::f(); // expected-warning {{calling function 'f' requires negative capability '!globalMutex'}}
- ns::fq(); // expected-warning {{calling function 'fq' requires negative capability '!globalMutex'}}
-}
-
-} // end namespace ScopeTest
-
namespace DoubleAttribute {
struct Foo {