Blame lib/warn-on-use.h

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