105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A C macro for emitting warnings if a function is used.
205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   Copyright (C) 2010-2012 Free Software Foundation, Inc.
305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is free software: you can redistribute it and/or modify it
505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   under the terms of the GNU General Public License as published
605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   by the Free Software Foundation; either version 3 of the License, or
705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (at your option) any later version.
805436638acc7c010349a69c3395f1a57c642dc62Ying Wang
905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This program is distributed in the hope that it will be useful,
1005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   but WITHOUT ANY WARRANTY; without even the implied warranty of
1105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   General Public License for more details.
1305436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   You should have received a copy of the GNU General Public License
1505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
1605436638acc7c010349a69c3395f1a57c642dc62Ying Wang
1705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* _GL_WARN_ON_USE (function, "literal string") issues a declaration
1805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   for FUNCTION which will then trigger a compiler warning containing
1905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the text of "literal string" anywhere that function is called, if
2005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   supported by the compiler.  If the compiler does not support this
2105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   feature, the macro expands to an unused extern declaration.
2205436638acc7c010349a69c3395f1a57c642dc62Ying Wang
2305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This macro is useful for marking a function as a potential
2405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   portability trap, with the intent that "literal string" include
2505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   instructions on the replacement function that should be used
2605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   instead.  However, one of the reasons that a function is a
2705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   portability trap is if it has the wrong signature.  Declaring
2805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   FUNCTION with a different signature in C is a compilation error, so
2905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   this macro must use the same type as any existing declaration so
3005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   that programs that avoid the problematic FUNCTION do not fail to
3105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   compile merely because they included a header that poisoned the
3205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   function.  But this implies that _GL_WARN_ON_USE is only safe to
3305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   use if FUNCTION is known to already have a declaration.  Use of
3405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   this macro implies that there must not be any other macro hiding
3505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the declaration of FUNCTION; but undefining FUNCTION first is part
3605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   of the poisoning process anyway (although for symbols that are
3705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   provided only via a macro, the result is a compilation error rather
3805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   than a warning containing "literal string").  Also note that in
3905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   C++, it is only safe to use if FUNCTION has no overloads.
4005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
4105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   For an example, it is possible to poison 'getline' by:
4205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   - adding a call to gl_WARN_ON_USE_PREPARE([[#include <stdio.h>]],
4305436638acc7c010349a69c3395f1a57c642dc62Ying Wang     [getline]) in configure.ac, which potentially defines
4405436638acc7c010349a69c3395f1a57c642dc62Ying Wang     HAVE_RAW_DECL_GETLINE
4505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   - adding this code to a header that wraps the system <stdio.h>:
4605436638acc7c010349a69c3395f1a57c642dc62Ying Wang     #undef getline
4705436638acc7c010349a69c3395f1a57c642dc62Ying Wang     #if HAVE_RAW_DECL_GETLINE
4805436638acc7c010349a69c3395f1a57c642dc62Ying Wang     _GL_WARN_ON_USE (getline, "getline is required by POSIX 2008, but"
4905436638acc7c010349a69c3395f1a57c642dc62Ying Wang       "not universally present; use the gnulib module getline");
5005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     #endif
5105436638acc7c010349a69c3395f1a57c642dc62Ying Wang
5205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   It is not possible to directly poison global variables.  But it is
5305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   possible to write a wrapper accessor function, and poison that
5405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   (less common usage, like &environ, will cause a compilation error
5505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   rather than issue the nice warning, but the end result of informing
5605436638acc7c010349a69c3395f1a57c642dc62Ying Wang   the developer about their portability problem is still achieved):
5705436638acc7c010349a69c3395f1a57c642dc62Ying Wang   #if HAVE_RAW_DECL_ENVIRON
5805436638acc7c010349a69c3395f1a57c642dc62Ying Wang   static char ***rpl_environ (void) { return &environ; }
5905436638acc7c010349a69c3395f1a57c642dc62Ying Wang   _GL_WARN_ON_USE (rpl_environ, "environ is not always properly declared");
6005436638acc7c010349a69c3395f1a57c642dc62Ying Wang   # undef environ
6105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   # define environ (*rpl_environ ())
6205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   #endif
6305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   */
6405436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _GL_WARN_ON_USE
6505436638acc7c010349a69c3395f1a57c642dc62Ying Wang
6605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
6705436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* A compiler attribute is available in gcc versions 4.3.0 and later.  */
6805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE(function, message) \
6905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern __typeof__ (function) function __attribute__ ((__warning__ (message)))
7005436638acc7c010349a69c3395f1a57c642dc62Ying Wang# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
7105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Verify the existence of the function.  */
7205436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE(function, message) \
7305436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern __typeof__ (function) function
7405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else /* Unsupported.  */
7505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE(function, message) \
7605436638acc7c010349a69c3395f1a57c642dc62Ying Wang_GL_WARN_EXTERN_C int _gl_warn_on_use
7705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
7805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
7905436638acc7c010349a69c3395f1a57c642dc62Ying Wang
8005436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* _GL_WARN_ON_USE_CXX (function, rettype, parameters_and_attributes, "string")
8105436638acc7c010349a69c3395f1a57c642dc62Ying Wang   is like _GL_WARN_ON_USE (function, "string"), except that the function is
8205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   declared with the given prototype, consisting of return type, parameters,
8305436638acc7c010349a69c3395f1a57c642dc62Ying Wang   and attributes.
8405436638acc7c010349a69c3395f1a57c642dc62Ying Wang   This variant is useful for overloaded functions in C++. _GL_WARN_ON_USE does
8505436638acc7c010349a69c3395f1a57c642dc62Ying Wang   not work in this case.  */
8605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _GL_WARN_ON_USE_CXX
8705436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if 4 < __GNUC__ || (__GNUC__ == 4 && 3 <= __GNUC_MINOR__)
8805436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
8905436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern rettype function parameters_and_attributes \
9005436638acc7c010349a69c3395f1a57c642dc62Ying Wang     __attribute__ ((__warning__ (msg)))
9105436638acc7c010349a69c3395f1a57c642dc62Ying Wang# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
9205436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* Verify the existence of the function.  */
9305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
9405436638acc7c010349a69c3395f1a57c642dc62Ying Wangextern rettype function parameters_and_attributes
9505436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else /* Unsupported.  */
9605436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_ON_USE_CXX(function,rettype,parameters_and_attributes,msg) \
9705436638acc7c010349a69c3395f1a57c642dc62Ying Wang_GL_WARN_EXTERN_C int _gl_warn_on_use
9805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
9905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
10005436638acc7c010349a69c3395f1a57c642dc62Ying Wang
10105436638acc7c010349a69c3395f1a57c642dc62Ying Wang/* _GL_WARN_EXTERN_C declaration;
10205436638acc7c010349a69c3395f1a57c642dc62Ying Wang   performs the declaration with C linkage.  */
10305436638acc7c010349a69c3395f1a57c642dc62Ying Wang#ifndef _GL_WARN_EXTERN_C
10405436638acc7c010349a69c3395f1a57c642dc62Ying Wang# if defined __cplusplus
10505436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_EXTERN_C extern "C"
10605436638acc7c010349a69c3395f1a57c642dc62Ying Wang# else
10705436638acc7c010349a69c3395f1a57c642dc62Ying Wang#  define _GL_WARN_EXTERN_C extern
10805436638acc7c010349a69c3395f1a57c642dc62Ying Wang# endif
10905436638acc7c010349a69c3395f1a57c642dc62Ying Wang#endif
110