xref: /llvm-project/clang-tools-extra/test/clang-tidy/checkers/llvmlibc/callee-namespace.cpp (revision daca97216cf132d733513f992d49e3c722aabf40)
189a1d03eSRichard // RUN: %check_clang_tidy %s llvmlibc-callee-namespace %t
289a1d03eSRichard 
3*daca9721Smichaelrj-google #define OTHER_MACRO_NAMESPACE custom_namespace
4*daca9721Smichaelrj-google namespace OTHER_MACRO_NAMESPACE {
wrong_name_macro_func()5*daca9721Smichaelrj-google   void wrong_name_macro_func() {}
6*daca9721Smichaelrj-google }
7*daca9721Smichaelrj-google 
889a1d03eSRichard namespace __llvm_libc {
right_name_no_macro_func()9*daca9721Smichaelrj-google   void right_name_no_macro_func() {}
10*daca9721Smichaelrj-google }
11*daca9721Smichaelrj-google 
12*daca9721Smichaelrj-google #define LIBC_NAMESPACE __llvm_libc_xyz
13*daca9721Smichaelrj-google namespace LIBC_NAMESPACE {
1489a1d03eSRichard namespace nested {
nested_func()1589a1d03eSRichard void nested_func() {}
1689a1d03eSRichard } // namespace nested
libc_api_func()1789a1d03eSRichard void libc_api_func() {}
1889a1d03eSRichard 
1989a1d03eSRichard struct libc_api_struct {
operator ()LIBC_NAMESPACE::libc_api_struct2089a1d03eSRichard   int operator()() const { return 0; }
2189a1d03eSRichard };
2289a1d03eSRichard } // namespace __llvm_libc
2389a1d03eSRichard 
2489a1d03eSRichard // Emulate a function from the public headers like string.h
libc_api_func()2589a1d03eSRichard void libc_api_func() {}
2689a1d03eSRichard 
2789a1d03eSRichard // Emulate a function specifically allowed by the exception list.
malloc()2889a1d03eSRichard void malloc() {}
2989a1d03eSRichard 
3089a1d03eSRichard // Emulate a non-trivially named symbol.
3189a1d03eSRichard struct global_struct {
operator ()global_struct3289a1d03eSRichard   int operator()() const { return 0; }
3389a1d03eSRichard };
3489a1d03eSRichard 
35*daca9721Smichaelrj-google namespace LIBC_NAMESPACE {
Test()3689a1d03eSRichard void Test() {
3789a1d03eSRichard   // Allow calls with the fully qualified name.
38*daca9721Smichaelrj-google   LIBC_NAMESPACE::libc_api_func();
39*daca9721Smichaelrj-google   LIBC_NAMESPACE::nested::nested_func();
40*daca9721Smichaelrj-google   void (*qualifiedPtr)(void) = LIBC_NAMESPACE::libc_api_func;
4189a1d03eSRichard   qualifiedPtr();
4289a1d03eSRichard 
4389a1d03eSRichard   // Should not trigger on compiler provided function calls.
4489a1d03eSRichard   (void)__builtin_abs(-1);
4589a1d03eSRichard 
4689a1d03eSRichard   // Bare calls are allowed as long as they resolve to the correct namespace.
4789a1d03eSRichard   libc_api_func();
4889a1d03eSRichard   nested::nested_func();
49*daca9721Smichaelrj-google   void (*barePtr)(void) = LIBC_NAMESPACE::libc_api_func;
5089a1d03eSRichard   barePtr();
5189a1d03eSRichard 
5289a1d03eSRichard   // Allow calling entities defined in the namespace.
53*daca9721Smichaelrj-google   LIBC_NAMESPACE::libc_api_struct{}();
5489a1d03eSRichard 
5589a1d03eSRichard   // Disallow calling into global namespace for implemented entrypoints.
5689a1d03eSRichard   ::libc_api_func();
57*daca9721Smichaelrj-google   // 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*daca9721Smichaelrj-google   // CHECK-MESSAGES: :25:6: note: resolves to this declaration
5989a1d03eSRichard 
6089a1d03eSRichard   // Disallow indirect references to functions in global namespace.
6189a1d03eSRichard   void (*badPtr)(void) = ::libc_api_func;
6289a1d03eSRichard   badPtr();
63*daca9721Smichaelrj-google   // 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*daca9721Smichaelrj-google   // CHECK-MESSAGES: :25:6: note: resolves to this declaration
6589a1d03eSRichard 
6689a1d03eSRichard   // Allow calling into global namespace for specific functions.
6789a1d03eSRichard   ::malloc();
6889a1d03eSRichard 
6989a1d03eSRichard   // Disallow calling on entities that are not in the namespace, but make sure
7089a1d03eSRichard   // no crashes happen.
7189a1d03eSRichard   global_struct{}();
72*daca9721Smichaelrj-google   // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: 'operator()' must resolve to a function declared within the namespace defined by the 'LIBC_NAMESPACE' macro
73*daca9721Smichaelrj-google   // CHECK-MESSAGES: :32:7: note: resolves to this declaration
74*daca9721Smichaelrj-google 
75*daca9721Smichaelrj-google   OTHER_MACRO_NAMESPACE::wrong_name_macro_func();
76*daca9721Smichaelrj-google   // 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*daca9721Smichaelrj-google   // CHECK-MESSAGES: :3:31: note: expanded from macro 'OTHER_MACRO_NAMESPACE'
78*daca9721Smichaelrj-google   // CHECK-MESSAGES: :5:8: note: resolves to this declaration
79*daca9721Smichaelrj-google 
80*daca9721Smichaelrj-google   __llvm_libc::right_name_no_macro_func();
81*daca9721Smichaelrj-google   // 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*daca9721Smichaelrj-google   // CHECK-MESSAGES: :9:8: note: resolves to this declaration
83*daca9721Smichaelrj-google 
8489a1d03eSRichard }
8589a1d03eSRichard 
8689a1d03eSRichard } // namespace __llvm_libc
87