Blame gl/warn-on-use.h

Packit Service 4684c1
/* A C macro for emitting warnings if a function is used.
Packit Service 4684c1
   Copyright (C) 2010-2020 Free Software Foundation, Inc.
Packit Service 4684c1
Packit Service 4684c1
   This program is free software: you can redistribute it and/or modify it
Packit Service 4684c1
   under the terms of the GNU Lesser General Public License as published
Packit Service 4684c1
   by the Free Software Foundation; either version 2.1 of the License, or
Packit Service 4684c1
   (at your option) any later version.
Packit Service 4684c1
Packit Service 4684c1
   This program is distributed in the hope that it will be useful,
Packit Service 4684c1
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 4684c1
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 4684c1
   Lesser General Public License for more details.
Packit Service 4684c1
Packit Service 4684c1
   You should have received a copy of the GNU Lesser General Public License
Packit Service 4684c1
   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
Packit Service 4684c1
Packit Service 4684c1
/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
Packit Service 4684c1
   for FUNCTION which will then trigger a compiler warning containing
Packit Service 4684c1
   the text of "literal string" anywhere that function is called, if
Packit Service 4684c1
   supported by the compiler.  If the compiler does not support this
Packit Service 4684c1
   feature, the macro expands to an unused extern declaration.
Packit Service 4684c1
Packit Service 4684c1
   _GL_WARN_ON_USE_ATTRIBUTE ("literal string") expands to the
Packit Service 4684c1
   attribute used in _GL_WARN_ON_USE.  If the compiler does not support
Packit Service 4684c1
   this feature, it expands to empty.
Packit Service 4684c1
Packit Service 4684c1
   These macros are useful for marking a function as a potential
Packit Service 4684c1
   portability trap, with the intent that "literal string" include
Packit Service 4684c1
   instructions on the replacement function that should be used
Packit Service 4684c1
   instead.
Packit Service 4684c1
   _GL_WARN_ON_USE is for functions with 'extern' linkage.
Packit Service 4684c1
   _GL_WARN_ON_USE_ATTRIBUTE is for functions with 'static' or 'inline'
Packit Service 4684c1
   linkage.
Packit Service 4684c1
Packit Service 4684c1
   However, one of the reasons that a function is a portability trap is
Packit Service 4684c1
   if it has the wrong signature.  Declaring FUNCTION with a different
Packit Service 4684c1
   signature in C is a compilation error, so this macro must use the
Packit Service 4684c1
   same type as any existing declaration so that programs that avoid
Packit Service 4684c1
   the problematic FUNCTION do not fail to compile merely because they
Packit Service 4684c1
   included a header that poisoned the function.  But this implies that
Packit Service 4684c1
   _GL_WARN_ON_USE is only safe to use if FUNCTION is known to already
Packit Service 4684c1
   have a declaration.  Use of this macro implies that there must not
Packit Service 4684c1
   be any other macro hiding the declaration of FUNCTION; but
Packit Service 4684c1
   undefining FUNCTION first is part of the poisoning process anyway
Packit Service 4684c1
   (although for symbols that are provided only via a macro, the result
Packit Service 4684c1
   is a compilation error rather than a warning containing
Packit Service 4684c1
   "literal string").  Also note that in C++, it is only safe to use if
Packit Service 4684c1
   FUNCTION has no overloads.
Packit Service 4684c1
Packit Service 4684c1
   For an example, it is possible to poison 'getline' by:
Packit Service 4684c1
   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
Packit Service 4684c1
     [getline]) in configure.ac, which potentially defines
Packit Service 4684c1
     HAVE_RAW_DECL_GETLINE
Packit Service 4684c1
   - adding this code to a header that wraps the system <stdio.h>:
Packit Service 4684c1
     #undef getline
Packit Service 4684c1
     #if HAVE_RAW_DECL_GETLINE
Packit Service 4684c1
     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
Packit Service 4684c1
       "not universally present; use the gnulib module getline");
Packit Service 4684c1
     #endif
Packit Service 4684c1
Packit Service 4684c1
   It is not possible to directly poison global variables.  But it is
Packit Service 4684c1
   possible to write a wrapper accessor function, and poison that
Packit Service 4684c1
   (less common usage, like &environ, will cause a compilation error
Packit Service 4684c1
   rather than issue the nice warning, but the end result of informing
Packit Service 4684c1
   the developer about their portability problem is still achieved):
Packit Service 4684c1
     #if HAVE_RAW_DECL_ENVIRON
Packit Service 4684c1
     static char ***
Packit Service 4684c1
     rpl_environ (void) { return &environ; }
Packit Service 4684c1
     _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
Packit Service 4684c1
     # undef environ
Packit Service 4684c1
     # define environ (*rpl_environ ())
Packit Service 4684c1
     #endif
Packit Service 4684c1
   or better (avoiding contradictory use of 'static' and 'extern'):
Packit Service 4684c1
     #if HAVE_RAW_DECL_ENVIRON
Packit Service 4684c1
     static char ***
Packit Service 4684c1
     _GL_WARN_ON_USE_ATTRIBUTE ("environ is not always properly declared")
Packit Service 4684c1
     rpl_environ (void) { return &environ; }
Packit Service 4684c1
     # undef environ
Packit Service 4684c1
     # define environ (*rpl_environ ())
Packit Service 4684c1
     #endif
Packit Service 4684c1
   */
Packit Service 4684c1
#ifndef _GL_WARN_ON_USE
Packit Service 4684c1
Packit Service 4684c1
# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
Packit Service 4684c1
/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
Packit Service 4684c1
#  define _GL_WARN_ON_USE(function, message) \
Packit Service 4684c1
extern __typeof__ (function) function __attribute__ ((__warning__ (message)))
Packit Service 4684c1
#  define _GL_WARN_ON_USE_ATTRIBUTE(message) \
Packit Service 4684c1
  __attribute__ ((__warning__ (message)))
Packit Service 4684c1
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
Packit Service 4684c1
/* Verify the existence of the function.  */
Packit Service 4684c1
#  define _GL_WARN_ON_USE(function, message) \
Packit Service 4684c1
extern __typeof__ (function) function
Packit Service 4684c1
#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
Packit Service 4684c1
# else /* Unsupported.  */
Packit Service 4684c1
#  define _GL_WARN_ON_USE(function, message) \
Packit Service 4684c1
_GL_WARN_EXTERN_C int _gl_warn_on_use
Packit Service 4684c1
#  define _GL_WARN_ON_USE_ATTRIBUTE(message)
Packit Service 4684c1
# endif
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
Packit Service 4684c1
   is like _GL_WARN_ON_USE (function, "string"), except that in C++ mode the
Packit Service 4684c1
   function is declared with the given prototype, consisting of return type,
Packit Service 4684c1
   parameters, and attributes.
Packit Service 4684c1
   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
Packit Service 4684c1
   not work in this case.  */
Packit Service 4684c1
#ifndef _GL_WARN_ON_USE_CXX
Packit Service 4684c1
# if !defined __cplusplus
Packit Service 4684c1
#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
Packit Service 4684c1
     _GL_WARN_ON_USE (function, msg)
Packit Service 4684c1
# else
Packit Service 4684c1
#  if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
Packit Service 4684c1
#   define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
Packit Service 4684c1
extern rettype function parameters_and_attributes \
Packit Service 4684c1
     __attribute__ ((__warning__ (msg)))
Packit Service 4684c1
#  elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
Packit Service 4684c1
/* Verify the existence of the function.  */
Packit Service 4684c1
#   define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
Packit Service 4684c1
extern rettype function parameters_and_attributes
Packit Service 4684c1
#  else /* Unsupported.  */
Packit Service 4684c1
#   define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
Packit Service 4684c1
_GL_WARN_EXTERN_C int _gl_warn_on_use
Packit Service 4684c1
#  endif
Packit Service 4684c1
# endif
Packit Service 4684c1
#endif
Packit Service 4684c1
Packit Service 4684c1
/* _GL_WARN_EXTERN_C declaration;
Packit Service 4684c1
   performs the declaration with C linkage.  */
Packit Service 4684c1
#ifndef _GL_WARN_EXTERN_C
Packit Service 4684c1
# if defined __cplusplus
Packit Service 4684c1
#  define _GL_WARN_EXTERN_C extern "C"
Packit Service 4684c1
# else
Packit Service 4684c1
#  define _GL_WARN_EXTERN_C extern
Packit Service 4684c1
# endif
Packit Service 4684c1
#endif