Skip to content

Commit a5abace

Browse files
petereadunstan
authored andcommitted
Fix -Wcast-function-type warnings
Three groups of issues needed to be addressed: load_external_function() and related functions returned PGFunction, even though not necessarily all callers are looking for a function of type PGFunction. Since these functions are really just wrappers around dlsym(), change to return void * just like dlsym(). In dynahash.c, we are using strlcpy() where a function with a signature like memcpy() is expected. This should be safe, as the new comment there explains, but the cast needs to be augmented to avoid the warning. In PL/Python, methods all need to be cast to PyCFunction, per Python API, but this now runs afoul of these warnings. (This issue also exists in core CPython.) To fix the second and third case, we add a new type pg_funcptr_t that is defined specifically so that gcc accepts it as a special function pointer that can be cast to any other function pointer without the warning. Also add -Wcast-function-type to the standard warning flags, subject to configure check. Reviewed-by: Tom Lane <tgl@sss.pgh.pa.us> Discussion: https://www.postgresql.org/message-id/flat/1e97628e-6447-b4fd-e230-d109cec2d584%402ndquadrant.com (cherry picked from commit de8feb1) Author: Peter Eisentraut <peter@eisentraut.org> Author: Alexandra Wang <alexandra.wang.oss@gmail.com>
1 parent f1cf641 commit a5abace

File tree

7 files changed

+127
-18
lines changed

7 files changed

+127
-18
lines changed

configure

+91
Original file line numberDiff line numberDiff line change
@@ -5645,6 +5645,97 @@ if test x"$pgac_cv_prog_CXX_cxxflags__Wimplicit_fallthrough_3" = x"yes"; then
56455645
fi
56465646

56475647

5648+
5649+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wcast-function-type, for CFLAGS" >&5
5650+
$as_echo_n "checking whether ${CC} supports -Wcast-function-type, for CFLAGS... " >&6; }
5651+
if ${pgac_cv_prog_CC_cflags__Wcast_function_type+:} false; then :
5652+
$as_echo_n "(cached) " >&6
5653+
else
5654+
pgac_save_CFLAGS=$CFLAGS
5655+
pgac_save_CC=$CC
5656+
CC=${CC}
5657+
CFLAGS="${CFLAGS} -Wcast-function-type"
5658+
ac_save_c_werror_flag=$ac_c_werror_flag
5659+
ac_c_werror_flag=yes
5660+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5661+
/* end confdefs.h. */
5662+
5663+
int
5664+
main ()
5665+
{
5666+
5667+
;
5668+
return 0;
5669+
}
5670+
_ACEOF
5671+
if ac_fn_c_try_compile "$LINENO"; then :
5672+
pgac_cv_prog_CC_cflags__Wcast_function_type=yes
5673+
else
5674+
pgac_cv_prog_CC_cflags__Wcast_function_type=no
5675+
fi
5676+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5677+
ac_c_werror_flag=$ac_save_c_werror_flag
5678+
CFLAGS="$pgac_save_CFLAGS"
5679+
CC="$pgac_save_CC"
5680+
fi
5681+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CC_cflags__Wcast_function_type" >&5
5682+
$as_echo "$pgac_cv_prog_CC_cflags__Wcast_function_type" >&6; }
5683+
if test x"$pgac_cv_prog_CC_cflags__Wcast_function_type" = x"yes"; then
5684+
CFLAGS="${CFLAGS} -Wcast-function-type"
5685+
fi
5686+
5687+
5688+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CXX} supports -Wcast-function-type, for CXXFLAGS" >&5
5689+
$as_echo_n "checking whether ${CXX} supports -Wcast-function-type, for CXXFLAGS... " >&6; }
5690+
if ${pgac_cv_prog_CXX_cxxflags__Wcast_function_type+:} false; then :
5691+
$as_echo_n "(cached) " >&6
5692+
else
5693+
pgac_save_CXXFLAGS=$CXXFLAGS
5694+
pgac_save_CXX=$CXX
5695+
CXX=${CXX}
5696+
CXXFLAGS="${CXXFLAGS} -Wcast-function-type"
5697+
ac_save_cxx_werror_flag=$ac_cxx_werror_flag
5698+
ac_cxx_werror_flag=yes
5699+
ac_ext=cpp
5700+
ac_cpp='$CXXCPP $CPPFLAGS'
5701+
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
5702+
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
5703+
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
5704+
5705+
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
5706+
/* end confdefs.h. */
5707+
5708+
int
5709+
main ()
5710+
{
5711+
5712+
;
5713+
return 0;
5714+
}
5715+
_ACEOF
5716+
if ac_fn_cxx_try_compile "$LINENO"; then :
5717+
pgac_cv_prog_CXX_cxxflags__Wcast_function_type=yes
5718+
else
5719+
pgac_cv_prog_CXX_cxxflags__Wcast_function_type=no
5720+
fi
5721+
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
5722+
ac_ext=c
5723+
ac_cpp='$CPP $CPPFLAGS'
5724+
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
5725+
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
5726+
ac_compiler_gnu=$ac_cv_c_compiler_gnu
5727+
5728+
ac_cxx_werror_flag=$ac_save_cxx_werror_flag
5729+
CXXFLAGS="$pgac_save_CXXFLAGS"
5730+
CXX="$pgac_save_CXX"
5731+
fi
5732+
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pgac_cv_prog_CXX_cxxflags__Wcast_function_type" >&5
5733+
$as_echo "$pgac_cv_prog_CXX_cxxflags__Wcast_function_type" >&6; }
5734+
if test x"$pgac_cv_prog_CXX_cxxflags__Wcast_function_type" = x"yes"; then
5735+
CXXFLAGS="${CXXFLAGS} -Wcast-function-type"
5736+
fi
5737+
5738+
56485739
# This was included in -Wall/-Wformat in older GCC versions
56495740

