1651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// RUN: %clang_cc1 -fsyntax-only -Wthread-safety -verify %s
2651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
3651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestypedef int __attribute__((capability("role"))) ThreadRole;
4651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((shared_capability("mutex"))) Mutex {};
5651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct NotACapability {};
6651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
7651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines// Test an invalid capability name
8651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((capability("wrong"))) IncorrectName {}; // expected-warning {{invalid capability name 'wrong'; capability name must be 'mutex' or 'role'}}
9651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
10651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint Test1 __attribute__((capability("test1")));  // expected-error {{'capability' attribute only applies to structs or typedefs}}
11651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint Test2 __attribute__((shared_capability("test2"))); // expected-error {{'shared_capability' attribute only applies to structs or typedefs}}
12651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint Test3 __attribute__((acquire_capability("test3")));  // expected-warning {{'acquire_capability' attribute only applies to functions}}
13651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint Test4 __attribute__((try_acquire_capability("test4"))); // expected-error {{'try_acquire_capability' attribute only applies to functions}}
14651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesint Test5 __attribute__((release_capability("test5"))); // expected-warning {{'release_capability' attribute only applies to functions}}
15651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
16651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((capability(12))) Test3 {}; // expected-error {{'capability' attribute requires a string}}
17651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((shared_capability(Test2))) Test4 {}; // expected-error {{'shared_capability' attribute requires a string}}
18651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
19651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((capability)) Test5 {}; // expected-error {{'capability' attribute takes one argument}}
20651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct __attribute__((shared_capability("test1", 12))) Test6 {}; // expected-error {{'shared_capability' attribute takes one argument}}
21651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
22651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesstruct NotACapability BadCapability;
23651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesThreadRole GUI, Worker;
24651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func1(void) __attribute__((requires_capability(GUI))) {}
25651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func2(void) __attribute__((requires_shared_capability(Worker))) {}
26651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
27651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func3(void) __attribute__((requires_capability)) {}  // expected-error {{'requires_capability' attribute takes at least 1 argument}}
28651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func4(void) __attribute__((requires_shared_capability)) {}  // expected-error {{'requires_shared_capability' attribute takes at least 1 argument}}
29651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
30651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func5(void) __attribute__((requires_capability(1))) {}  // expected-warning {{'requires_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
31651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func6(void) __attribute__((requires_shared_capability(BadCapability))) {}  // expected-warning {{'requires_shared_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'struct NotACapability'}}
32651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
33651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func7(void) __attribute__((assert_capability(GUI))) {}
34651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func8(void) __attribute__((assert_shared_capability(GUI))) {}
35651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
36651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func9(void) __attribute__((assert_capability())) {} // expected-error {{'assert_capability' attribute takes one argument}}
37651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func10(void) __attribute__((assert_shared_capability())) {} // expected-error {{'assert_shared_capability' attribute takes one argument}}
38651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
39651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func11(void) __attribute__((acquire_capability(GUI))) {}
40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func12(void) __attribute__((acquire_shared_capability(GUI))) {}
41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func15(void) __attribute__((release_capability(GUI))) {}
43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func16(void) __attribute__((release_shared_capability(GUI))) {}
44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func17(void) __attribute__((release_generic_capability(GUI))) {}
45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func21(void) __attribute__((try_acquire_capability(1))) {}
47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func22(void) __attribute__((try_acquire_shared_capability(1))) {}
48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func23(void) __attribute__((try_acquire_capability(1, GUI))) {}
50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func24(void) __attribute__((try_acquire_shared_capability(1, GUI))) {}
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinesvoid Func25(void) __attribute__((try_acquire_capability())) {} // expected-error {{'try_acquire_capability' attribute takes at least 1 argument}}
536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func26(void) __attribute__((try_acquire_shared_capability())) {} // expected-error {{'try_acquire_shared_capability' attribute takes at least 1 argument}}
546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines// Test that boolean logic works with capability attributes
566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func27(void) __attribute__((requires_capability(!GUI)));
576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func28(void) __attribute__((requires_capability(GUI && Worker)));
586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func29(void) __attribute__((requires_capability(GUI || Worker)));
596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func30(void) __attribute__((requires_capability((Worker || Worker) && !GUI)));
606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines
616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesint AlsoNotACapability;
626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid Func31(void) __attribute__((requires_capability(GUI && AlsoNotACapability))); // expected-warning {{'requires_capability' attribute requires arguments whose type is annotated with 'capability' attribute; type here is 'int'}}
63