1 /* compiler.h 2 * Copyright (C) 2007-2015, Parrot Foundation. 3 * Overview: 4 * defines compiler capabilities and attributes 5 */ 6 7 #ifndef PARROT_COMPILER_H_GUARD 8 #define PARROT_COMPILER_H_GUARD 9 10 /* darwin clang! */ 11 #ifndef __WORDSIZE 12 # define __WORDSIZE (sizeof(void*) * 8) 13 #endif 14 15 /* 16 * This set of macros define capabilities that may or may not be available 17 * for a given compiler. They are based on GCC's and CLANG's __attribute__ functionality. 18 */ 19 20 #ifdef HASATTRIBUTE_NEVER_WORKS 21 # error This attribute can never succeed. Something has mis-sniffed your configuration. 22 #endif 23 #ifdef HASATTRIBUTE_DEPRECATED 24 # ifdef _MSC_VER 25 # define __attribute__deprecated__ __declspec(deprecated) 26 # else 27 # define __attribute__deprecated__ __attribute__((__deprecated__)) 28 # endif 29 #else 30 # define __attribute__deprecated__ 31 #endif 32 #if defined(HASATTRIBUTE_FORMAT_GNU_PRINTF) 33 # define __attribute__format__(y, z) __attribute__ ((format (gnu_printf, (y), (z)))) 34 #elif defined(HASATTRIBUTE_FORMAT_MS_PRINTF) 35 # define __attribute__format__(y, z) __attribute__ ((format (ms_printf, (y), (z)))) 36 #elif defined(HASATTRIBUTE_FORMAT_PRINTF) 37 # define __attribute__format__(y, z) __attribute__ ((format (printf, (y), (z)))) 38 #else 39 # define __attribute__format__(y, z) 40 #endif 41 #ifdef HASATTRIBUTE_MALLOC 42 # define __attribute__malloc__ __attribute__((__malloc__)) 43 #else 44 # define __attribute__malloc__ 45 #endif 46 #if defined(HASATTRIBUTE_NONNULL) && !defined(__cplusplus) 47 /* g++ has some problem with this attribute */ 48 # define __attribute__nonnull__(a) __attribute__((__nonnull__(a))) 49 #else 50 # define __attribute__nonnull__(a) 51 #endif 52 #ifdef HASATTRIBUTE_NORETURN 53 # ifdef _MSC_VER 54 # define __attribute__noreturn__ __declspec(noreturn) 55 # else 56 # define __attribute__noreturn__ __attribute__((__noreturn__)) 57 # endif 58 #else 59 # define __attribute__noreturn__ 60 #endif 61 #ifdef HASATTRIBUTE_PURE 62 # define __attribute__pure__ __attribute__((__pure__)) 63 #else 64 # define __attribute__pure__ 65 #endif 66 #ifdef HASATTRIBUTE_CONST 67 # define __attribute__const__ __attribute__((__const__)) 68 #else 69 # define __attribute__const__ 70 #endif 71 #ifdef HASATTRIBUTE_UNUSED 72 # define __attribute__unused__ __attribute__((__unused__)) 73 #else 74 # define __attribute__unused__ 75 #endif 76 #ifdef HASATTRIBUTE_WARN_UNUSED_RESULT 77 # define __attribute__warn_unused_result__ __attribute__((__warn_unused_result__)) 78 #elif defined(_MSC_VER) && _MSC_VER > 1600 && defined(PARROT_HAS_HEADER_SAL) 79 # define __attribute__warn_unused_result__ _Check_return_ 80 #else 81 # define __attribute__warn_unused_result__ 82 #endif 83 #ifdef HASATTRIBUTE_HOT 84 # define __attribute__hot__ __attribute__((__hot__)) 85 #else 86 # define __attribute__hot__ 87 #endif 88 #ifdef HASATTRIBUTE_COLD 89 # define __attribute__cold__ __attribute__((__cold__)) 90 #else 91 # define __attribute__cold__ 92 #endif 93 #ifdef HASATTRIBUTE_RETURNS_NONNULL 94 # define __attribute__returns_nonnull__ __attribute__((returns_nonnull)) 95 #else 96 # define __attribute__returns_nonnull__ 97 #endif 98 99 /* Shim arguments are arguments that must be included in your function, 100 * but serve no purpose inside. Mark them with the SHIM() macro so that 101 * the compiler and/or lint know that it's OK it's unused. Shim arguments 102 * get "_unused" added to them so that you can't accidentally use them 103 * without removing the shim designation. 104 */ 105 #define SHIM(a) /*@unused@*/ a ##_unused __attribute__unused__ 106 107 /* UNUSED() is the old way we handled shim arguments Should still be 108 used in cases where the argument should, at some point be used. 109 */ 110 #ifdef __clang__ 111 # define UNUSED(a) (void)(a); 112 #else 113 # define UNUSED(a) /*@-noeffect*/if (0) (void)(a)/*@=noeffect*/; 114 #endif 115 116 #ifdef PARROT_HAS_HEADER_SAL 117 /* 118 * Microsoft provides two annotations mechanisms. __declspec, which has been 119 * around for a while, and Microsoft's standard source code annotation 120 * language (SAL), introduced with Visual C++ 8.0. 121 * See <http://msdn.microsoft.com/en-us/library/ms182032.aspx>, 122 * <http://msdn2.microsoft.com/en-us/library/ms235402(VS.80).aspx>, 123 * <http://msdn2.microsoft.com/en-us/library/dabb5z75(VS.80).aspx>. 124 */ 125 # include <sal.h> 126 /* TODO: New syntax: _Ret_maybenull_ http://msdn.microsoft.com/en-us/library/jj159525.aspx */ 127 # define PARROT_CAN_RETURN_NULL /*@null@*/ __maybenull 128 # define PARROT_CANNOT_RETURN_NULL /*@notnull@*/ __notnull 129 #else 130 # define PARROT_CAN_RETURN_NULL /*@null@*/ 131 # define PARROT_CANNOT_RETURN_NULL /*@notnull@*/ __attribute__returns_nonnull__ 132 #endif /* PARROT_HAS_HEADER_SAL */ 133 134 #define PARROT_DEPRECATED __attribute__deprecated__ 135 136 #define PARROT_IGNORABLE_RESULT 137 #define PARROT_WARN_UNUSED_RESULT __attribute__warn_unused_result__ 138 139 #define PARROT_PURE_FUNCTION __attribute__pure__ __attribute__warn_unused_result__ 140 /* Pure functions have no side-effects, and depend only on parms or globals. e.g. strlen() */ 141 /* "Many functions have no effects except the return value and their 142 return value depends only on the parameters and/or global 143 variables. Such a function can be subject to common subexpression 144 elimination and loop optimization just as an arithmetic operator 145 would be. For example, "PARROT_PURE_FUNCTION int square(int x)" 146 says that the hypothetical function square is safe to call fewer 147 times than the program says. 148 149 Some of common examples of pure functions are strlen or 150 memcmp. Interesting non-pure functions are functions with infinite 151 loops or those depending on volatile memory or other system resource, 152 that may change between two consecutive calls (such as feof in a 153 multithreading environment)." -- http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 154 */ 155 156 #define PARROT_CONST_FUNCTION __attribute__const__ __attribute__warn_unused_result__ 157 /* Const functions are pure functions, and also do not examine targets of 158 pointer args or globals. e.g. sqrt() */ 159 /* "Many functions do not examine any values except their arguments, 160 and have no effects except the return value. Basically this is just 161 slightly more strict class than the pure attribute below, since 162 function is not allowed to read global memory. Note that a function 163 that has pointer arguments and examines the data pointed to must 164 not be declared const. Likewise, a function that calls a non-const 165 function usually must not be const. It does not make sense for a 166 const function to return void." 167 -- http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html 168 */ 169 170 #define PARROT_DOES_NOT_RETURN /*@noreturn@*/ __attribute__noreturn__ 171 #define PARROT_DOES_NOT_RETURN_WHEN_FALSE /*@noreturnwhenfalse@*/ 172 #define PARROT_MALLOC /*@only@*/ __attribute__malloc__ \ 173 __attribute__warn_unused_result__ 174 175 /* Hot functions can be optimized by the compiler. */ 176 #define PARROT_HOT __attribute__hot__ 177 #define PARROT_COLD __attribute__cold__ 178 179 /* Macros for exposure tracking for splint. */ 180 /* See http://www.splint.org/manual/html/all.html section 6.2 */ 181 #define PARROT_OBSERVER /*@observer@*/ 182 #define PARROT_EXPOSED /*@exposed@*/ 183 184 /* Function argument instrumentation */ 185 /* For explanations of the annotations, see http://www.splint.org/manual/manual.html */ 186 187 #ifdef PARROT_HAS_HEADER_SAL 188 # define NOTNULL(x) /*@notnull@*/ __notnull x 189 /* The pointer passed may not be NULL */ 190 191 # define NULLOK(x) /*@null@*/ __maybenull x 192 /* The pointer passed may be NULL */ 193 194 # define ARGIN(x) /*@in@*/ /*@notnull@*/ __in x 195 # define ARGIN_FORMAT(x) /*@in@*/ /*@notnull@*/ __in x 196 # define ARGIN_NULLOK(x) /*@in@*/ /*@null@*/ __in_opt x 197 /* The pointer target must be completely defined before being passed */ 198 /* to the function. */ 199 200 # define ARGOUT(x) /*@out@*/ /*@notnull@*/ __out x 201 # define ARGOUT_NULLOK(x) /*@out@*/ /*@null@*/ __out_opt x 202 /* The pointer target will be defined by the function */ 203 204 # define ARGMOD(x) /*@in@*/ /*@notnull@*/ __inout x 205 # define ARGMOD_NULLOK(x) /*@in@*/ /*@null@*/ __inout_opt x 206 /* The pointer target must be completely defined before being passed, */ 207 /* and MAY be modified by the function. */ 208 209 # define FUNC_MODIFIES(x) /*@modifies x@*/ 210 /* Never applied by a human, only by the headerizer. */ 211 212 #else 213 214 # define NOTNULL(x) /*@notnull@*/ x 215 /* The pointer passed may not be NULL */ 216 217 # define NULLOK(x) /*@null@*/ x 218 /* The pointer passed may be NULL */ 219 220 # define ARGIN(x) /*@in@*/ /*@notnull@*/ x 221 # define ARGIN_FORMAT(x) /*@in@*/ /*@notnull@*/ x 222 # define ARGIN_NULLOK(x) /*@in@*/ /*@null@*/ x 223 /* The pointer target must be completely defined before being passed */ 224 /* to the function. */ 225 226 # define ARGOUT(x) /*@out@*/ /*@notnull@*/ x 227 # define ARGOUT_NULLOK(x) /*@out@*/ /*@null@*/ x 228 /* The pointer target will be defined by the function */ 229 230 # define ARGMOD(x) /*@in@*/ /*@notnull@*/ x 231 # define ARGMOD_NULLOK(x) /*@in@*/ /*@null@*/ x 232 /* The pointer target must be completely defined before being passed, */ 233 /* and MAY be modified by the function. */ 234 235 # define FUNC_MODIFIES(x) /*@modifies x@*/ 236 /* Never applied by a human, only by the headerizer. */ 237 238 #endif 239 240 #define ARGFREE(x) /*@only@*/ /*@out@*/ /*@null@*/ x 241 /* From the Splint manual: The parameter to free() must reference */ 242 /* an unshared object. Since the parameter is declared using "only", */ 243 /* the caller may not use the referenced object after the call, and */ 244 /* may not pass in a reference to a shared object. There is nothing */ 245 /* special about malloc and free -- their behavior can be described */ 246 /* entirely in terms of the provided annotations. */ 247 #define ARGFREE_NOTNULL(x) /*@only@*/ /*@out@*/ /*@notnull@*/ x 248 249 #define PARROT_NO_ADDRESS_SAFETY_ANALYSIS 250 /* We violate ASAN in Parrot_x_execute_on_exit_handlers() and trace_mem_block() */ 251 #if defined(__clang__) && defined(__has_feature) 252 # if __has_feature(address_sanitizer) 253 # undef PARROT_NO_ADDRESS_SAFETY_ANALYSIS 254 # define PARROT_NO_ADDRESS_SAFETY_ANALYSIS __attribute__((no_address_safety_analysis)) 255 # endif 256 #endif 257 258 #endif /* PARROT_COMPILER_H_GUARD */ 259 260 /* 261 * Local variables: 262 * c-file-style: "parrot" 263 * End: 264 * vim: expandtab shiftwidth=4 cinoptions='\:2=2' : 265 */ 266