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