LCOV - code coverage report
Current view: top level - source/lib - code_annotation.h (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 1 100.0 %
Date: 2023-01-19 00:18:29 Functions: 2 3 66.7 %

          Line data    Source code
       1             : /* Copyright (c) 2021 Wildfire Games.
       2             :  *
       3             :  * Permission is hereby granted, free of charge, to any person obtaining
       4             :  * a copy of this software and associated documentation files (the
       5             :  * "Software"), to deal in the Software without restriction, including
       6             :  * without limitation the rights to use, copy, modify, merge, publish,
       7             :  * distribute, sublicense, and/or sell copies of the Software, and to
       8             :  * permit persons to whom the Software is furnished to do so, subject to
       9             :  * the following conditions:
      10             :  *
      11             :  * The above copyright notice and this permission notice shall be included
      12             :  * in all copies or substantial portions of the Software.
      13             :  *
      14             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
      15             :  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
      16             :  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
      17             :  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
      18             :  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
      19             :  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
      20             :  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
      21             :  */
      22             : 
      23             : /*
      24             :  * macros for code annotation.
      25             :  */
      26             : 
      27             : #ifndef INCLUDED_CODE_ANNOTATION
      28             : #define INCLUDED_CODE_ANNOTATION
      29             : 
      30             : #include "lib/sysdep/compiler.h"
      31             : #include "lib/sysdep/arch.h"  // ARCH_AMD64
      32             : 
      33             : /**
      34             :  * mark a function parameter as unused and avoid
      35             :  * the corresponding compiler warning.
      36             :  * wrap around the parameter name, e.g. void f(int UNUSED(x))
      37             :  **/
      38             : #define UNUSED(param)
      39             : 
      40             : /**
      41             :  * mark a function local variable or parameter as unused and avoid
      42             :  * the corresponding compiler warning.
      43             :  * note that UNUSED is not applicable to variable definitions that
      44             :  * involve initialization, nor is it sufficient in cases where
      45             :  * an argument is unused only in certain situations.
      46             :  * example: void f(int x) { ASSERT(x == 0); UNUSED2(x); }
      47             :  * this asserts in debug builds and avoids warnings in release.
      48             :  **/
      49             : #if HAVE_C99 && GCC_VERSION // _Pragma from C99, unused from GCC
      50             : # define UNUSED2(param) _Pragma("unused " #param)
      51             : #elif ICC_VERSION
      52             : // ICC 12 still doesn't recognize pragma unused, casting to void
      53             : // isn't sufficient, and self-assignment doesn't work for references.
      54             : # define UNUSED2(param) do{ if(&param) {} } while(false)
      55             : #else
      56             : # define UNUSED2(param) ((void)(param))
      57             : #endif
      58             : 
      59             : /**
      60             :  * Silence the 'unused result' warning.
      61             :  * (void) would be sufficient but Spidermonkey still uses warn_unused_result,
      62             :  * and GCC is stricter about that. See https://bugzilla.mozilla.org/show_bug.cgi?id=1571631.
      63             :  **/
      64             : template<typename T>
      65         246 : inline void ignore_result(const T&) {}
      66             : 
      67             : /**
      68             :  * indicate a function will not throw any synchronous exceptions,
      69             :  * thus hopefully generating smaller and more efficient code.
      70             :  *
      71             :  * must be placed BEFORE return types because "The [VC++] compiler
      72             :  * ignores, without warning, any __declspec keywords placed after *".
      73             :  * such syntax is apparently also legal in GCC, per the example
      74             :  * "__attribute__((noreturn)) void d0 (void)".
      75             :  *
      76             :  * example:
      77             :  * NOTHROW_DECLARE void function();
      78             :  * NOTHROW_DEFINE void function() {}
      79             :  **/
      80             : #if GCC_VERSION
      81             : # define NOTHROW_DECLARE __attribute__((nothrow))
      82             : # define NOTHROW_DEFINE // not supported for definitions
      83             : #elif CLANG_VERSION
      84             : # define NOTHROW_DECLARE __attribute__((nothrow))
      85             : # define NOTHROW_DEFINE // not supported for definitions
      86             : #elif MSC_VERSION
      87             : // Kevin Frei, 2006-03-23: "I work on the Visual C++ compiler team,
      88             : // and agree completely with Paul Parks: don't use throw(), because
      89             : // there's a chance that we'll eventually implement it according to the standard".
      90             : # define NOTHROW_DECLARE __declspec(nothrow)
      91             : # define NOTHROW_DEFINE __declspec(nothrow)
      92             : #else
      93             : // don't use throw() because it might result in ADDITIONAL checks
      94             : // (the standard mandates calling unexpected())
      95             : # define NOTHROW_DECLARE
      96             : # define NOTHROW_DEFINE
      97             : #endif
      98             : 
      99             : 
     100             : /**
     101             :  * mark a function as noreturn for static analyzer purposes.
     102             :  * currently only for clang-analyzer.
     103             :  */
     104             : #if __has_feature(attribute_analyzer_noreturn)
     105             : # define ANALYZER_NORETURN __attribute__((analyzer_noreturn))
     106             : #else
     107             : # define ANALYZER_NORETURN
     108             : #endif
     109             : 
     110             : 
     111             : /**
     112             :  * "unreachable code" helpers
     113             :  *
     114             :  * unreachable lines of code are often the source or symptom of subtle bugs.
     115             :  * they are flagged by compiler warnings; however, the opposite problem -
     116             :  * erroneously reaching certain spots (e.g. due to missing return statement)
     117             :  * is worse and not detected automatically.
     118             :  *
     119             :  * to defend against this, the programmer can annotate their code to
     120             :  * indicate to humans that a particular spot should never be reached.
     121             :  * however, that isn't much help; better is a sentinel that raises an
     122             :  * error if if it is actually reached. hence, the UNREACHABLE macro.
     123             :  *
     124             :  * ironically, if the code guarded by UNREACHABLE works as it should,
     125             :  * compilers may flag the macro's code as unreachable. this would
     126             :  * distract from genuine warnings, which is unacceptable.
     127             :  *
     128             :  * even worse, compilers differ in their code checking: GCC only complains if
     129             :  * non-void functions end without returning a value (i.e. missing return
     130             :  * statement), while VC checks if lines are unreachable (e.g. if they are
     131             :  * preceded by a return on all paths).
     132             :  *
     133             :  * the implementation below enables optimization and automated checking
     134             :  * without raising warnings.
     135             :  **/
     136             : #define UNREACHABLE // actually defined below.. this is for
     137             : # undef UNREACHABLE // CppDoc's benefit only.
     138             : 
     139             : // this macro should not generate any fallback code; it is merely the
     140             : // compiler-specific backend for UNREACHABLE.
     141             : // #define it to nothing if the compiler doesn't support such a hint.
     142             : #define HAVE_ASSUME_UNREACHABLE 1
     143             : #if MSC_VERSION && !ICC_VERSION // (ICC ignores this)
     144             : # define ASSUME_UNREACHABLE __assume(0)
     145             : #elif GCC_VERSION
     146             : # define ASSUME_UNREACHABLE __builtin_unreachable()
     147             : #else
     148             : # define ASSUME_UNREACHABLE
     149             : # undef HAVE_ASSUME_UNREACHABLE
     150             : # define HAVE_ASSUME_UNREACHABLE 0
     151             : #endif
     152             : 
     153             : // compiler supports ASSUME_UNREACHABLE => allow it to assume the code is
     154             : // never reached (improves optimization at the cost of undefined behavior
     155             : // if the annotation turns out to be incorrect).
     156             : #if HAVE_ASSUME_UNREACHABLE && !CONFIG_ENABLE_CHECKS
     157             : # define UNREACHABLE ASSUME_UNREACHABLE
     158             : // otherwise (or if CONFIG_ENABLE_CHECKS is set), add a user-visible
     159             : // warning if the code is reached. note that abort() fails to stop
     160             : // ICC from warning about the lack of a return statement, so we
     161             : // use an infinite loop instead.
     162             : #else
     163             : # define UNREACHABLE\
     164             :     STMT(\
     165             :         DEBUG_WARN_ERR(ERR::LOGIC); /* hit supposedly unreachable code */\
     166             :         for(;;){};\
     167             :     )
     168             : #endif
     169             : 
     170             : /**
     171             : convenient specialization of UNREACHABLE for switch statements whose
     172             : default can never be reached. example usage:
     173             : int x;
     174             : switch(x % 2)
     175             : {
     176             :     case 0: break;
     177             :     case 1: break;
     178             :     NODEFAULT;
     179             : }
     180             : **/
     181             : #define NODEFAULT default: UNREACHABLE
     182             : 
     183             : 
     184             : // generate a symbol containing the line number of the macro invocation.
     185             : // used to give a unique name (per file) to types or variables.
     186             : // we can't prepend __FILE__ to make it globally unique - the filename
     187             : // may be enclosed in quotes. PASTE3_HIDDEN__ is needed to make sure
     188             : // __LINE__ is expanded correctly.
     189             : #define PASTE3_HIDDEN__(a, b, c) a ## b ## c
     190             : #define PASTE3__(a, b, c) PASTE3_HIDDEN__(a, b, c)
     191             : #define UID__  PASTE3__(LINE_, __LINE__, _)
     192             : #define UID2__ PASTE3__(LINE_, __LINE__, _2)
     193             : 
     194             : 
     195             : //-----------------------------------------------------------------------------
     196             : // cassert
     197             : 
     198             : /**
     199             :  * Compile-time assertion. Causes a compile error if the expression
     200             :  * evaluates to zero/false.
     201             :  *
     202             :  * No runtime overhead; may be used anywhere, including file scope.
     203             :  * Especially useful for testing sizeof types.
     204             :  *
     205             :  * @param expr Expression that is expected to evaluate to non-zero at compile-time.
     206             :  **/
     207             : #define cassert(expr) static_assert((expr), #expr)
     208             : 
     209             : 
     210             : /**
     211             :  * Indicates that a class is noncopyable (usually due to const or reference
     212             :  * members, or because the class works as a singleton).
     213             :  *
     214             :  * For example:
     215             :  *
     216             :  * @code
     217             :  * class ClassName {
     218             :  *   NONCOPYABLE(ClassName);
     219             :  * public: // etc.
     220             :  * };
     221             :  * @endcode
     222             :  *
     223             :  * This is preferable to inheritance from boost::noncopyable because it avoids
     224             :  * ICC 11 W4 warnings about non-virtual dtors and suppression of the copy
     225             :  * assignment operator.
     226             :  */
     227             : #define NONCOPYABLE(className) \
     228             :     className(const className&) = delete; \
     229             :     className& operator=(const className&) = delete
     230             : 
     231             : /**
     232             :  * Indicates that move semantics can be used, so that a NONCOPYABLE class can still be assigned by taking over the reference to the value.
     233             :  * Make sure to use the macro with the necessary access modifier.
     234             :  */
     235             : #define MOVABLE(className) \
     236             :     className(className&&) = default; \
     237             :     className& operator=(className&&) = default
     238             : 
     239             : #if ICC_VERSION
     240             : # define ASSUME_ALIGNED(ptr, multiple) __assume_aligned(ptr, multiple)
     241             : #else
     242             : # define ASSUME_ALIGNED(ptr, multiple)
     243             : #endif
     244             : 
     245             : // annotate printf-style functions for compile-time type checking.
     246             : // fmtpos is the index of the format argument, counting from 1 or
     247             : // (if it's a non-static class function) 2; the '...' is assumed
     248             : // to come directly after it.
     249             : #if GCC_VERSION
     250             : # define PRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, fmtpos+1)))
     251             : # define VPRINTF_ARGS(fmtpos) __attribute__ ((format (printf, fmtpos, 0)))
     252             : # define WPRINTF_ARGS(fmtpos) /* not currently supported in GCC */
     253             : # define VWPRINTF_ARGS(fmtpos) /* not currently supported in GCC */
     254             : #else
     255             : # define PRINTF_ARGS(fmtpos)
     256             : # define VPRINTF_ARGS(fmtpos)
     257             : # define WPRINTF_ARGS(fmtpos)
     258             : # define VWPRINTF_ARGS(fmtpos)
     259             : // TODO: support _Printf_format_string_ for VC9+
     260             : #endif
     261             : 
     262             : // annotate vararg functions that expect to end with an explicit NULL
     263             : #if GCC_VERSION
     264             : # define SENTINEL_ARG __attribute__ ((sentinel))
     265             : #else
     266             : # define SENTINEL_ARG
     267             : #endif
     268             : 
     269             : /**
     270             :  * prevent the compiler from reordering loads or stores across this point.
     271             :  **/
     272             : #if ICC_VERSION
     273             : # define COMPILER_FENCE __memory_barrier()
     274             : #elif MSC_VERSION
     275             : # include <intrin.h>
     276             : # pragma intrinsic(_ReadWriteBarrier)
     277             : # define COMPILER_FENCE _ReadWriteBarrier()
     278             : #elif GCC_VERSION
     279             : # define COMPILER_FENCE asm volatile("" : : : "memory")
     280             : #else
     281             : # define COMPILER_FENCE
     282             : #endif
     283             : 
     284             : 
     285             : // try to define _W64, if not already done
     286             : // (this is useful for catching pointer size bugs)
     287             : #ifndef _W64
     288             : # if MSC_VERSION
     289             : #  define _W64 __w64
     290             : # elif GCC_VERSION
     291             : #  define _W64 __attribute__((mode (__pointer__)))
     292             : # else
     293             : #  define _W64
     294             : # endif
     295             : #endif
     296             : 
     297             : 
     298             : // C99-like restrict (non-standard in C++, but widely supported in various forms).
     299             : //
     300             : // May be used on pointers. May also be used on member functions to indicate
     301             : // that 'this' is unaliased (e.g. "void C::m() RESTRICT { ... }").
     302             : // Must not be used on references - GCC supports that but VC doesn't.
     303             : //
     304             : // We call this "RESTRICT" to avoid conflicts with VC's __declspec(restrict),
     305             : // and because it's not really the same as C99's restrict.
     306             : //
     307             : // To be safe and satisfy the compilers' stated requirements: an object accessed
     308             : // by a restricted pointer must not be accessed by any other pointer within the
     309             : // lifetime of the restricted pointer, if the object is modified.
     310             : // To maximise the chance of optimisation, any pointers that could potentially
     311             : // alias with the restricted one should be marked as restricted too.
     312             : //
     313             : // It would probably be a good idea to write test cases for any code that uses
     314             : // this in an even very slightly unclear way, in case it causes obscure problems
     315             : // in a rare compiler due to differing semantics.
     316             : //
     317             : // .. GCC
     318             : #if GCC_VERSION
     319             : # define RESTRICT __restrict__
     320             : // .. VC8 provides __restrict
     321             : #elif MSC_VERSION
     322             : # define RESTRICT __restrict
     323             : // .. ICC supports the keyword 'restrict' when run with the /Qrestrict option,
     324             : //    but it always also supports __restrict__ or __restrict to be compatible
     325             : //    with GCC/MSVC, so we'll use the underscored version. One of {GCC,MSC}_VERSION
     326             : //    should have been defined in addition to ICC_VERSION, so we should be using
     327             : //    one of the above cases (unless it's an old VS7.1-emulating ICC).
     328             : #elif ICC_VERSION
     329             : # error ICC_VERSION defined without either GCC_VERSION or an adequate MSC_VERSION
     330             : // .. unsupported; remove it from code
     331             : #else
     332             : # define RESTRICT
     333             : #endif
     334             : 
     335             : 
     336             : //
     337             : // number of array elements
     338             : //
     339             : 
     340             : // (function taking a reference to an array and returning a pointer to
     341             : // an array of characters. it's only declared and never defined; we just
     342             : // need it to determine n, the size of the array that was passed.)
     343             : template<typename T, size_t n> char (*ArraySizeDeducer(T (&)[n]))[n];
     344             : 
     345             : // (although requiring C++, this method is much better than the standard
     346             : // sizeof(name) / sizeof(name[0]) because it doesn't compile when a
     347             : // pointer is passed, which can easily happen under maintenance.)
     348             : #define ARRAY_SIZE(name) (sizeof(*ArraySizeDeducer(name)))
     349             : 
     350             : 
     351             : // C99-style __func__
     352             : // .. newer GCC already have it
     353             : #if GCC_VERSION
     354             : // nothing need be done
     355             : // .. MSVC have __FUNCTION__
     356             : #elif MSC_VERSION
     357             : # define __func__ __FUNCTION__
     358             : // .. unsupported
     359             : #else
     360             : # define __func__ "(unknown)"
     361             : #endif
     362             : 
     363             : 
     364             : // extern "C", but does the right thing in pure-C mode
     365             : #if defined(__cplusplus)
     366             : # define EXTERN_C extern "C"
     367             : #else
     368             : # define EXTERN_C extern
     369             : #endif
     370             : 
     371             : 
     372             : #if MSC_VERSION
     373             : # define INLINE __forceinline
     374             : #else
     375             : # define INLINE inline
     376             : #endif
     377             : 
     378             : 
     379             : #if MSC_VERSION
     380             : # define CALL_CONV __cdecl
     381             : #else
     382             : # define CALL_CONV
     383             : #endif
     384             : 
     385             : 
     386             : #if MSC_VERSION && !ARCH_AMD64
     387             : # define DECORATED_NAME(name) _##name
     388             : #else
     389             : # define DECORATED_NAME(name) name
     390             : #endif
     391             : 
     392             : 
     393             : // workaround for preprocessor limitation: macro args aren't expanded
     394             : // before being pasted.
     395             : #define STRINGIZE2(id) # id
     396             : #define STRINGIZE(id) STRINGIZE2(id)
     397             : 
     398             : // for widening non-literals (e.g. __FILE__)
     399             : // note: C99 says __func__ is a magic *variable*, and GCC doesn't allow
     400             : // widening it via preprocessor.
     401             : #define WIDEN2(x) L ## x
     402             : #define WIDEN(x) WIDEN2(x)
     403             : 
     404             : // TODO: Replace this with [[fallthrough]] once we support C++17
     405             : #if __has_cpp_attribute(fallthrough) || defined(__cplusplus) && __cplusplus >= 201703L
     406             : # define FALLTHROUGH [[fallthrough]]
     407             : #elif __has_cpp_attribute(gnu::fallthrough)
     408             : # define FALLTHROUGH [[gnu::fallthrough]]
     409             : #elif __has_cpp_attribute(clang::fallthrough)
     410             : # define FALLTHROUGH [[clang::fallthrough]]
     411             : #else
     412             : # define FALLTHROUGH
     413             : // TODO: Maybe use __fallthrough for the MSVC code analyzer (also figure out if we need to add some switch when switching to a newer version of VS that supports [[fallthrough]]
     414             : #endif
     415             : 
     416             : #endif  // #ifndef INCLUDED_CODE_ANNOTATION

Generated by: LCOV version 1.13