1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_COMPILER_SPECIFIC_H_
6 #define BASE_COMPILER_SPECIFIC_H_
7 
8 #include "build/build_config.h"
9 
10 #if defined(COMPILER_MSVC) && !defined(__clang__)
11 #error "Only clang-cl is supported on Windows, see https://crbug.com/988071"
12 #endif
13 
14 // Annotate a variable indicating it's ok if the variable is not used.
15 // (Typically used to silence a compiler warning when the assignment
16 // is important for some other reason.)
17 // Use like:
18 //   int x = ...;
19 //   ALLOW_UNUSED_LOCAL(x);
20 #define ALLOW_UNUSED_LOCAL(x) (void)x
21 
22 // Annotate a typedef or function indicating it's ok if it's not used.
23 // Use like:
24 //   typedef Foo Bar ALLOW_UNUSED_TYPE;
25 #if defined(COMPILER_GCC) || defined(__clang__)
26 #define ALLOW_UNUSED_TYPE __attribute__((unused))
27 #else
28 #define ALLOW_UNUSED_TYPE
29 #endif
30 
31 // Annotate a function indicating it should not be inlined.
32 // Use like:
33 //   NOINLINE void DoStuff() { ... }
34 #if defined(COMPILER_GCC)
35 #define NOINLINE __attribute__((noinline))
36 #elif defined(COMPILER_MSVC)
37 #define NOINLINE __declspec(noinline)
38 #else
39 #define NOINLINE
40 #endif
41 
42 #if defined(COMPILER_GCC) && defined(NDEBUG)
43 #define ALWAYS_INLINE inline __attribute__((__always_inline__))
44 #elif defined(COMPILER_MSVC) && defined(NDEBUG)
45 #define ALWAYS_INLINE __forceinline
46 #else
47 #define ALWAYS_INLINE inline
48 #endif
49 
50 // Annotate a function indicating it should never be tail called. Useful to make
51 // sure callers of the annotated function are never omitted from call-stacks.
52 // To provide the complementary behavior (prevent the annotated function from
53 // being omitted) look at NOINLINE. Also note that this doesn't prevent code
54 // folding of multiple identical caller functions into a single signature. To
55 // prevent code folding, see base::debug::Alias.
56 // Use like:
57 //   void NOT_TAIL_CALLED FooBar();
58 #if defined(__clang__) && __has_attribute(not_tail_called)
59 #define NOT_TAIL_CALLED __attribute__((not_tail_called))
60 #else
61 #define NOT_TAIL_CALLED
62 #endif
63 
64 // Specify memory alignment for structs, classes, etc.
65 // Use like:
66 //   class ALIGNAS(16) MyClass { ... }
67 //   ALIGNAS(16) int array[4];
68 //
69 // In most places you can use the C++11 keyword "alignas", which is preferred.
70 //
71 // But compilers have trouble mixing __attribute__((...)) syntax with
72 // alignas(...) syntax.
73 //
74 // Doesn't work in clang or gcc:
75 //   struct alignas(16) __attribute__((packed)) S { char c; };
76 // Works in clang but not gcc:
77 //   struct __attribute__((packed)) alignas(16) S2 { char c; };
78 // Works in clang and gcc:
79 //   struct alignas(16) S3 { char c; } __attribute__((packed));
80 //
81 // There are also some attributes that must be specified *before* a class
82 // definition: visibility (used for exporting functions/classes) is one of
83 // these attributes. This means that it is not possible to use alignas() with a
84 // class that is marked as exported.
85 #if defined(COMPILER_MSVC)
86 #define ALIGNAS(byte_alignment) __declspec(align(byte_alignment))
87 #elif defined(COMPILER_GCC)
88 #define ALIGNAS(byte_alignment) __attribute__((aligned(byte_alignment)))
89 #endif
90 
91 // Annotate a function indicating the caller must examine the return value.
92 // Use like:
93 //   int foo() WARN_UNUSED_RESULT;
94 // To explicitly ignore a result, see |ignore_result()| in base/macros.h.
95 #undef WARN_UNUSED_RESULT
96 #if defined(COMPILER_GCC) || defined(__clang__)
97 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
98 #else
99 #define WARN_UNUSED_RESULT
100 #endif
101 
102 // Tell the compiler a function is using a printf-style format string.
103 // |format_param| is the one-based index of the format string parameter;
104 // |dots_param| is the one-based index of the "..." parameter.
105 // For v*printf functions (which take a va_list), pass 0 for dots_param.
106 // (This is undocumented but matches what the system C headers do.)
107 // For member functions, the implicit this parameter counts as index 1.
108 #if defined(COMPILER_GCC) || defined(__clang__)
109 #define PRINTF_FORMAT(format_param, dots_param) \
110   __attribute__((format(printf, format_param, dots_param)))
111 #else
112 #define PRINTF_FORMAT(format_param, dots_param)
113 #endif
114 
115 // WPRINTF_FORMAT is the same, but for wide format strings.
116 // This doesn't appear to yet be implemented in any compiler.
117 // See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38308 .
118 #define WPRINTF_FORMAT(format_param, dots_param)
119 // If available, it would look like:
120 //   __attribute__((format(wprintf, format_param, dots_param)))
121 
122 // Sanitizers annotations.
123 #if defined(__has_attribute)
124 #if __has_attribute(no_sanitize)
125 #define NO_SANITIZE(what) __attribute__((no_sanitize(what)))
126 #endif
127 #endif
128 #if !defined(NO_SANITIZE)
129 #define NO_SANITIZE(what)
130 #endif
131 
132 // MemorySanitizer annotations.
133 #if defined(MEMORY_SANITIZER) && !defined(OS_NACL)
134 #include <sanitizer/msan_interface.h>
135 
136 // Mark a memory region fully initialized.
137 // Use this to annotate code that deliberately reads uninitialized data, for
138 // example a GC scavenging root set pointers from the stack.
139 #define MSAN_UNPOISON(p, size) __msan_unpoison(p, size)
140 
141 // Check a memory region for initializedness, as if it was being used here.
142 // If any bits are uninitialized, crash with an MSan report.
143 // Use this to sanitize data which MSan won't be able to track, e.g. before
144 // passing data to another process via shared memory.
145 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size) \
146   __msan_check_mem_is_initialized(p, size)
147 #else  // MEMORY_SANITIZER
148 #define MSAN_UNPOISON(p, size)
149 #define MSAN_CHECK_MEM_IS_INITIALIZED(p, size)
150 #endif  // MEMORY_SANITIZER
151 
152 // DISABLE_CFI_PERF -- Disable Control Flow Integrity for perf reasons.
153 #if !defined(DISABLE_CFI_PERF)
154 #if defined(__clang__) && defined(OFFICIAL_BUILD)
155 #define DISABLE_CFI_PERF __attribute__((no_sanitize("cfi")))
156 #else
157 #define DISABLE_CFI_PERF
158 #endif
159 #endif
160 
161 // DISABLE_CFI_ICALL -- Disable Control Flow Integrity indirect call checks.
162 #if !defined(DISABLE_CFI_ICALL)
163 #if defined(OS_WIN)
164 // Windows also needs __declspec(guard(nocf)).
165 #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall") __declspec(guard(nocf))
166 #else
167 #define DISABLE_CFI_ICALL NO_SANITIZE("cfi-icall")
168 #endif
169 #endif
170 #if !defined(DISABLE_CFI_ICALL)
171 #define DISABLE_CFI_ICALL
172 #endif
173 
174 // Macro useful for writing cross-platform function pointers.
175 #if !defined(CDECL)
176 #if defined(OS_WIN)
177 #define CDECL __cdecl
178 #else  // defined(OS_WIN)
179 #define CDECL
180 #endif  // defined(OS_WIN)
181 #endif  // !defined(CDECL)
182 
183 // Macro for hinting that an expression is likely to be false.
184 #if !defined(UNLIKELY)
185 #if defined(COMPILER_GCC) || defined(__clang__)
186 #define UNLIKELY(x) __builtin_expect(!!(x), 0)
187 #else
188 #define UNLIKELY(x) (x)
189 #endif  // defined(COMPILER_GCC)
190 #endif  // !defined(UNLIKELY)
191 
192 #if !defined(LIKELY)
193 #if defined(COMPILER_GCC) || defined(__clang__)
194 #define LIKELY(x) __builtin_expect(!!(x), 1)
195 #else
196 #define LIKELY(x) (x)
197 #endif  // defined(COMPILER_GCC)
198 #endif  // !defined(LIKELY)
199 
200 // Compiler feature-detection.
201 // clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
202 #if defined(__has_feature)
203 #define HAS_FEATURE(FEATURE) __has_feature(FEATURE)
204 #else
205 #define HAS_FEATURE(FEATURE) 0
206 #endif
207 
208 // Macro for telling -Wimplicit-fallthrough that a fallthrough is intentional.
209 #if defined(__clang__)
210 #define FALLTHROUGH [[clang::fallthrough]]
211 #else
212 #define FALLTHROUGH
213 #endif
214 
215 #if defined(COMPILER_GCC)
216 #define PRETTY_FUNCTION __PRETTY_FUNCTION__
217 #elif defined(COMPILER_MSVC)
218 #define PRETTY_FUNCTION __FUNCSIG__
219 #else
220 // See https://en.cppreference.com/w/c/language/function_definition#func
221 #define PRETTY_FUNCTION __func__
222 #endif
223 
224 #if !defined(CPU_ARM_NEON)
225 #if defined(__arm__)
226 #if !defined(__ARMEB__) && !defined(__ARM_EABI__) && !defined(__EABI__) && \
227     !defined(__VFP_FP__) && !defined(_WIN32_WCE) && !defined(ANDROID)
228 #error Chromium does not support middle endian architecture
229 #endif
230 #if defined(__ARM_NEON__)
231 #define CPU_ARM_NEON 1
232 #endif
233 #endif  // defined(__arm__)
234 #endif  // !defined(CPU_ARM_NEON)
235 
236 #if !defined(HAVE_MIPS_MSA_INTRINSICS)
237 #if defined(__mips_msa) && defined(__mips_isa_rev) && (__mips_isa_rev >= 5)
238 #define HAVE_MIPS_MSA_INTRINSICS 1
239 #endif
240 #endif
241 
242 #if defined(__clang__) && __has_attribute(uninitialized)
243 // Attribute "uninitialized" disables -ftrivial-auto-var-init=pattern for
244 // the specified variable.
245 // Library-wide alternative is
246 // 'configs -= [ "//build/config/compiler:default_init_stack_vars" ]' in .gn
247 // file.
248 //
249 // See "init_stack_vars" in build/config/compiler/BUILD.gn and
250 // http://crbug.com/977230
251 // "init_stack_vars" is enabled for non-official builds and we hope to enable it
252 // in official build in 2020 as well. The flag writes fixed pattern into
253 // uninitialized parts of all local variables. In rare cases such initialization
254 // is undesirable and attribute can be used:
255 //   1. Degraded performance
256 // In most cases compiler is able to remove additional stores. E.g. if memory is
257 // never accessed or properly initialized later. Preserved stores mostly will
258 // not affect program performance. However if compiler failed on some
259 // performance critical code we can get a visible regression in a benchmark.
260 //   2. memset, memcpy calls
261 // Compiler may replaces some memory writes with memset or memcpy calls. This is
262 // not -ftrivial-auto-var-init specific, but it can happen more likely with the
263 // flag. It can be a problem if code is not linked with C run-time library.
264 //
265 // Note: The flag is security risk mitigation feature. So in future the
266 // attribute uses should be avoided when possible. However to enable this
267 // mitigation on the most of the code we need to be less strict now and minimize
268 // number of exceptions later. So if in doubt feel free to use attribute, but
269 // please document the problem for someone who is going to cleanup it later.
270 // E.g. platform, bot, benchmark or test name in patch description or next to
271 // the attribute.
272 #define STACK_UNINITIALIZED __attribute__((uninitialized))
273 #else
274 #define STACK_UNINITIALIZED
275 #endif
276 
277 // The ANALYZER_ASSUME_TRUE(bool arg) macro adds compiler-specific hints
278 // to Clang which control what code paths are statically analyzed,
279 // and is meant to be used in conjunction with assert & assert-like functions.
280 // The expression is passed straight through if analysis isn't enabled.
281 //
282 // ANALYZER_SKIP_THIS_PATH() suppresses static analysis for the current
283 // codepath and any other branching codepaths that might follow.
284 #if defined(__clang_analyzer__)
285 
AnalyzerNoReturn()286 inline constexpr bool AnalyzerNoReturn() __attribute__((analyzer_noreturn)) {
287   return false;
288 }
289 
AnalyzerAssumeTrue(bool arg)290 inline constexpr bool AnalyzerAssumeTrue(bool arg) {
291   // AnalyzerNoReturn() is invoked and analysis is terminated if |arg| is
292   // false.
293   return arg || AnalyzerNoReturn();
294 }
295 
296 #define ANALYZER_ASSUME_TRUE(arg) ::AnalyzerAssumeTrue(!!(arg))
297 #define ANALYZER_SKIP_THIS_PATH() static_cast<void>(::AnalyzerNoReturn())
298 #define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
299 
300 #else  // !defined(__clang_analyzer__)
301 
302 #define ANALYZER_ASSUME_TRUE(arg) (arg)
303 #define ANALYZER_SKIP_THIS_PATH()
304 #define ANALYZER_ALLOW_UNUSED(var) static_cast<void>(var);
305 
306 #endif  // defined(__clang_analyzer__)
307 
308 #endif  // BASE_COMPILER_SPECIFIC_H_
309