56505741
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${CC} supports -Wformat-security, for CFLAGS" >&5

configure.in

+2
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,8 @@ if test "$GCC" = yes -a "$ICC" = no; then
498498
PGAC_PROG_CXX_CFLAGS_OPT([-Wmissing-format-attribute])
499499
PGAC_PROG_CC_CFLAGS_OPT([-Wimplicit-fallthrough=3])
500500
PGAC_PROG_CXX_CFLAGS_OPT([-Wimplicit-fallthrough=3])
501+
PGAC_PROG_CC_CFLAGS_OPT([-Wcast-function-type])
502+
PGAC_PROG_CXX_CFLAGS_OPT([-Wcast-function-type])
501503
# This was included in -Wall/-Wformat in older GCC versions
502504
PGAC_PROG_CC_CFLAGS_OPT([-Wformat-security])
503505
PGAC_PROG_CXX_CFLAGS_OPT([-Wformat-security])

src/backend/utils/fmgr/dfmgr.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -95,21 +95,21 @@ static const Pg_magic_struct magic_data = PG_MODULE_MAGIC_DATA;
9595
* named funcname in it.
9696
*
9797
* If the function is not found, we raise an error if signalNotFound is true,
98-
* else return (PGFunction) NULL. Note that errors in loading the library
98+
* else return NULL. Note that errors in loading the library
9999
* will provoke ereport() regardless of signalNotFound.
100100
*
101101
* If filehandle is not NULL, then *filehandle will be set to a handle
102102
* identifying the library file. The filehandle can be used with
103103
* lookup_external_function to lookup additional functions in the same file
104104
* at less cost than repeating load_external_function.
105105
*/
106-
PGFunction
106+
void *
107107
load_external_function(const char *filename, const char *funcname,
108108
bool signalNotFound, void **filehandle)
109109
{
110110
char *fullname;
111111
void *lib_handle;
112-
PGFunction retval;
112+
void *retval;
113113

114114
/* Expand the possibly-abbreviated filename to an exact path name */
115115
fullname = expand_dynamic_library_name(filename);
@@ -122,7 +122,7 @@ load_external_function(const char *filename, const char *funcname,
122122
*filehandle = lib_handle;
123123

124124
/* Look up the function within the library. */
125-
retval = (PGFunction) dlsym(lib_handle, funcname);
125+
retval = dlsym(lib_handle, funcname);
126126

127127
if (retval == NULL && signalNotFound)
128128
ereport(ERROR,
@@ -165,12 +165,12 @@ load_file(const char *filename, bool restricted)
165165

166166
/*
167167
* Lookup a function whose library file is already loaded.
168-
* Return (PGFunction) NULL if not found.
168+
* Return NULL if not found.
169169
*/
170-
PGFunction
170+
void *
171171
lookup_external_function(void *filehandle, const char *funcname)
172172
{
173-
return (PGFunction) dlsym(filehandle, funcname);
173+
return dlsym(filehandle, funcname);
174174
}
175175

176176

src/backend/utils/hash/dynahash.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,16 @@ hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
398398
if (flags & HASH_KEYCOPY)
399399
hashp->keycopy = info->keycopy;
400400
else if (hashp->hash == string_hash)
401-
hashp->keycopy = (HashCopyFunc) strlcpy;
401+
{
402+
/*
403+
* The signature of keycopy is meant for memcpy(), which returns
404+
* void*, but strlcpy() returns size_t. Since we never use the return
405+
* value of keycopy, and size_t is pretty much always the same size as
406+
* void *, this should be safe. The extra cast in the middle is to
407+
* avoid warnings from -Wcast-function-type.
408+
*/
409+
hashp->keycopy = (HashCopyFunc) (pg_funcptr_t) strlcpy;
410+
}
402411
else
403412
hashp->keycopy = memcpy;
404413

src/include/c.h

+7
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,13 @@
277277
#define dummyret char
278278
#endif
279279

280+
/*
281+
* Generic function pointer. This can be used in the rare cases where it's
282+
* necessary to cast a function pointer to a seemingly incompatible function
283+
* pointer type while avoiding gcc's -Wcast-function-type warnings.
284+
*/
285+
typedef void (*pg_funcptr_t) (void);
286+
280287
/*
281288
* We require C99, hence the compiler should understand flexible array
282289
* members. However, for documentation purposes we still consider it to be

src/include/fmgr.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -716,9 +716,9 @@ extern bool CheckFunctionValidatorAccess(Oid validatorOid, Oid functionOid);
716716
*/
717717
extern char *Dynamic_library_path;
718718

719-
extern PGFunction load_external_function(const char *filename, const char *funcname,
720-
bool signalNotFound, void **filehandle);
721-
extern PGFunction lookup_external_function(void *filehandle, const char *funcname);
719+
extern void *load_external_function(const char *filename, const char *funcname,
720+
bool signalNotFound, void **filehandle);
721+
extern void *lookup_external_function(void *filehandle, const char *funcname);
722722
extern void load_file(const char *filename, bool restricted);
723723
extern void **find_rendezvous_variable(const char *varName);
724724
extern Size EstimateLibraryStateSpace(void);

src/pl/plpython/plpy_plpymodule.c

+7-7
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,13 @@ static PyMethodDef PLy_methods[] = {
5959
/*
6060
* logging methods
6161
*/
62-
{"debug", (PyCFunction) PLy_debug, METH_VARARGS | METH_KEYWORDS, NULL},
63-
{"log", (PyCFunction) PLy_log, METH_VARARGS | METH_KEYWORDS, NULL},
64-
{"info", (PyCFunction) PLy_info, METH_VARARGS | METH_KEYWORDS, NULL},
65-
{"notice", (PyCFunction) PLy_notice, METH_VARARGS | METH_KEYWORDS, NULL},
66-
{"warning", (PyCFunction) PLy_warning, METH_VARARGS | METH_KEYWORDS, NULL},
67-
{"error", (PyCFunction) PLy_error, METH_VARARGS | METH_KEYWORDS, NULL},
68-
{"fatal", (PyCFunction) PLy_fatal, METH_VARARGS | METH_KEYWORDS, NULL},
62+
{"debug", (PyCFunction) (pg_funcptr_t) PLy_debug, METH_VARARGS | METH_KEYWORDS, NULL},
63+
{"log", (PyCFunction) (pg_funcptr_t) PLy_log, METH_VARARGS | METH_KEYWORDS, NULL},
64+
{"info", (PyCFunction) (pg_funcptr_t) PLy_info, METH_VARARGS | METH_KEYWORDS, NULL},
65+
{"notice", (PyCFunction) (pg_funcptr_t) PLy_notice, METH_VARARGS | METH_KEYWORDS, NULL},
66+
{"warning", (PyCFunction) (pg_funcptr_t) PLy_warning, METH_VARARGS | METH_KEYWORDS, NULL},
67+
{"error", (PyCFunction) (pg_funcptr_t) PLy_error, METH_VARARGS | METH_KEYWORDS, NULL},
68+
{"fatal", (PyCFunction) (pg_funcptr_t) PLy_fatal, METH_VARARGS | METH_KEYWORDS, NULL},
6969

7070
/*
7171
* create a stored plan

0 commit comments

Comments
 (0)