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