1*05b00f60SXin Li /* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */ 2*05b00f60SXin Li /* 3*05b00f60SXin Li * Copyright (c) 1993, 1994, 1995, 1996, 1997 4*05b00f60SXin Li * The Regents of the University of California. All rights reserved. 5*05b00f60SXin Li * 6*05b00f60SXin Li * Redistribution and use in source and binary forms, with or without 7*05b00f60SXin Li * modification, are permitted provided that the following conditions 8*05b00f60SXin Li * are met: 9*05b00f60SXin Li * 1. Redistributions of source code must retain the above copyright 10*05b00f60SXin Li * notice, this list of conditions and the following disclaimer. 11*05b00f60SXin Li * 2. Redistributions in binary form must reproduce the above copyright 12*05b00f60SXin Li * notice, this list of conditions and the following disclaimer in the 13*05b00f60SXin Li * documentation and/or other materials provided with the distribution. 14*05b00f60SXin Li * 3. All advertising materials mentioning features or use of this software 15*05b00f60SXin Li * must display the following acknowledgement: 16*05b00f60SXin Li * This product includes software developed by the Computer Systems 17*05b00f60SXin Li * Engineering Group at Lawrence Berkeley Laboratory. 18*05b00f60SXin Li * 4. Neither the name of the University nor of the Laboratory may be used 19*05b00f60SXin Li * to endorse or promote products derived from this software without 20*05b00f60SXin Li * specific prior written permission. 21*05b00f60SXin Li * 22*05b00f60SXin Li * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23*05b00f60SXin Li * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24*05b00f60SXin Li * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25*05b00f60SXin Li * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26*05b00f60SXin Li * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27*05b00f60SXin Li * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28*05b00f60SXin Li * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29*05b00f60SXin Li * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30*05b00f60SXin Li * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31*05b00f60SXin Li * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32*05b00f60SXin Li * SUCH DAMAGE. 33*05b00f60SXin Li */ 34*05b00f60SXin Li 35*05b00f60SXin Li #ifndef lib_funcattrs_h 36*05b00f60SXin Li #define lib_funcattrs_h 37*05b00f60SXin Li 38*05b00f60SXin Li #include "compiler-tests.h" 39*05b00f60SXin Li 40*05b00f60SXin Li /* 41*05b00f60SXin Li * Attributes to apply to functions and their arguments, using various 42*05b00f60SXin Li * compiler-specific extensions. 43*05b00f60SXin Li */ 44*05b00f60SXin Li 45*05b00f60SXin Li /* 46*05b00f60SXin Li * NORETURN, before a function declaration, means "this function 47*05b00f60SXin Li * never returns". (It must go before the function declaration, e.g. 48*05b00f60SXin Li * "extern NORETURN func(...)" rather than after the function 49*05b00f60SXin Li * declaration, as the MSVC version has to go before the declaration.) 50*05b00f60SXin Li */ 51*05b00f60SXin Li #if __has_attribute(noreturn) \ 52*05b00f60SXin Li || ND_IS_AT_LEAST_GNUC_VERSION(2,5) \ 53*05b00f60SXin Li || ND_IS_AT_LEAST_SUNC_VERSION(5,9) \ 54*05b00f60SXin Li || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \ 55*05b00f60SXin Li || ND_IS_AT_LEAST_HP_C_VERSION(6,10) 56*05b00f60SXin Li /* 57*05b00f60SXin Li * Compiler with support for __attribute((noreturn)), or GCC 2.5 and 58*05b00f60SXin Li * later, or some compiler asserting compatibility with GCC 2.5 and 59*05b00f60SXin Li * later, or Solaris Studio 12 (Sun C 5.9) and later, or IBM XL C 10.1 60*05b00f60SXin Li * and later (do any earlier versions of XL C support this?), or HP aCC 61*05b00f60SXin Li * A.06.10 and later. 62*05b00f60SXin Li */ 63*05b00f60SXin Li #define NORETURN __attribute((noreturn)) 64*05b00f60SXin Li 65*05b00f60SXin Li /* 66*05b00f60SXin Li * However, GCC didn't support that for function *pointers* until GCC 67*05b00f60SXin Li * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481. 68*05b00f60SXin Li * 69*05b00f60SXin Li * Sun C/Oracle Studio C doesn't seem to support it, either. 70*05b00f60SXin Li */ 71*05b00f60SXin Li #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 401)) \ 72*05b00f60SXin Li || (defined(__SUNPRO_C)) 73*05b00f60SXin Li #define NORETURN_FUNCPTR 74*05b00f60SXin Li #else 75*05b00f60SXin Li #define NORETURN_FUNCPTR __attribute((noreturn)) 76*05b00f60SXin Li #endif 77*05b00f60SXin Li #elif defined(_MSC_VER) 78*05b00f60SXin Li /* 79*05b00f60SXin Li * MSVC. 80*05b00f60SXin Li * It doesn't allow __declspec(noreturn) to be applied to function 81*05b00f60SXin Li * pointers. 82*05b00f60SXin Li */ 83*05b00f60SXin Li #define NORETURN __declspec(noreturn) 84*05b00f60SXin Li #define NORETURN_FUNCPTR 85*05b00f60SXin Li #else 86*05b00f60SXin Li #define NORETURN 87*05b00f60SXin Li #define NORETURN_FUNCPTR 88*05b00f60SXin Li #endif 89*05b00f60SXin Li 90*05b00f60SXin Li /* 91*05b00f60SXin Li * WARN_UNUSED_RESULT, before a function declaration, means "the caller 92*05b00f60SXin Li * should use the result of this function" (even if it's just a success/ 93*05b00f60SXin Li * failure indication). 94*05b00f60SXin Li */ 95*05b00f60SXin Li #if __has_attribute(warn_unused_result) \ 96*05b00f60SXin Li || ND_IS_AT_LEAST_GNUC_VERSION(3,4) \ 97*05b00f60SXin Li || ND_IS_AT_LEAST_HP_C_VERSION(6,25) 98*05b00f60SXin Li #define WARN_UNUSED_RESULT __attribute((warn_unused_result)) 99*05b00f60SXin Li #else 100*05b00f60SXin Li #define WARN_UNUSED_RESULT 101*05b00f60SXin Li #endif 102*05b00f60SXin Li 103*05b00f60SXin Li /* 104*05b00f60SXin Li * PRINTFLIKE(x,y), after a function declaration, means "this function 105*05b00f60SXin Li * does printf-style formatting, with the xth argument being the format 106*05b00f60SXin Li * string and the yth argument being the first argument for the format 107*05b00f60SXin Li * string". 108*05b00f60SXin Li */ 109*05b00f60SXin Li #if __has_attribute(__format__) \ 110*05b00f60SXin Li || ND_IS_AT_LEAST_GNUC_VERSION(2,3) \ 111*05b00f60SXin Li || ND_IS_AT_LEAST_XL_C_VERSION(10,1) \ 112*05b00f60SXin Li || ND_IS_AT_LEAST_HP_C_VERSION(6,10) 113*05b00f60SXin Li /* 114*05b00f60SXin Li * Compiler with support for it, or GCC 2.3 and later, or some compiler 115*05b00f60SXin Li * asserting compatibility with GCC 2.3 and later, or IBM XL C 10.1 116*05b00f60SXin Li * and later (do any earlier versions of XL C support this?), 117*05b00f60SXin Li * or HP aCC A.06.10 and later. 118*05b00f60SXin Li */ 119*05b00f60SXin Li #define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y))) 120*05b00f60SXin Li 121*05b00f60SXin Li /* 122*05b00f60SXin Li * However, GCC didn't support that for function *pointers* until GCC 123*05b00f60SXin Li * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481. 124*05b00f60SXin Li * XL C 16.1 (and possibly some earlier versions, but not 12.1 or 13.1) has 125*05b00f60SXin Li * a similar bug, the bugfix for which was made in: 126*05b00f60SXin Li * * version 16.1.1.8 for Linux (25 June 2020), which fixes 127*05b00f60SXin Li * https://www.ibm.com/support/pages/apar/LI81402 128*05b00f60SXin Li * * version 16.1.0.5 for AIX (5 May 2020), which fixes 129*05b00f60SXin Li * https://www.ibm.com/support/pages/apar/IJ24678 130*05b00f60SXin Li * 131*05b00f60SXin Li * When testing versions, keep in mind that XL C 16.1 pretends to be both 132*05b00f60SXin Li * GCC 4.2 and Clang 4.0 at once. 133*05b00f60SXin Li */ 134*05b00f60SXin Li #if (ND_IS_AT_LEAST_GNUC_VERSION(4,1) \ 135*05b00f60SXin Li && !ND_IS_AT_LEAST_XL_C_VERSION(10,1)) \ 136*05b00f60SXin Li || (ND_IS_AT_LEAST_XL_C_VERSION(16,1) \ 137*05b00f60SXin Li && (ND_IS_AT_LEAST_XL_C_MODFIX(1, 8) && defined(__linux__)) \ 138*05b00f60SXin Li || (ND_IS_AT_LEAST_XL_C_MODFIX(0, 5) && defined(_AIX))) 139*05b00f60SXin Li #define PRINTFLIKE_FUNCPTR(x,y) __attribute__((__format__(__printf__,x,y))) 140*05b00f60SXin Li #endif 141*05b00f60SXin Li #endif 142*05b00f60SXin Li 143*05b00f60SXin Li #if !defined(PRINTFLIKE) 144*05b00f60SXin Li #define PRINTFLIKE(x,y) 145*05b00f60SXin Li #endif 146*05b00f60SXin Li #if !defined(PRINTFLIKE_FUNCPTR) 147*05b00f60SXin Li #define PRINTFLIKE_FUNCPTR(x,y) 148*05b00f60SXin Li #endif 149*05b00f60SXin Li 150*05b00f60SXin Li /* 151*05b00f60SXin Li * For flagging arguments as format strings in MSVC. 152*05b00f60SXin Li */ 153*05b00f60SXin Li #ifdef _MSC_VER 154*05b00f60SXin Li #include <sal.h> 155*05b00f60SXin Li #define FORMAT_STRING(p) _Printf_format_string_ p 156*05b00f60SXin Li #else 157*05b00f60SXin Li #define FORMAT_STRING(p) p 158*05b00f60SXin Li #endif 159*05b00f60SXin Li 160*05b00f60SXin Li #endif /* lib_funcattrs_h */ 161