Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /* Implementations of various class and method modifier attributes. */ |
michael@0 | 8 | |
michael@0 | 9 | #ifndef mozilla_Attributes_h |
michael@0 | 10 | #define mozilla_Attributes_h |
michael@0 | 11 | |
michael@0 | 12 | #include "mozilla/Compiler.h" |
michael@0 | 13 | |
michael@0 | 14 | /* |
michael@0 | 15 | * MOZ_ALWAYS_INLINE is a macro which expands to tell the compiler that the |
michael@0 | 16 | * method decorated with it must be inlined, even if the compiler thinks |
michael@0 | 17 | * otherwise. This is only a (much) stronger version of the inline hint: |
michael@0 | 18 | * compilers are not guaranteed to respect it (although they're much more likely |
michael@0 | 19 | * to do so). |
michael@0 | 20 | * |
michael@0 | 21 | * The MOZ_ALWAYS_INLINE_EVEN_DEBUG macro is yet stronger. It tells the |
michael@0 | 22 | * compiler to inline even in DEBUG builds. It should be used very rarely. |
michael@0 | 23 | */ |
michael@0 | 24 | #if defined(_MSC_VER) |
michael@0 | 25 | # define MOZ_ALWAYS_INLINE_EVEN_DEBUG __forceinline |
michael@0 | 26 | #elif defined(__GNUC__) |
michael@0 | 27 | # define MOZ_ALWAYS_INLINE_EVEN_DEBUG __attribute__((always_inline)) inline |
michael@0 | 28 | #else |
michael@0 | 29 | # define MOZ_ALWAYS_INLINE_EVEN_DEBUG inline |
michael@0 | 30 | #endif |
michael@0 | 31 | |
michael@0 | 32 | #if !defined(DEBUG) |
michael@0 | 33 | # define MOZ_ALWAYS_INLINE MOZ_ALWAYS_INLINE_EVEN_DEBUG |
michael@0 | 34 | #elif defined(_MSC_VER) && !defined(__cplusplus) |
michael@0 | 35 | # define MOZ_ALWAYS_INLINE __inline |
michael@0 | 36 | #else |
michael@0 | 37 | # define MOZ_ALWAYS_INLINE inline |
michael@0 | 38 | #endif |
michael@0 | 39 | |
michael@0 | 40 | /* |
michael@0 | 41 | * g++ requires -std=c++0x or -std=gnu++0x to support C++11 functionality |
michael@0 | 42 | * without warnings (functionality used by the macros below). These modes are |
michael@0 | 43 | * detectable by checking whether __GXX_EXPERIMENTAL_CXX0X__ is defined or, more |
michael@0 | 44 | * standardly, by checking whether __cplusplus has a C++11 or greater value. |
michael@0 | 45 | * Current versions of g++ do not correctly set __cplusplus, so we check both |
michael@0 | 46 | * for forward compatibility. |
michael@0 | 47 | */ |
michael@0 | 48 | #if defined(__clang__) |
michael@0 | 49 | /* |
michael@0 | 50 | * Per Clang documentation, "Note that marketing version numbers should not |
michael@0 | 51 | * be used to check for language features, as different vendors use different |
michael@0 | 52 | * numbering schemes. Instead, use the feature checking macros." |
michael@0 | 53 | */ |
michael@0 | 54 | # ifndef __has_extension |
michael@0 | 55 | # define __has_extension __has_feature /* compatibility, for older versions of clang */ |
michael@0 | 56 | # endif |
michael@0 | 57 | # if __has_extension(cxx_constexpr) |
michael@0 | 58 | # define MOZ_HAVE_CXX11_CONSTEXPR |
michael@0 | 59 | # endif |
michael@0 | 60 | # if __has_extension(cxx_explicit_conversions) |
michael@0 | 61 | # define MOZ_HAVE_EXPLICIT_CONVERSION |
michael@0 | 62 | # endif |
michael@0 | 63 | # if __has_extension(cxx_deleted_functions) |
michael@0 | 64 | # define MOZ_HAVE_CXX11_DELETE |
michael@0 | 65 | # endif |
michael@0 | 66 | # if __has_extension(cxx_override_control) |
michael@0 | 67 | # define MOZ_HAVE_CXX11_OVERRIDE |
michael@0 | 68 | # define MOZ_HAVE_CXX11_FINAL final |
michael@0 | 69 | # endif |
michael@0 | 70 | # if __has_attribute(noinline) |
michael@0 | 71 | # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) |
michael@0 | 72 | # endif |
michael@0 | 73 | # if __has_attribute(noreturn) |
michael@0 | 74 | # define MOZ_HAVE_NORETURN __attribute__((noreturn)) |
michael@0 | 75 | # endif |
michael@0 | 76 | #elif defined(__GNUC__) |
michael@0 | 77 | # if defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L |
michael@0 | 78 | # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) |
michael@0 | 79 | # define MOZ_HAVE_CXX11_OVERRIDE |
michael@0 | 80 | # define MOZ_HAVE_CXX11_FINAL final |
michael@0 | 81 | # endif |
michael@0 | 82 | # if MOZ_GCC_VERSION_AT_LEAST(4, 6, 0) |
michael@0 | 83 | # define MOZ_HAVE_CXX11_CONSTEXPR |
michael@0 | 84 | # endif |
michael@0 | 85 | # if MOZ_GCC_VERSION_AT_LEAST(4, 5, 0) |
michael@0 | 86 | # define MOZ_HAVE_EXPLICIT_CONVERSION |
michael@0 | 87 | # endif |
michael@0 | 88 | # define MOZ_HAVE_CXX11_DELETE |
michael@0 | 89 | # else |
michael@0 | 90 | /* __final is a non-C++11 GCC synonym for 'final', per GCC r176655. */ |
michael@0 | 91 | # if MOZ_GCC_VERSION_AT_LEAST(4, 7, 0) |
michael@0 | 92 | # define MOZ_HAVE_CXX11_FINAL __final |
michael@0 | 93 | # endif |
michael@0 | 94 | # endif |
michael@0 | 95 | # define MOZ_HAVE_NEVER_INLINE __attribute__((noinline)) |
michael@0 | 96 | # define MOZ_HAVE_NORETURN __attribute__((noreturn)) |
michael@0 | 97 | #elif defined(_MSC_VER) |
michael@0 | 98 | # if _MSC_VER >= 1800 |
michael@0 | 99 | # define MOZ_HAVE_CXX11_DELETE |
michael@0 | 100 | # endif |
michael@0 | 101 | # if _MSC_VER >= 1700 |
michael@0 | 102 | # define MOZ_HAVE_CXX11_FINAL final |
michael@0 | 103 | # else |
michael@0 | 104 | /* MSVC <= 10 used to spell "final" as "sealed". */ |
michael@0 | 105 | # define MOZ_HAVE_CXX11_FINAL sealed |
michael@0 | 106 | # endif |
michael@0 | 107 | # define MOZ_HAVE_CXX11_OVERRIDE |
michael@0 | 108 | # define MOZ_HAVE_NEVER_INLINE __declspec(noinline) |
michael@0 | 109 | # define MOZ_HAVE_NORETURN __declspec(noreturn) |
michael@0 | 110 | // Staying away from explicit conversion operators in MSVC for now, see |
michael@0 | 111 | // http://stackoverflow.com/questions/20498142/visual-studio-2013-explicit-keyword-bug |
michael@0 | 112 | #endif |
michael@0 | 113 | |
michael@0 | 114 | /* |
michael@0 | 115 | * The MOZ_CONSTEXPR specifier declares that a C++11 compiler can evaluate a |
michael@0 | 116 | * function at compile time. A constexpr function cannot examine any values |
michael@0 | 117 | * except its arguments and can have no side effects except its return value. |
michael@0 | 118 | * The MOZ_CONSTEXPR_VAR specifier tells a C++11 compiler that a variable's |
michael@0 | 119 | * value may be computed at compile time. It should be prefered to just |
michael@0 | 120 | * marking variables as MOZ_CONSTEXPR because if the compiler does not support |
michael@0 | 121 | * constexpr it will fall back to making the variable const, and some compilers |
michael@0 | 122 | * do not accept variables being marked both const and constexpr. |
michael@0 | 123 | */ |
michael@0 | 124 | #ifdef MOZ_HAVE_CXX11_CONSTEXPR |
michael@0 | 125 | # define MOZ_CONSTEXPR constexpr |
michael@0 | 126 | # define MOZ_CONSTEXPR_VAR constexpr |
michael@0 | 127 | #else |
michael@0 | 128 | # define MOZ_CONSTEXPR /* no support */ |
michael@0 | 129 | # define MOZ_CONSTEXPR_VAR const |
michael@0 | 130 | #endif |
michael@0 | 131 | |
michael@0 | 132 | /* |
michael@0 | 133 | * MOZ_EXPLICIT_CONVERSION is a specifier on a type conversion |
michael@0 | 134 | * overloaded operator that declares that a C++11 compiler should restrict |
michael@0 | 135 | * this operator to allow only explicit type conversions, disallowing |
michael@0 | 136 | * implicit conversions. |
michael@0 | 137 | * |
michael@0 | 138 | * Example: |
michael@0 | 139 | * |
michael@0 | 140 | * template<typename T> |
michael@0 | 141 | * class Ptr |
michael@0 | 142 | * { |
michael@0 | 143 | * T* ptr; |
michael@0 | 144 | * MOZ_EXPLICIT_CONVERSION operator bool() const { |
michael@0 | 145 | * return ptr != nullptr; |
michael@0 | 146 | * } |
michael@0 | 147 | * }; |
michael@0 | 148 | * |
michael@0 | 149 | */ |
michael@0 | 150 | #ifdef MOZ_HAVE_EXPLICIT_CONVERSION |
michael@0 | 151 | # define MOZ_EXPLICIT_CONVERSION explicit |
michael@0 | 152 | #else |
michael@0 | 153 | # define MOZ_EXPLICIT_CONVERSION /* no support */ |
michael@0 | 154 | #endif |
michael@0 | 155 | |
michael@0 | 156 | /* |
michael@0 | 157 | * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the |
michael@0 | 158 | * method decorated with it must never be inlined, even if the compiler would |
michael@0 | 159 | * otherwise choose to inline the method. Compilers aren't absolutely |
michael@0 | 160 | * guaranteed to support this, but most do. |
michael@0 | 161 | */ |
michael@0 | 162 | #if defined(MOZ_HAVE_NEVER_INLINE) |
michael@0 | 163 | # define MOZ_NEVER_INLINE MOZ_HAVE_NEVER_INLINE |
michael@0 | 164 | #else |
michael@0 | 165 | # define MOZ_NEVER_INLINE /* no support */ |
michael@0 | 166 | #endif |
michael@0 | 167 | |
michael@0 | 168 | /* |
michael@0 | 169 | * MOZ_NORETURN, specified at the start of a function declaration, indicates |
michael@0 | 170 | * that the given function does not return. (The function definition does not |
michael@0 | 171 | * need to be annotated.) |
michael@0 | 172 | * |
michael@0 | 173 | * MOZ_NORETURN void abort(const char* msg); |
michael@0 | 174 | * |
michael@0 | 175 | * This modifier permits the compiler to optimize code assuming a call to such a |
michael@0 | 176 | * function will never return. It also enables the compiler to avoid spurious |
michael@0 | 177 | * warnings about not initializing variables, or about any other seemingly-dodgy |
michael@0 | 178 | * operations performed after the function returns. |
michael@0 | 179 | * |
michael@0 | 180 | * This modifier does not affect the corresponding function's linking behavior. |
michael@0 | 181 | */ |
michael@0 | 182 | #if defined(MOZ_HAVE_NORETURN) |
michael@0 | 183 | # define MOZ_NORETURN MOZ_HAVE_NORETURN |
michael@0 | 184 | #else |
michael@0 | 185 | # define MOZ_NORETURN /* no support */ |
michael@0 | 186 | #endif |
michael@0 | 187 | |
michael@0 | 188 | /* |
michael@0 | 189 | * MOZ_ASAN_BLACKLIST is a macro to tell AddressSanitizer (a compile-time |
michael@0 | 190 | * instrumentation shipped with Clang and GCC) to not instrument the annotated |
michael@0 | 191 | * function. Furthermore, it will prevent the compiler from inlining the |
michael@0 | 192 | * function because inlining currently breaks the blacklisting mechanism of |
michael@0 | 193 | * AddressSanitizer. |
michael@0 | 194 | */ |
michael@0 | 195 | #if defined(__has_feature) |
michael@0 | 196 | # if __has_feature(address_sanitizer) |
michael@0 | 197 | # define MOZ_HAVE_ASAN_BLACKLIST |
michael@0 | 198 | # endif |
michael@0 | 199 | #elif defined(__GNUC__) |
michael@0 | 200 | # if defined(__SANITIZE_ADDRESS__) |
michael@0 | 201 | # define MOZ_HAVE_ASAN_BLACKLIST |
michael@0 | 202 | # endif |
michael@0 | 203 | #endif |
michael@0 | 204 | |
michael@0 | 205 | #if defined(MOZ_HAVE_ASAN_BLACKLIST) |
michael@0 | 206 | # define MOZ_ASAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_address)) |
michael@0 | 207 | #else |
michael@0 | 208 | # define MOZ_ASAN_BLACKLIST /* nothing */ |
michael@0 | 209 | #endif |
michael@0 | 210 | |
michael@0 | 211 | /* |
michael@0 | 212 | * MOZ_TSAN_BLACKLIST is a macro to tell ThreadSanitizer (a compile-time |
michael@0 | 213 | * instrumentation shipped with Clang) to not instrument the annotated function. |
michael@0 | 214 | * Furthermore, it will prevent the compiler from inlining the function because |
michael@0 | 215 | * inlining currently breaks the blacklisting mechanism of ThreadSanitizer. |
michael@0 | 216 | */ |
michael@0 | 217 | #if defined(__has_feature) |
michael@0 | 218 | # if __has_feature(thread_sanitizer) |
michael@0 | 219 | # define MOZ_TSAN_BLACKLIST MOZ_NEVER_INLINE __attribute__((no_sanitize_thread)) |
michael@0 | 220 | # else |
michael@0 | 221 | # define MOZ_TSAN_BLACKLIST /* nothing */ |
michael@0 | 222 | # endif |
michael@0 | 223 | #else |
michael@0 | 224 | # define MOZ_TSAN_BLACKLIST /* nothing */ |
michael@0 | 225 | #endif |
michael@0 | 226 | |
michael@0 | 227 | #ifdef __cplusplus |
michael@0 | 228 | |
michael@0 | 229 | /* |
michael@0 | 230 | * MOZ_DELETE, specified immediately prior to the ';' terminating an undefined- |
michael@0 | 231 | * method declaration, attempts to delete that method from the corresponding |
michael@0 | 232 | * class. An attempt to use the method will always produce an error *at compile |
michael@0 | 233 | * time* (instead of sometimes as late as link time) when this macro can be |
michael@0 | 234 | * implemented. For example, you can use MOZ_DELETE to produce classes with no |
michael@0 | 235 | * implicit copy constructor or assignment operator: |
michael@0 | 236 | * |
michael@0 | 237 | * struct NonCopyable |
michael@0 | 238 | * { |
michael@0 | 239 | * private: |
michael@0 | 240 | * NonCopyable(const NonCopyable& other) MOZ_DELETE; |
michael@0 | 241 | * void operator=(const NonCopyable& other) MOZ_DELETE; |
michael@0 | 242 | * }; |
michael@0 | 243 | * |
michael@0 | 244 | * If MOZ_DELETE can't be implemented for the current compiler, use of the |
michael@0 | 245 | * annotated method will still cause an error, but the error might occur at link |
michael@0 | 246 | * time in some cases rather than at compile time. |
michael@0 | 247 | * |
michael@0 | 248 | * MOZ_DELETE relies on C++11 functionality not universally implemented. As a |
michael@0 | 249 | * backstop, method declarations using MOZ_DELETE should be private. |
michael@0 | 250 | */ |
michael@0 | 251 | #if defined(MOZ_HAVE_CXX11_DELETE) |
michael@0 | 252 | # define MOZ_DELETE = delete |
michael@0 | 253 | #else |
michael@0 | 254 | # define MOZ_DELETE /* no support */ |
michael@0 | 255 | #endif |
michael@0 | 256 | |
michael@0 | 257 | /* |
michael@0 | 258 | * MOZ_OVERRIDE explicitly indicates that a virtual member function in a class |
michael@0 | 259 | * overrides a member function of a base class, rather than potentially being a |
michael@0 | 260 | * new member function. MOZ_OVERRIDE should be placed immediately before the |
michael@0 | 261 | * ';' terminating the member function's declaration, or before '= 0;' if the |
michael@0 | 262 | * member function is pure. If the member function is defined in the class |
michael@0 | 263 | * definition, it should appear before the opening brace of the function body. |
michael@0 | 264 | * |
michael@0 | 265 | * class Base |
michael@0 | 266 | * { |
michael@0 | 267 | * public: |
michael@0 | 268 | * virtual void f() = 0; |
michael@0 | 269 | * }; |
michael@0 | 270 | * class Derived1 : public Base |
michael@0 | 271 | * { |
michael@0 | 272 | * public: |
michael@0 | 273 | * virtual void f() MOZ_OVERRIDE; |
michael@0 | 274 | * }; |
michael@0 | 275 | * class Derived2 : public Base |
michael@0 | 276 | * { |
michael@0 | 277 | * public: |
michael@0 | 278 | * virtual void f() MOZ_OVERRIDE = 0; |
michael@0 | 279 | * }; |
michael@0 | 280 | * class Derived3 : public Base |
michael@0 | 281 | * { |
michael@0 | 282 | * public: |
michael@0 | 283 | * virtual void f() MOZ_OVERRIDE { } |
michael@0 | 284 | * }; |
michael@0 | 285 | * |
michael@0 | 286 | * In compilers supporting C++11 override controls, MOZ_OVERRIDE *requires* that |
michael@0 | 287 | * the function marked with it override a member function of a base class: it |
michael@0 | 288 | * is a compile error if it does not. Otherwise MOZ_OVERRIDE does not affect |
michael@0 | 289 | * semantics and merely documents the override relationship to the reader (but |
michael@0 | 290 | * of course must still be used correctly to not break C++11 compilers). |
michael@0 | 291 | */ |
michael@0 | 292 | #if defined(MOZ_HAVE_CXX11_OVERRIDE) |
michael@0 | 293 | # define MOZ_OVERRIDE override |
michael@0 | 294 | #else |
michael@0 | 295 | # define MOZ_OVERRIDE /* no support */ |
michael@0 | 296 | #endif |
michael@0 | 297 | |
michael@0 | 298 | /* |
michael@0 | 299 | * MOZ_FINAL indicates that some functionality cannot be overridden through |
michael@0 | 300 | * inheritance. It can be used to annotate either classes/structs or virtual |
michael@0 | 301 | * member functions. |
michael@0 | 302 | * |
michael@0 | 303 | * To annotate a class/struct with MOZ_FINAL, place MOZ_FINAL immediately after |
michael@0 | 304 | * the name of the class, before the list of classes from which it derives (if |
michael@0 | 305 | * any) and before its opening brace. MOZ_FINAL must not be used to annotate |
michael@0 | 306 | * unnamed classes or structs. (With some compilers, and with C++11 proper, the |
michael@0 | 307 | * underlying expansion is ambiguous with specifying a class name.) |
michael@0 | 308 | * |
michael@0 | 309 | * class Base MOZ_FINAL |
michael@0 | 310 | * { |
michael@0 | 311 | * public: |
michael@0 | 312 | * Base(); |
michael@0 | 313 | * ~Base(); |
michael@0 | 314 | * virtual void f() { } |
michael@0 | 315 | * }; |
michael@0 | 316 | * // This will be an error in some compilers: |
michael@0 | 317 | * class Derived : public Base |
michael@0 | 318 | * { |
michael@0 | 319 | * public: |
michael@0 | 320 | * ~Derived() { } |
michael@0 | 321 | * }; |
michael@0 | 322 | * |
michael@0 | 323 | * One particularly common reason to specify MOZ_FINAL upon a class is to tell |
michael@0 | 324 | * the compiler that it's not dangerous for it to have a non-virtual destructor |
michael@0 | 325 | * yet have one or more virtual functions, silencing the warning it might emit |
michael@0 | 326 | * in this case. Suppose Base above weren't annotated with MOZ_FINAL. Because |
michael@0 | 327 | * ~Base() is non-virtual, an attempt to delete a Derived* through a Base* |
michael@0 | 328 | * wouldn't call ~Derived(), so any cleanup ~Derived() might do wouldn't happen. |
michael@0 | 329 | * (Formally C++ says behavior is undefined, but compilers will likely just call |
michael@0 | 330 | * ~Base() and not ~Derived().) Specifying MOZ_FINAL tells the compiler that |
michael@0 | 331 | * it's safe for the destructor to be non-virtual. |
michael@0 | 332 | * |
michael@0 | 333 | * In compilers implementing final controls, it is an error to inherit from a |
michael@0 | 334 | * class annotated with MOZ_FINAL. In other compilers it serves only as |
michael@0 | 335 | * documentation. |
michael@0 | 336 | * |
michael@0 | 337 | * To annotate a virtual member function with MOZ_FINAL, place MOZ_FINAL |
michael@0 | 338 | * immediately before the ';' terminating the member function's declaration, or |
michael@0 | 339 | * before '= 0;' if the member function is pure. If the member function is |
michael@0 | 340 | * defined in the class definition, it should appear before the opening brace of |
michael@0 | 341 | * the function body. (This placement is identical to that for MOZ_OVERRIDE. |
michael@0 | 342 | * If both are used, they should appear in the order 'MOZ_FINAL MOZ_OVERRIDE' |
michael@0 | 343 | * for consistency.) |
michael@0 | 344 | * |
michael@0 | 345 | * class Base |
michael@0 | 346 | * { |
michael@0 | 347 | * public: |
michael@0 | 348 | * virtual void f() MOZ_FINAL; |
michael@0 | 349 | * }; |
michael@0 | 350 | * class Derived |
michael@0 | 351 | * { |
michael@0 | 352 | * public: |
michael@0 | 353 | * // This will be an error in some compilers: |
michael@0 | 354 | * virtual void f(); |
michael@0 | 355 | * }; |
michael@0 | 356 | * |
michael@0 | 357 | * In compilers implementing final controls, it is an error for a derived class |
michael@0 | 358 | * to override a method annotated with MOZ_FINAL. In other compilers it serves |
michael@0 | 359 | * only as documentation. |
michael@0 | 360 | */ |
michael@0 | 361 | #if defined(MOZ_HAVE_CXX11_FINAL) |
michael@0 | 362 | # define MOZ_FINAL MOZ_HAVE_CXX11_FINAL |
michael@0 | 363 | #else |
michael@0 | 364 | # define MOZ_FINAL /* no support */ |
michael@0 | 365 | #endif |
michael@0 | 366 | |
michael@0 | 367 | /** |
michael@0 | 368 | * MOZ_WARN_UNUSED_RESULT tells the compiler to emit a warning if a function's |
michael@0 | 369 | * return value is not used by the caller. |
michael@0 | 370 | * |
michael@0 | 371 | * Place this attribute at the very beginning of a function definition. For |
michael@0 | 372 | * example, write |
michael@0 | 373 | * |
michael@0 | 374 | * MOZ_WARN_UNUSED_RESULT int foo(); |
michael@0 | 375 | * |
michael@0 | 376 | * or |
michael@0 | 377 | * |
michael@0 | 378 | * MOZ_WARN_UNUSED_RESULT int foo() { return 42; } |
michael@0 | 379 | */ |
michael@0 | 380 | #if defined(__GNUC__) || defined(__clang__) |
michael@0 | 381 | # define MOZ_WARN_UNUSED_RESULT __attribute__ ((warn_unused_result)) |
michael@0 | 382 | #else |
michael@0 | 383 | # define MOZ_WARN_UNUSED_RESULT |
michael@0 | 384 | #endif |
michael@0 | 385 | |
michael@0 | 386 | /* |
michael@0 | 387 | * The following macros are attributes that support the static analysis plugin |
michael@0 | 388 | * included with Mozilla, and will be implemented (when such support is enabled) |
michael@0 | 389 | * as C++11 attributes. Since such attributes are legal pretty much everywhere |
michael@0 | 390 | * and have subtly different semantics depending on their placement, the |
michael@0 | 391 | * following is a guide on where to place the attributes. |
michael@0 | 392 | * |
michael@0 | 393 | * Attributes that apply to a struct or class precede the name of the class: |
michael@0 | 394 | * (Note that this is different from the placement of MOZ_FINAL for classes!) |
michael@0 | 395 | * |
michael@0 | 396 | * class MOZ_CLASS_ATTRIBUTE SomeClass {}; |
michael@0 | 397 | * |
michael@0 | 398 | * Attributes that apply to functions follow the parentheses and const |
michael@0 | 399 | * qualifiers but precede MOZ_FINAL, MOZ_OVERRIDE and the function body: |
michael@0 | 400 | * |
michael@0 | 401 | * void DeclaredFunction() MOZ_FUNCTION_ATTRIBUTE; |
michael@0 | 402 | * void SomeFunction() MOZ_FUNCTION_ATTRIBUTE {} |
michael@0 | 403 | * void PureFunction() const MOZ_FUNCTION_ATTRIBUTE = 0; |
michael@0 | 404 | * void OverriddenFunction() MOZ_FUNCTION_ATTIRBUTE MOZ_OVERRIDE; |
michael@0 | 405 | * |
michael@0 | 406 | * Attributes that apply to variables or parameters follow the variable's name: |
michael@0 | 407 | * |
michael@0 | 408 | * int variable MOZ_VARIABLE_ATTRIBUTE; |
michael@0 | 409 | * |
michael@0 | 410 | * Attributes that apply to types follow the type name: |
michael@0 | 411 | * |
michael@0 | 412 | * typedef int MOZ_TYPE_ATTRIBUTE MagicInt; |
michael@0 | 413 | * int MOZ_TYPE_ATTRIBUTE someVariable; |
michael@0 | 414 | * int * MOZ_TYPE_ATTRIBUTE magicPtrInt; |
michael@0 | 415 | * int MOZ_TYPE_ATTRIBUTE * ptrToMagicInt; |
michael@0 | 416 | * |
michael@0 | 417 | * Attributes that apply to statements precede the statement: |
michael@0 | 418 | * |
michael@0 | 419 | * MOZ_IF_ATTRIBUTE if (x == 0) |
michael@0 | 420 | * MOZ_DO_ATTRIBUTE do { } while(0); |
michael@0 | 421 | * |
michael@0 | 422 | * Attributes that apply to labels precede the label: |
michael@0 | 423 | * |
michael@0 | 424 | * MOZ_LABEL_ATTRIBUTE target: |
michael@0 | 425 | * goto target; |
michael@0 | 426 | * MOZ_CASE_ATTRIBUTE case 5: |
michael@0 | 427 | * MOZ_DEFAULT_ATTRIBUTE default: |
michael@0 | 428 | * |
michael@0 | 429 | * The static analyses that are performed by the plugin are as follows: |
michael@0 | 430 | * |
michael@0 | 431 | * MOZ_MUST_OVERRIDE: Applies to all C++ member functions. All immediate |
michael@0 | 432 | * subclasses must provide an exact override of this method; if a subclass |
michael@0 | 433 | * does not override this method, the compiler will emit an error. This |
michael@0 | 434 | * attribute is not limited to virtual methods, so if it is applied to a |
michael@0 | 435 | * nonvirtual method and the subclass does not provide an equivalent |
michael@0 | 436 | * definition, the compiler will emit an error. |
michael@0 | 437 | * MOZ_STACK_CLASS: Applies to all classes. Any class with this annotation is |
michael@0 | 438 | * expected to live on the stack, so it is a compile-time error to use it, or |
michael@0 | 439 | * an array of such objects, as a global or static variable, or as the type of |
michael@0 | 440 | * a new expression (unless placement new is being used). If a member of |
michael@0 | 441 | * another class uses this class, or if another class inherits from this |
michael@0 | 442 | * class, then it is considered to be a stack class as well, although this |
michael@0 | 443 | * attribute need not be provided in such cases. |
michael@0 | 444 | * MOZ_NONHEAP_CLASS: Applies to all classes. Any class with this annotation is |
michael@0 | 445 | * expected to live on the stack or in static storage, so it is a compile-time |
michael@0 | 446 | * error to use it, or an array of such objects, as the type of a new |
michael@0 | 447 | * expression (unless placement new is being used). If a member of another |
michael@0 | 448 | * class uses this class, or if another class inherits from this class, then |
michael@0 | 449 | * it is considered to be a non-heap class as well, although this attribute |
michael@0 | 450 | * need not be provided in such cases. |
michael@0 | 451 | * MOZ_HEAP_ALLOCATOR: Applies to any function. This indicates that the return |
michael@0 | 452 | * value is allocated on the heap, and will as a result check such allocations |
michael@0 | 453 | * during MOZ_STACK_CLASS and MOZ_NONHEAP_CLASS annotation checking. |
michael@0 | 454 | */ |
michael@0 | 455 | #ifdef MOZ_CLANG_PLUGIN |
michael@0 | 456 | # define MOZ_MUST_OVERRIDE __attribute__((annotate("moz_must_override"))) |
michael@0 | 457 | # define MOZ_STACK_CLASS __attribute__((annotate("moz_stack_class"))) |
michael@0 | 458 | # define MOZ_NONHEAP_CLASS __attribute__((annotate("moz_nonheap_class"))) |
michael@0 | 459 | /* |
michael@0 | 460 | * It turns out that clang doesn't like void func() __attribute__ {} without a |
michael@0 | 461 | * warning, so use pragmas to disable the warning. This code won't work on GCC |
michael@0 | 462 | * anyways, so the warning is safe to ignore. |
michael@0 | 463 | */ |
michael@0 | 464 | # define MOZ_HEAP_ALLOCATOR \ |
michael@0 | 465 | _Pragma("clang diagnostic push") \ |
michael@0 | 466 | _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ |
michael@0 | 467 | __attribute__((annotate("moz_heap_allocator"))) \ |
michael@0 | 468 | _Pragma("clang diagnostic pop") |
michael@0 | 469 | #else |
michael@0 | 470 | # define MOZ_MUST_OVERRIDE /* nothing */ |
michael@0 | 471 | # define MOZ_STACK_CLASS /* nothing */ |
michael@0 | 472 | # define MOZ_NONHEAP_CLASS /* nothing */ |
michael@0 | 473 | # define MOZ_HEAP_ALLOCATOR /* nothing */ |
michael@0 | 474 | #endif /* MOZ_CLANG_PLUGIN */ |
michael@0 | 475 | |
michael@0 | 476 | /* |
michael@0 | 477 | * MOZ_THIS_IN_INITIALIZER_LIST is used to avoid a warning when we know that |
michael@0 | 478 | * it's safe to use 'this' in an initializer list. |
michael@0 | 479 | */ |
michael@0 | 480 | #ifdef _MSC_VER |
michael@0 | 481 | # define MOZ_THIS_IN_INITIALIZER_LIST() \ |
michael@0 | 482 | __pragma(warning(push)) \ |
michael@0 | 483 | __pragma(warning(disable:4355)) \ |
michael@0 | 484 | this \ |
michael@0 | 485 | __pragma(warning(pop)) |
michael@0 | 486 | #else |
michael@0 | 487 | # define MOZ_THIS_IN_INITIALIZER_LIST() this |
michael@0 | 488 | #endif |
michael@0 | 489 | |
michael@0 | 490 | #endif /* __cplusplus */ |
michael@0 | 491 | |
michael@0 | 492 | #endif /* mozilla_Attributes_h */ |