diff options
Diffstat (limited to 'src/utils/compiler_attributes.h')
-rw-r--r-- | src/utils/compiler_attributes.h | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/utils/compiler_attributes.h b/src/utils/compiler_attributes.h new file mode 100644 index 0000000..e122426 --- /dev/null +++ b/src/utils/compiler_attributes.h @@ -0,0 +1,181 @@ +/* + * Copyright 2019 The libgav1 Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ +#define LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ + +// A collection of compiler attribute checks and defines to control for +// compatibility across toolchains. + +//------------------------------------------------------------------------------ +// Language version, attribute and feature helpers. + +// Detect c++17 support. Visual Studio sets __cplusplus to 199711L by default +// unless compiled with /Zc:__cplusplus, use the value controlled by /std +// instead. +// https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus +#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) +#define LIBGAV1_CXX17 1 +#else +#define LIBGAV1_CXX17 0 +#endif + +#if defined(__has_attribute) +#define LIBGAV1_HAS_ATTRIBUTE __has_attribute +#else +#define LIBGAV1_HAS_ATTRIBUTE(x) 0 +#endif + +#if defined(__has_feature) +#define LIBGAV1_HAS_FEATURE __has_feature +#else +#define LIBGAV1_HAS_FEATURE(x) 0 +#endif + +//------------------------------------------------------------------------------ +// Sanitizer attributes. + +#if LIBGAV1_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +#define LIBGAV1_ASAN 1 +#else +#define LIBGAV1_ASAN 0 +#endif + +#if LIBGAV1_HAS_FEATURE(memory_sanitizer) +#define LIBGAV1_MSAN 1 +#else +#define LIBGAV1_MSAN 0 +#endif + +#if LIBGAV1_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) +#define LIBGAV1_TSAN 1 +#else +#define LIBGAV1_TSAN 0 +#endif + +//------------------------------------------------------------------------------ +// AddressSanitizer support. + +// Define the macros for AddressSanitizer manual memory poisoning. See +// https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning. +#if LIBGAV1_ASAN +#include <sanitizer/asan_interface.h> +#else +#define ASAN_POISON_MEMORY_REGION(addr, size) \ + (static_cast<void>(addr), static_cast<void>(size)) +#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ + (static_cast<void>(addr), static_cast<void>(size)) +#endif + +//------------------------------------------------------------------------------ +// Function attributes. +// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html +// Clang: https://clang.llvm.org/docs/AttributeReference.html + +#if defined(__GNUC__) +#define LIBGAV1_ALWAYS_INLINE __attribute__((always_inline)) inline +#elif defined(_MSC_VER) +#define LIBGAV1_ALWAYS_INLINE __forceinline +#else +#define LIBGAV1_ALWAYS_INLINE inline +#endif + +// LIBGAV1_MUST_USE_RESULT +// +// Tells the compiler to warn about unused results. +// +// When annotating a function, it must appear as the first part of the +// declaration or definition. The compiler will warn if the return value from +// such a function is unused: +// +// LIBGAV1_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// AllocateSprocket(); // Triggers a warning. +// +// When annotating a class, it is equivalent to annotating every function which +// returns an instance. +// +// class LIBGAV1_MUST_USE_RESULT Sprocket {}; +// Sprocket(); // Triggers a warning. +// +// Sprocket MakeSprocket(); +// MakeSprocket(); // Triggers a warning. +// +// Note that references and pointers are not instances: +// +// Sprocket* SprocketPointer(); +// SprocketPointer(); // Does *not* trigger a warning. +// +// LIBGAV1_MUST_USE_RESULT allows using cast-to-void to suppress the unused +// result warning. For that, warn_unused_result is used only for clang but not +// for gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 +#if LIBGAV1_HAS_ATTRIBUTE(nodiscard) +#define LIBGAV1_MUST_USE_RESULT [[nodiscard]] +#elif defined(__clang__) && LIBGAV1_HAS_ATTRIBUTE(warn_unused_result) +#define LIBGAV1_MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define LIBGAV1_MUST_USE_RESULT +#endif + +// LIBGAV1_PRINTF_ATTRIBUTE +// +// Tells the compiler to perform `printf` format string checking if the +// compiler supports it; see the 'format' attribute in +// <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html>. +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +#if LIBGAV1_HAS_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) +#define LIBGAV1_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#else +#define LIBGAV1_PRINTF_ATTRIBUTE(string_index, first_to_check) +#endif + +//------------------------------------------------------------------------------ +// Thread annotations. + +// LIBGAV1_GUARDED_BY() +// +// Documents if a shared field or global variable needs to be protected by a +// mutex. LIBGAV1_GUARDED_BY() allows the user to specify a particular mutex +// that should be held when accessing the annotated variable. +// +// Although this annotation cannot be applied to local variables, a local +// variable and its associated mutex can often be combined into a small class +// or struct, thereby allowing the annotation. +// +// Example: +// +// class Foo { +// Mutex mu_; +// int p1_ LIBGAV1_GUARDED_BY(mu_); +// ... +// }; +// TODO(b/132506370): this can be reenabled after a local MutexLock +// implementation is added with proper thread annotations. +#if 0 // LIBGAV1_HAS_ATTRIBUTE(guarded_by) +#define LIBGAV1_GUARDED_BY(x) __attribute__((guarded_by(x))) +#else +#define LIBGAV1_GUARDED_BY(x) +#endif + +//------------------------------------------------------------------------------ + +#undef LIBGAV1_HAS_ATTRIBUTE +#undef LIBGAV1_HAS_FEATURE + +#endif // LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ |