Blame src/gl/warn-on-use.h

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