Annotation of embedaddon/libiconv/srclib/warn-on-use.h, revision 1.1.1.1

1.1       misho       1: /* A C macro for emitting warnings if a function is used.
                      2:    Copyright (C) 2010-2019 Free Software Foundation, Inc.
                      3: 
                      4:    This program is free software: you can redistribute it and/or modify it
                      5:    under the terms of the GNU General Public License as published
                      6:    by the Free Software Foundation; either version 3 of the License, or
                      7:    (at your option) any later version.
                      8: 
                      9:    This program is distributed in the hope that it will be useful,
                     10:    but WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:    General Public License for more details.
                     13: 
                     14:    You should have received a copy of the GNU General Public License
                     15:    along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
                     16: 
                     17: /* _GL_WARN_ON_USE (function, "literal string") issues a declaration
                     18:    for FUNCTION which will then trigger a compiler warning containing
                     19:    the text of "literal string" anywhere that function is called, if
                     20:    supported by the compiler.  If the compiler does not support this
                     21:    feature, the macro expands to an unused extern declaration.
                     22: 
                     23:    _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
                     24:    attribute used in _GL_WARN_ON_USE.  If the compiler does not support
                     25:    this feature, it expands to empty.
                     26: 
                     27:    These macros are useful for marking a function as a potential
                     28:    portability trap, with the intent that "literal string" include
                     29:    instructions on the replacement function that should be used
                     30:    instead.
                     31:    _GL_WARN_ON_USE is for functions with 'extern' linkage.
                     32:    _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
                     33:    linkage.
                     34: 
                     35:    However, one of the reasons that a function is a portability trap is
                     36:    if it has the wrong signature.  Declaring FUNCTION with a different
                     37:    signature in C is a compilation error, so this macro must use the
                     38:    same type as any existing declaration so that programs that avoid
                     39:    the problematic FUNCTION do not fail to compile merely because they
                     40:    included a header that poisoned the function.  But this implies that
                     41:    _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
                     42:    have a declaration.  Use of this macro implies that there must not
                     43:    be any other macro hiding the declaration of FUNCTION; but
                     44:    undefining FUNCTION first is part of the poisoning process anyway
                     45:    (although for symbols that are provided only via a macro, the result
                     46:    is a compilation error rather than a warning containing
                     47:    "literal string").  Also note that in C++, it is only safe to use if
                     48:    FUNCTION has no overloads.
                     49: 
                     50:    For an example, it is possible to poison 'getline' by:
                     51:    - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
                     52:      [getline]) in configure.ac, which potentially defines
                     53:      HAVE_RAW_DECL_GETLINE
                     54:    - adding this code to a header that wraps the system <stdio.h>:
                     55:      #undef getline
                     56:      #if HAVE_RAW_DECL_GETLINE
                     57:      _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
                     58:        "not universally present; use the gnulib module getline");
                     59:      #endif
                     60: 
                     61:    It is not possible to directly poison global variables.  But it is
                     62:    possible to write a wrapper accessor function, and poison that
                     63:    (less common usage, like &environ, will cause a compilation error
                     64:    rather than issue the nice warning, but the end result of informing
                     65:    the developer about their portability problem is still achieved):
                     66:      #if HAVE_RAW_DECL_ENVIRON
                     67:      static char ***
                     68:      rpl_environ (void) { return &environ; }
                     69:      _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
                     70:      # undef environ
                     71:      # define environ (*rpl_environ ())
                     72:      #endif
                     73:    or better (avoiding contradictory use of 'static' and 'extern'):
                     74:      #if HAVE_RAW_DECL_ENVIRON
                     75:      static char ***
                     76:      _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
                     77:      rpl_environ (void) { return &environ; }
                     78:      # undef environ
                     79:      # define environ (*rpl_environ ())
                     80:      #endif
                     81:    */
                     82: #ifndef _GL_WARN_ON_USE
                     83: 
                     84: # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
                     85: /* A compiler attribute is available in gcc versions 4.3.0 and later.  */
                     86: #  define _GL_WARN_ON_USE(function, message) \
                     87: extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
                     88: #  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
                     89:   __attribute__ ((__warning__ (message)))
                     90: # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
                     91: /* Verify the existence of the function.  */
                     92: #  define _GL_WARN_ON_USE(function, message) \
                     93: extern __typeof__ (function) function
                     94: #  define _GL_WARN_ON_USE_ATTRIBUTE(message)
                     95: # else /* Unsupported.  */
                     96: #  define _GL_WARN_ON_USE(function, message) \
                     97: _GL_WARN_EXTERN_C int _gl_warn_on_use
                     98: #  define _GL_WARN_ON_USE_ATTRIBUTE(message)
                     99: # endif
                    100: #endif
                    101: 
                    102: /* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
                    103:    is like _GL_WARN_ON_USE (function, "string"), except that the function is
                    104:    declared with the given prototype, consisting of return type, parameters,
                    105:    and attributes.
                    106:    This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
                    107:    not work in this case.  */
                    108: #ifndef _GL_WARN_ON_USE_CXX
                    109: # if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
                    110: #  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
                    111: extern rettype function parameters_and_attributes \
                    112:      __attribute__ ((__warning__ (msg)))
                    113: # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
                    114: /* Verify the existence of the function.  */
                    115: #  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
                    116: extern rettype function parameters_and_attributes
                    117: # else /* Unsupported.  */
                    118: #  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
                    119: _GL_WARN_EXTERN_C int _gl_warn_on_use
                    120: # endif
                    121: #endif
                    122: 
                    123: /* _GL_WARN_EXTERN_C declaration;
                    124:    performs the declaration with C linkage.  */
                    125: #ifndef _GL_WARN_EXTERN_C
                    126: # if defined __cplusplus
                    127: #  define _GL_WARN_EXTERN_C extern "C"
                    128: # else
                    129: #  define _GL_WARN_EXTERN_C extern
                    130: # endif
                    131: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>