• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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