1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 
3 #define PLACE_IN_TCB(NAME) __attribute__ ((enforce_tcb(NAME)))
4 #define PLACE_IN_TCB_LEAF(NAME) __attribute__ ((enforce_tcb_leaf(NAME)))
5 
6 void foo1 (void) PLACE_IN_TCB("bar");
7 void foo2 (void) PLACE_IN_TCB("bar");
8 void foo3 (void); // not in any TCB
9 void foo4 (void) PLACE_IN_TCB("bar2");
10 void foo5 (void) PLACE_IN_TCB_LEAF("bar");
11 void foo6 (void) PLACE_IN_TCB("bar2") PLACE_IN_TCB("bar");
12 void foo7 (void) PLACE_IN_TCB("bar3");
13 void foo8 (void) PLACE_IN_TCB("bar") PLACE_IN_TCB("bar2");
14 void foo9 (void);
15 
foo1()16 void foo1() {
17     foo2(); // OK - function in same TCB
18     foo3(); // expected-warning {{calling 'foo3' is a violation of trusted computing base 'bar'}}
19     foo4(); // expected-warning {{calling 'foo4' is a violation of trusted computing base 'bar'}}
20     foo5(); // OK - in leaf node
21     foo6(); // OK - in multiple TCBs, one of which is the same
22     foo7(); // expected-warning {{calling 'foo7' is a violation of trusted computing base 'bar'}}
23     (void) __builtin_clz(5); // OK - builtins are excluded
24 }
25 
26 // Normal use without any attributes works
foo3()27 void foo3() {
28     foo9(); // no-warning
29 }
30 
foo5()31 void foo5() {
32     // all calls should be okay, function in TCB leaf
33     foo2(); // no-warning
34     foo3(); // no-warning
35     foo4(); // no-warning
36 }
37 
foo6()38 void foo6() {
39     foo1(); // expected-warning {{calling 'foo1' is a violation of trusted computing base 'bar2'}}
40     foo4(); // expected-warning {{calling 'foo4' is a violation of trusted computing base 'bar'}}
41     foo8(); // no-warning
42     foo7(); // #1
43     // expected-warning@#1 {{calling 'foo7' is a violation of trusted computing base 'bar2'}}
44     // expected-warning@#1 {{calling 'foo7' is a violation of trusted computing base 'bar'}}
45 }
46 
47 // Ensure that attribute merging works as expected across redeclarations.
48 void foo10() PLACE_IN_TCB("bar");
49 void foo10() PLACE_IN_TCB("bar2");
50 void foo10() PLACE_IN_TCB("bar3");
foo10()51 void foo10() {
52   foo1(); // #2
53     // expected-warning@#2 {{calling 'foo1' is a violation of trusted computing base 'bar2'}}
54     // expected-warning@#2 {{calling 'foo1' is a violation of trusted computing base 'bar3'}}
55   foo3(); // #3
56     // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar'}}
57     // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar2'}}
58     // expected-warning@#3 {{calling 'foo3' is a violation of trusted computing base 'bar3'}}
59   foo4(); // #4
60     // expected-warning@#4 {{calling 'foo4' is a violation of trusted computing base 'bar'}}
61     // expected-warning@#4 {{calling 'foo4' is a violation of trusted computing base 'bar3'}}
62   foo7(); // #5
63     // expected-warning@#5 {{calling 'foo7' is a violation of trusted computing base 'bar'}}
64     // expected-warning@#5 {{calling 'foo7' is a violation of trusted computing base 'bar2'}}
65 }
66