1 | // RUN: %check_clang_tidy %s llvmlibc-callee-namespace %t |
2 | |
3 | #define OTHER_MACRO_NAMESPACE custom_namespace |
4 | namespace OTHER_MACRO_NAMESPACE { |
5 | void wrong_name_macro_func() {} |
6 | } |
7 | |
8 | namespace __llvm_libc { |
9 | void right_name_no_macro_func() {} |
10 | } |
11 | |
12 | #define LIBC_NAMESPACE __llvm_libc_xyz |
13 | namespace LIBC_NAMESPACE { |
14 | namespace nested { |
15 | void nested_func() {} |
16 | } // namespace nested |
17 | void libc_api_func() {} |
18 | |
19 | struct libc_api_struct { |
20 | int operator()() const { return 0; } |
21 | }; |
22 | } // namespace __llvm_libc |
23 | |
24 | // Emulate a function from the public headers like string.h |
25 | void libc_api_func() {} |
26 | |
27 | // Emulate a function specifically allowed by the exception list. |
28 | void malloc() {} |
29 | |
30 | // Emulate a non-trivially named symbol. |
31 | struct global_struct { |
32 | int operator()() const { return 0; } |
33 | }; |
34 | |
35 | namespace LIBC_NAMESPACE { |
36 | void Test() { |
37 | // Allow calls with the fully qualified name. |
38 | LIBC_NAMESPACE::libc_api_func(); |
39 | LIBC_NAMESPACE::nested::nested_func(); |
40 | void (*qualifiedPtr)(void) = LIBC_NAMESPACE::libc_api_func; |
41 | qualifiedPtr(); |
42 | |
43 | // Should not trigger on compiler provided function calls. |
44 | (void)__builtin_abs(-1); |
45 | |
46 | // Bare calls are allowed as long as they resolve to the correct namespace. |
47 | libc_api_func(); |
48 | nested::nested_func(); |
49 | void (*barePtr)(void) = LIBC_NAMESPACE::libc_api_func; |
50 | barePtr(); |
51 | |
52 | // Allow calling entities defined in the namespace. |
53 | LIBC_NAMESPACE::libc_api_struct{}(); |
54 | |
55 | // Disallow calling into global namespace for implemented entrypoints. |
56 | ::libc_api_func(); |
57 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'libc_api_func' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro |
58 | // CHECK-MESSAGES: :25:6: note: resolves to this declaration |
59 | |
60 | // Disallow indirect references to functions in global namespace. |
61 | void (*badPtr)(void) = ::libc_api_func; |
62 | badPtr(); |
63 | // CHECK-MESSAGES: :[[@LINE-2]]:26: warning: 'libc_api_func' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro |
64 | // CHECK-MESSAGES: :25:6: note: resolves to this declaration |
65 | |
66 | // Allow calling into global namespace for specific functions. |
67 | ::malloc(); |
68 | |
69 | // Disallow calling on entities that are not in the namespace, but make sure |
70 | // no crashes happen. |
71 | global_struct{}(); |
72 | // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'operator()' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro |
73 | // CHECK-MESSAGES: :32:7: note: resolves to this declaration |
74 | |
75 | OTHER_MACRO_NAMESPACE::wrong_name_macro_func(); |
76 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'wrong_name_macro_func' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro |
77 | // CHECK-MESSAGES: :3:31: note: expanded from macro 'OTHER_MACRO_NAMESPACE' |
78 | // CHECK-MESSAGES: :5:8: note: resolves to this declaration |
79 | |
80 | __llvm_libc::right_name_no_macro_func(); |
81 | // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: 'right_name_no_macro_func' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro |
82 | // CHECK-MESSAGES: :9:8: note: resolves to this declaration |
83 | |
84 | } |
85 | |
86 | } // namespace __llvm_libc |
87 | |