File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / libiconv / srclib / warn-on-use.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 13:38:46 2021 UTC (3 years, 3 months ago) by misho
Branches: libiconv, MAIN
CVS tags: v1_16p0, HEAD
libiconv 1.16

    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>