1 /* 2 * Copyright 2019 The libgav1 Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ 18 #define LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ 19 20 // A collection of compiler attribute checks and defines to control for 21 // compatibility across toolchains. 22 23 //------------------------------------------------------------------------------ 24 // Language version, attribute and feature helpers. 25 26 // Detect c++17 support. Visual Studio sets __cplusplus to 199711L by default 27 // unless compiled with /Zc:__cplusplus, use the value controlled by /std 28 // instead. 29 // https://docs.microsoft.com/en-us/cpp/build/reference/zc-cplusplus 30 #if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) 31 #define LIBGAV1_CXX17 1 32 #else 33 #define LIBGAV1_CXX17 0 34 #endif 35 36 #if defined(__has_attribute) 37 #define LIBGAV1_HAS_ATTRIBUTE __has_attribute 38 #else 39 #define LIBGAV1_HAS_ATTRIBUTE(x) 0 40 #endif 41 42 #if defined(__has_feature) 43 #define LIBGAV1_HAS_FEATURE __has_feature 44 #else 45 #define LIBGAV1_HAS_FEATURE(x) 0 46 #endif 47 48 //------------------------------------------------------------------------------ 49 // Sanitizer attributes. 50 51 #if LIBGAV1_HAS_FEATURE(address_sanitizer) || defined(__SANITIZE_ADDRESS__) 52 #define LIBGAV1_ASAN 1 53 #else 54 #define LIBGAV1_ASAN 0 55 #endif 56 57 #if LIBGAV1_HAS_FEATURE(memory_sanitizer) 58 #define LIBGAV1_MSAN 1 59 #else 60 #define LIBGAV1_MSAN 0 61 #endif 62 63 #if LIBGAV1_HAS_FEATURE(thread_sanitizer) || defined(__SANITIZE_THREAD__) 64 #define LIBGAV1_TSAN 1 65 #else 66 #define LIBGAV1_TSAN 0 67 #endif 68 69 //------------------------------------------------------------------------------ 70 // AddressSanitizer support. 71 72 // Define the macros for AddressSanitizer manual memory poisoning. See 73 // https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning. 74 #if LIBGAV1_ASAN 75 #include <sanitizer/asan_interface.h> 76 #else 77 #define ASAN_POISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) 78 #define ASAN_UNPOISON_MEMORY_REGION(addr, size) ((void)(addr), (void)(size)) 79 #endif 80 81 //------------------------------------------------------------------------------ 82 // MemorySanitizer support. 83 84 #if LIBGAV1_MSAN 85 #include <sanitizer/msan_interface.h> 86 #endif // LIBGAV1_MSAN 87 88 //------------------------------------------------------------------------------ 89 // Function attributes. 90 // GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 91 // Clang: https://clang.llvm.org/docs/AttributeReference.html 92 93 #if defined(__GNUC__) 94 #define LIBGAV1_ALWAYS_INLINE __attribute__((always_inline)) inline 95 #elif defined(_MSC_VER) 96 #define LIBGAV1_ALWAYS_INLINE __forceinline 97 #else 98 #define LIBGAV1_ALWAYS_INLINE inline 99 #endif 100 101 // LIBGAV1_MUST_USE_RESULT 102 // 103 // Tells the compiler to warn about unused results. 104 // 105 // When annotating a function, it must appear as the first part of the 106 // declaration or definition. The compiler will warn if the return value from 107 // such a function is unused: 108 // 109 // LIBGAV1_MUST_USE_RESULT Sprocket* AllocateSprocket(); 110 // AllocateSprocket(); // Triggers a warning. 111 // 112 // When annotating a class, it is equivalent to annotating every function which 113 // returns an instance. 114 // 115 // class LIBGAV1_MUST_USE_RESULT Sprocket {}; 116 // Sprocket(); // Triggers a warning. 117 // 118 // Sprocket MakeSprocket(); 119 // MakeSprocket(); // Triggers a warning. 120 // 121 // Note that references and pointers are not instances: 122 // 123 // Sprocket* SprocketPointer(); 124 // SprocketPointer(); // Does *not* trigger a warning. 125 // 126 // LIBGAV1_MUST_USE_RESULT allows using cast-to-void to suppress the unused 127 // result warning. For that, warn_unused_result is used only for clang but not 128 // for gcc. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 129 #if LIBGAV1_HAS_ATTRIBUTE(nodiscard) 130 #define LIBGAV1_MUST_USE_RESULT [[nodiscard]] 131 #elif defined(__clang__) && LIBGAV1_HAS_ATTRIBUTE(warn_unused_result) 132 #define LIBGAV1_MUST_USE_RESULT __attribute__((warn_unused_result)) 133 #else 134 #define LIBGAV1_MUST_USE_RESULT 135 #endif 136 137 // LIBGAV1_PRINTF_ATTRIBUTE 138 // 139 // Tells the compiler to perform `printf` format string checking if the 140 // compiler supports it; see the 'format' attribute in 141 // <https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html>. 142 // 143 // Note: As the GCC manual states, "[s]ince non-static C++ methods 144 // have an implicit 'this' argument, the arguments of such methods 145 // should be counted from two, not one." 146 #if LIBGAV1_HAS_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) 147 #define LIBGAV1_PRINTF_ATTRIBUTE(string_index, first_to_check) \ 148 __attribute__((__format__(__printf__, string_index, first_to_check))) 149 #else 150 #define LIBGAV1_PRINTF_ATTRIBUTE(string_index, first_to_check) 151 #endif 152 153 //------------------------------------------------------------------------------ 154 // Thread annotations. 155 156 // LIBGAV1_GUARDED_BY() 157 // 158 // Documents if a shared field or global variable needs to be protected by a 159 // mutex. LIBGAV1_GUARDED_BY() allows the user to specify a particular mutex 160 // that should be held when accessing the annotated variable. 161 // 162 // Although this annotation cannot be applied to local variables, a local 163 // variable and its associated mutex can often be combined into a small class 164 // or struct, thereby allowing the annotation. 165 // 166 // Example: 167 // 168 // class Foo { 169 // Mutex mu_; 170 // int p1_ LIBGAV1_GUARDED_BY(mu_); 171 // ... 172 // }; 173 // TODO(b/133245043): this can be reenabled after a local MutexLock 174 // implementation is added with proper thread annotations. 175 #if 0 // LIBGAV1_HAS_ATTRIBUTE(guarded_by) 176 #define LIBGAV1_GUARDED_BY(x) __attribute__((guarded_by(x))) 177 #else 178 #define LIBGAV1_GUARDED_BY(x) 179 #endif 180 181 //------------------------------------------------------------------------------ 182 183 #undef LIBGAV1_HAS_ATTRIBUTE 184 #undef LIBGAV1_HAS_FEATURE 185 186 #endif // LIBGAV1_SRC_UTILS_COMPILER_ATTRIBUTES_H_ 187