diff --git a/libc/docs/clang_tidy_checks.rst b/libc/docs/clang_tidy_checks.rst new file mode 100644 --- /dev/null +++ b/libc/docs/clang_tidy_checks.rst @@ -0,0 +1,86 @@ +LLVM libc clang-tidy checks +=========================== +These are the clang-tidy checks designed to help enforce implementation +standards. +The configuration file is ``src/.clang-tidy``. + +restrict-system-libc-header +--------------------------- +One of libc-project’s design goals is to use kernel headers and compiler +provided headers to prevent code duplication on a per platform basis. This +presents a problem when writing implementations since system libc headers are +easy to include accidentally and we can't just use the ``-nostdinc`` flag. +Improperly included system headers can introduce runtime errors because the C +standard outlines function prototypes and behaviors but doesn’t define +underlying implementation details such as the layout of a struct. + +This check prevents accidental inclusion of system libc headers when writing a +libc implementation. + +.. code-block:: c++ + + #include // Not allowed because it is part of system libc. + #include // Allowed because it is provided by the compiler. + #include "internal/stdio.h" // Allowed because it is NOT part of system libc. + + +implementation-in-namespace +--------------------------- + +It is part of our implementation standards that all implementation pieces live +under the ``__llvm_libc`` namespace. This prevents polution of the global +namespace. Without a formal check to ensure this, an implementation might +compile and pass unit tests, but not produce a usable libc function. + +This check that ensures any function call resolves to a function within the +``__llvm_libc`` namespace. + +.. code-block:: c++ + + // Correct: implementation inside the correct namespace. + namespace __llvm_libc { + void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + // Namespaces within __llvm_libc namespace are allowed. + namespace inner{ + int localVar = 0; + } + // Functions with C linkage are allowed. + extern "C" void str_fuzz(){} + } + + // Incorrect: implementation not in a namespace. + void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + + // Incorrect: outer most namespace is not correct. + namespace something_else { + void LLVM_LIBC_ENTRYPOINT(strcpy)(char *dest, const char *src) {} + } + + +callee-namespace +---------------- +LLVM-libc is distinct because it is designed to maintain interoperability with +other libc libraries, including the one that lives on the system. This feature +creates some uncertainty about which library a call resolves to especially when +a public header with non-namespaced functions like ``string.h`` is included. + +This check ensures any function call resolves to a function within the +__llvm_libc namespace. + +.. code-block:: c++ + + namespace __llvm_libc { + + // Allow calls with the fully qualified name. + __llvm_libc::strlen("hello"); + + // Allow calls to compiler provided functions. + (void)__builtin_abs(-1); + + // Bare calls are allowed as long as they resolve to the correct namespace. + strlen("world"); + + // Disallow calling into functions in the global namespace. + ::strlen("!"); + + } // namespace __llvm_libc