mfbt/Attributes.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

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.

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

mercurial