compat_compiler.h (8807B)
1 /* Copyright (c) 2003-2004, Roger Dingledine 2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson. 3 * Copyright (c) 2007-2021, The Tor Project, Inc. */ 4 /* See LICENSE for licensing information */ 5 6 /** 7 * \file compat_compiler.h 8 * \brief Utility macros to handle different features and behavior in different 9 * compilers. 10 **/ 11 12 #ifndef TOR_COMPAT_COMPILER_H 13 #define TOR_COMPAT_COMPILER_H 14 15 #include "orconfig.h" 16 #include <inttypes.h> 17 18 #if defined(__MINGW32__) || defined(__MINGW64__) 19 #define MINGW_ANY 20 #endif 21 22 #ifdef MINGW_ANY 23 /* We need this for __MINGW_PRINTF_FORMAT, alas. */ 24 #include <stdio.h> 25 #endif 26 27 #if defined(__has_feature) 28 # if __has_feature(address_sanitizer) 29 /* Some of the fancy glibc strcmp() macros include references to memory that 30 * clang rejects because it is off the end of a less-than-3. Clang hates this, 31 * even though those references never actually happen. */ 32 # undef strcmp 33 #endif /* __has_feature(address_sanitizer) */ 34 #endif /* defined(__has_feature) */ 35 36 #ifndef NULL_REP_IS_ZERO_BYTES 37 #error "Your platform does not represent NULL as zero. We can't cope." 38 #endif 39 40 #ifndef DOUBLE_0_REP_IS_ZERO_BYTES 41 #error "Your platform does not represent 0.0 as zeros. We can't cope." 42 #endif 43 44 #if 'a'!=97 || 'z'!=122 || 'A'!=65 || ' '!=32 45 #error "It seems that you encode characters in something other than ASCII." 46 #endif 47 48 /* Use the right magic attribute on mingw, which might be printf, gnu_printf, 49 * or ms_printf, depending on how we're set up to build. 50 */ 51 #ifdef __MINGW_PRINTF_FORMAT 52 #define PRINTF_FORMAT_ATTR __MINGW_PRINTF_FORMAT 53 #else 54 #define PRINTF_FORMAT_ATTR printf 55 #endif 56 #ifdef __MINGW_SCANF_FORMAT 57 #define SCANF_FORMAT_ATTR __MINGW_SCANF_FORMAT 58 #else 59 #define SCANF_FORMAT_ATTR scanf 60 #endif 61 62 /* GCC can check printf and scanf types on arbitrary functions. */ 63 #ifdef __GNUC__ 64 #define CHECK_PRINTF(formatIdx, firstArg) \ 65 __attribute__ ((format(PRINTF_FORMAT_ATTR, formatIdx, firstArg))) 66 #else 67 #define CHECK_PRINTF(formatIdx, firstArg) 68 #endif /* defined(__GNUC__) */ 69 #ifdef __GNUC__ 70 #define CHECK_SCANF(formatIdx, firstArg) \ 71 __attribute__ ((format(SCANF_FORMAT_ATTR, formatIdx, firstArg))) 72 #else 73 #define CHECK_SCANF(formatIdx, firstArg) 74 #endif /* defined(__GNUC__) */ 75 76 #if defined(HAVE_ATTR_FALLTHROUGH) 77 #define FALLTHROUGH __attribute__((fallthrough)) 78 #else 79 #define FALLTHROUGH 80 #endif 81 82 #if defined(HAVE_ATTR_NONSTRING) 83 #define NONSTRING __attribute__((nonstring)) 84 #else 85 #define NONSTRING 86 #endif 87 88 /* What GCC do we have? */ 89 #ifdef __GNUC__ 90 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) 91 #else 92 #define GCC_VERSION 0 93 #endif 94 95 /* Temporarily enable and disable warnings. */ 96 #ifdef __GNUC__ 97 /* Support for macro-generated pragmas (c99) */ 98 # define PRAGMA_(x) _Pragma (#x) 99 # ifdef __clang__ 100 # define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(clang diagnostic x) 101 # else 102 # define PRAGMA_DIAGNOSTIC_(x) PRAGMA_(GCC diagnostic x) 103 # endif 104 # if defined(__clang__) || GCC_VERSION >= 406 105 /* we have push/pop support */ 106 # define DISABLE_GCC_WARNING(warningopt) \ 107 PRAGMA_DIAGNOSTIC_(push) \ 108 PRAGMA_DIAGNOSTIC_(ignored warningopt) 109 # define ENABLE_GCC_WARNING(warningopt) \ 110 PRAGMA_DIAGNOSTIC_(pop) 111 #else /* !(defined(__clang__) || GCC_VERSION >= 406) */ 112 /* older version of gcc: no push/pop support. */ 113 # define DISABLE_GCC_WARNING(warningopt) \ 114 PRAGMA_DIAGNOSTIC_(ignored warningopt) 115 # define ENABLE_GCC_WARNING(warningopt) \ 116 PRAGMA_DIAGNOSTIC_(warning warningopt) 117 #endif /* defined(__clang__) || GCC_VERSION >= 406 */ 118 #else /* !defined(__GNUC__) */ 119 /* not gcc at all */ 120 # define DISABLE_GCC_WARNING(warning) 121 # define ENABLE_GCC_WARNING(warning) 122 #endif /* defined(__GNUC__) */ 123 124 /* inline is __inline on windows. */ 125 #ifdef _WIN32 126 #define inline __inline 127 #endif 128 129 /* Try to get a reasonable __func__ substitute in place. */ 130 #if defined(_MSC_VER) 131 132 #define __func__ __FUNCTION__ 133 134 #else 135 /* For platforms where autoconf works, make sure __func__ is defined 136 * sanely. */ 137 #ifndef HAVE_MACRO__func__ 138 #ifdef HAVE_MACRO__FUNCTION__ 139 #define __func__ __FUNCTION__ 140 #elif HAVE_MACRO__FUNC__ 141 #define __func__ __FUNC__ 142 #else 143 #define __func__ "???" 144 #endif /* defined(HAVE_MACRO__FUNCTION__) || ... */ 145 #endif /* !defined(HAVE_MACRO__func__) */ 146 #endif /* defined(_MSC_VER) */ 147 148 #ifdef ENUM_VALS_ARE_SIGNED 149 #define ENUM_BF(t) unsigned 150 #else 151 /** Wrapper for having a bitfield of an enumerated type. Where possible, we 152 * just use the enumerated type (so the compiler can help us and notice 153 * problems), but if enumerated types are unsigned, we must use unsigned, 154 * so that the loss of precision doesn't make large values negative. */ 155 #define ENUM_BF(t) t 156 #endif /* defined(ENUM_VALS_ARE_SIGNED) */ 157 158 /* GCC has several useful attributes. */ 159 #if defined(__GNUC__) && __GNUC__ >= 3 160 #define ATTR_NORETURN __attribute__((noreturn)) 161 #define ATTR_CONST __attribute__((const)) 162 #define ATTR_MALLOC __attribute__((malloc)) 163 #define ATTR_NORETURN __attribute__((noreturn)) 164 #define ATTR_WUR __attribute__((warn_unused_result)) 165 #define ATTR_UNUSED __attribute__ ((unused)) 166 167 /** Macro: Evaluates to <b>exp</b> and hints the compiler that the value 168 * of <b>exp</b> will probably be true. 169 * 170 * In other words, "if (PREDICT_LIKELY(foo))" is the same as "if (foo)", 171 * except that it tells the compiler that the branch will be taken most of the 172 * time. This can generate slightly better code with some CPUs. 173 */ 174 #define PREDICT_LIKELY(exp) __builtin_expect(!!(exp), 1) 175 /** Macro: Evaluates to <b>exp</b> and hints the compiler that the value 176 * of <b>exp</b> will probably be false. 177 * 178 * In other words, "if (PREDICT_UNLIKELY(foo))" is the same as "if (foo)", 179 * except that it tells the compiler that the branch will usually not be 180 * taken. This can generate slightly better code with some CPUs. 181 */ 182 #define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0) 183 #else /* !(defined(__GNUC__) && __GNUC__ >= 3) */ 184 #define ATTR_NORETURN 185 #define ATTR_CONST 186 #define ATTR_MALLOC 187 #define ATTR_NORETURN 188 #define ATTR_UNUSED 189 #define ATTR_WUR 190 #define PREDICT_LIKELY(exp) (exp) 191 #define PREDICT_UNLIKELY(exp) (exp) 192 #endif /* defined(__GNUC__) && __GNUC__ >= 3 */ 193 194 /** Expands to a syntactically valid empty statement. */ 195 #define STMT_NIL (void)0 196 197 /** Expands to a syntactically valid empty statement, explicitly (void)ing its 198 * argument. */ 199 #define STMT_VOID(a) while (0) { (void)(a); } 200 201 #ifdef __GNUC__ 202 /** STMT_BEGIN and STMT_END are used to wrap blocks inside macros so that 203 * the macro can be used as if it were a single C statement. */ 204 #define STMT_BEGIN (void) ({ 205 #define STMT_END }) 206 #elif defined(sun) || defined(__sun__) 207 #define STMT_BEGIN if (1) { 208 #define STMT_END } else STMT_NIL 209 #else 210 #define STMT_BEGIN do { 211 #define STMT_END } while (0) 212 #endif /* defined(__GNUC__) || ... */ 213 214 /* Some tools (like coccinelle) don't like to see operators as macro 215 * arguments. */ 216 #define OP_LT < 217 #define OP_GT > 218 #define OP_GE >= 219 #define OP_LE <= 220 #define OP_EQ == 221 #define OP_NE != 222 223 /** Macro: yield a pointer to the field at position <b>off</b> within the 224 * structure <b>st</b>. Example: 225 * <pre> 226 * struct a_t { int foo; int bar; } x; 227 * ptrdiff_t bar_offset = offsetof(struct a_t, bar); 228 * int *bar_p = STRUCT_VAR_P(&x, bar_offset); 229 * *bar_p = 3; 230 * </pre> 231 */ 232 #define STRUCT_VAR_P(st, off) ((void*) ( ((char*)(st)) + (off) ) ) 233 234 /** Macro: yield a pointer to an enclosing structure given a pointer to 235 * a substructure at offset <b>off</b>. Example: 236 * <pre> 237 * struct base_t { ... }; 238 * struct subtype_t { int x; struct base_t b; } x; 239 * struct base_t *bp = &x.base; 240 * struct *sp = SUBTYPE_P(bp, struct subtype_t, b); 241 * </pre> 242 */ 243 #define SUBTYPE_P(p, subtype, basemember) \ 244 ((void*) ( ((char*)(p)) - offsetof(subtype, basemember) )) 245 246 /** Macro: Yields the number of elements in array x. */ 247 #define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0])) 248 249 /** 250 * "Eat" a semicolon that somebody puts at the end of a top-level macro. 251 * 252 * Frequently, we want to declare a macro that people will use at file scope, 253 * and we want to allow people to put a semicolon after the macro. 254 * 255 * This declaration of a struct can be repeated any number of times, and takes 256 * a trailing semicolon afterwards. 257 **/ 258 #define EAT_SEMICOLON \ 259 struct dummy_semicolon_eater__ 260 261 /** 262 * Tell our static analysis tool to believe that (clang's scan-build or 263 * coverity scan) that an expression might be true. We use this to suppress 264 * dead-code warnings. 265 **/ 266 #if defined(__COVERITY__) || defined(__clang_analyzer__) 267 /* By calling getenv, we force the analyzer not to conclude that 'expr' is 268 * false. */ 269 #define POSSIBLE(expr) ((expr) || getenv("STATIC_ANALYZER_DEADCODE_DUMMY_")) 270 #else 271 #define POSSIBLE(expr) (expr) 272 #endif /* defined(__COVERITY__) || defined(__clang_analyzer__) */ 273 274 #endif /* !defined(TOR_COMPAT_COMPILER_H) */