1 // RUN: %check_clang_tidy %s llvmlibc-callee-namespace %t 2 3 #define OTHER_MACRO_NAMESPACE custom_namespace 4 namespace OTHER_MACRO_NAMESPACE { wrong_name_macro_func()5 void wrong_name_macro_func() {} 6 } 7 8 namespace __llvm_libc { right_name_no_macro_func()9 void right_name_no_macro_func() {} 10 } 11 12 #define LIBC_NAMESPACE __llvm_libc_xyz 13 namespace LIBC_NAMESPACE { 14 namespace nested { nested_func()15void nested_func() {} 16 } // namespace nested libc_api_func()17void libc_api_func() {} 18 19 struct libc_api_struct { operator ()LIBC_NAMESPACE::libc_api_struct20 int operator()() const { return 0; } 21 }; 22 } // namespace __llvm_libc 23 24 // Emulate a function from the public headers like string.h libc_api_func()25void libc_api_func() {} 26 27 // Emulate a function specifically allowed by the exception list. malloc()28void malloc() {} 29 30 // Emulate a non-trivially named symbol. 31 struct global_struct { operator ()global_struct32 int operator()() const { return 0; } 33 }; 34 35 namespace LIBC_NAMESPACE { Test()36void 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