(root)/
make-4.4/
lib/
warn-on-use.h
       1  /* A C macro for emitting warnings if a function is used.
       2     Copyright (C) 2010-2022 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 Lesser General Public License as published
       6     by the Free Software Foundation; either version 2 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     Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser 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  _GL_WARN_EXTERN_C __typeof__ (function) function __attribute__ ((__warning__ (message)))
      88  #  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
      89    __attribute__ ((__warning__ (message)))
      90  # elif __clang_major__ >= 4
      91  /* Another compiler attribute is available in clang.  */
      92  #  define _GL_WARN_ON_USE(function, message) \
      93  _GL_WARN_EXTERN_C __typeof__ (function) function \
      94    __attribute__ ((__diagnose_if__ (1, message, "warning")))
      95  #  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
      96    __attribute__ ((__diagnose_if__ (1, message, "warning")))
      97  # elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
      98  /* Verify the existence of the function.  */
      99  #  define _GL_WARN_ON_USE(function, message) \
     100  _GL_WARN_EXTERN_C __typeof__ (function) function
     101  #  define _GL_WARN_ON_USE_ATTRIBUTE(message)
     102  # else /* Unsupported.  */
     103  #  define _GL_WARN_ON_USE(function, message) \
     104  _GL_WARN_EXTERN_C int _gl_warn_on_use
     105  #  define _GL_WARN_ON_USE_ATTRIBUTE(message)
     106  # endif
     107  #endif
     108  
     109  /* _GL_WARN_ON_USE_CXX (function, rettype_gcc, rettype_clang, parameters_and_attributes, "message")
     110     is like _GL_WARN_ON_USE (function, "message"), except that in C++ mode the
     111     function is declared with the given prototype, consisting of return type,
     112     parameters, and attributes.
     113     This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
     114     not work in this case.  */
     115  #ifndef _GL_WARN_ON_USE_CXX
     116  # if !defined __cplusplus
     117  #  define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
     118       _GL_WARN_ON_USE (function, msg)
     119  # else
     120  #  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
     121  /* A compiler attribute is available in gcc versions 4.3.0 and later.  */
     122  #   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
     123  extern rettype_gcc function parameters_and_attributes \
     124    __attribute__ ((__warning__ (msg)))
     125  #  elif __clang_major__ >= 4
     126  /* Another compiler attribute is available in clang.  */
     127  #   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
     128  extern rettype_clang function parameters_and_attributes \
     129    __attribute__ ((__diagnose_if__ (1, msg, "warning")))
     130  #  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
     131  /* Verify the existence of the function.  */
     132  #   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
     133  extern rettype_gcc function parameters_and_attributes
     134  #  else /* Unsupported.  */
     135  #   define _GL_WARN_ON_USE_CXX(function,rettype_gcc,rettype_clang,parameters_and_attributes,msg) \
     136  _GL_WARN_EXTERN_C int _gl_warn_on_use
     137  #  endif
     138  # endif
     139  #endif
     140  
     141  /* _GL_WARN_EXTERN_C declaration;
     142     performs the declaration with C linkage.  */
     143  #ifndef _GL_WARN_EXTERN_C
     144  # if defined __cplusplus
     145  #  define _GL_WARN_EXTERN_C extern "C"
     146  # else
     147  #  define _GL_WARN_EXTERN_C extern
     148  # endif
     149  #endif