summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2017-08-19 11:25:24 -0700
committerGuy Harris <guy@alum.mit.edu>2017-08-19 11:25:24 -0700
commit3dc736d939536bcd843597cb655fcba28268705c (patch)
tree6c69e8113f12d847aa00e1c56df66c5777a43137
parent297bf6343f27ea1d18e5dad529c253ffd3935d41 (diff)
downloadtcpdump-3dc736d939536bcd843597cb655fcba28268705c.tar.gz
Handle attributes for function pointers by checking the compiler version.
Handle attributes for function pointers the same way we handle attributes for functions, by explicitly checking for the compiler version with #if rather than with a configure script check. That's one fewer thing that, if you're not using autoconf, has to be done in some other fashion. While we're at it, put NORETURN in the right place to have it work with Microsoft Visual Studio as well as various UN*X compilers.
-rw-r--r--aclocal.m490
-rw-r--r--config.h.in11
-rwxr-xr-xconfigure125
-rw-r--r--configure.in5
-rw-r--r--funcattrs.h23
-rw-r--r--machdep.c10
-rw-r--r--netdissect.h22
-rw-r--r--print.c6
-rw-r--r--tcpdump.c10
9 files changed, 37 insertions, 265 deletions
diff --git a/aclocal.m4 b/aclocal.m4
index cfd59afd..a0031412 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1234,96 +1234,6 @@ AC_MSG_RESULT($ac_cv___attribute___unused)
])
dnl
-dnl Test whether __attribute__((format)) can be used without warnings
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE___FORMAT, [
-AC_MSG_CHECKING([whether __attribute__((format)) can be used without warnings])
-AC_CACHE_VAL(ac_cv___attribute___format, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-extern int foo(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int
-main(int argc, char **argv)
-{
- foo("%s", "test");
-}
- ]])],
-ac_cv___attribute___format=yes,
-ac_cv___attribute___format=no)])
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___format" = "yes"; then
- AC_DEFINE(__ATTRIBUTE___FORMAT_OK, 1,
- [define if your compiler allows __attribute__((format)) without a warning])
-fi
-AC_MSG_RESULT($ac_cv___attribute___format)
-])
-
-dnl
-dnl Test whether __attribute__((format)) can be applied to function
-dnl pointers
-dnl
-
-AC_DEFUN(AC_C___ATTRIBUTE___FORMAT_FUNCTION_POINTER, [
-AC_MSG_CHECKING([whether __attribute__((format)) can be applied to function pointers])
-AC_CACHE_VAL(ac_cv___attribute___format_function_pointer, [
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-extern int (*foo)(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int
-main(int argc, char **argv)
-{
- (*foo)("%s", "test");
-}
- ]])],
-ac_cv___attribute___format_function_pointer=yes,
-ac_cv___attribute___format_function_pointer=no)])
-if test "$ac_cv___attribute___format_function_pointer" = "yes"; then
- AC_DEFINE(__ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS, 1,
- [define if your compiler allows __attribute__((format)) to be applied to function pointers])
-fi
-AC_MSG_RESULT($ac_cv___attribute___format_function_pointer)
-])
-
-AC_DEFUN(AC_C___ATTRIBUTE___NORETURN_FUNCTION_POINTER, [
-AC_MSG_CHECKING([whether __attribute__((noreturn)) can be applied to function pointers without warnings])
-AC_CACHE_VAL(ac_cv___attribute___noreturn_function_pointer, [
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-AC_COMPILE_IFELSE([
- AC_LANG_SOURCE([[
-#include <stdlib.h>
-
-extern int (*foo)(int i)
- __attribute__ ((noreturn));
-
-int
-main(int argc, char **argv)
-{
- (*foo)(1);
-}
- ]])],
-ac_cv___attribute___noreturn_function_pointer=yes,
-ac_cv___attribute___noreturn_function_pointer=no)])
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___noreturn_function_pointer" = "yes"; then
- AC_DEFINE(__ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS, 1,
- [define if your compiler allows __attribute__((noreturn)) to be applied to function pointers])
-fi
-AC_MSG_RESULT($ac_cv___attribute___noreturn_function_pointer)
-])
-
-dnl
dnl Test whether __attribute__((fallthrough)) can be used without warnings
dnl
diff --git a/config.h.in b/config.h.in
index 6388afdc..6adf589f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -335,17 +335,6 @@
warning */
#undef __ATTRIBUTE___FALLTHROUGH_OK
-/* define if your compiler allows __attribute__((format)) without a warning */
-#undef __ATTRIBUTE___FORMAT_OK
-
-/* define if your compiler allows __attribute__((format)) to be applied to
- function pointers */
-#undef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
-
-/* define if your compiler allows __attribute__((noreturn)) to be applied to
- function pointers */
-#undef __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS
-
/* to handle Ultrix compilers that don't support const in prototypes */
#undef const
diff --git a/configure b/configure
index a369590d..64b05e0e 100755
--- a/configure
+++ b/configure
@@ -3670,131 +3670,6 @@ fi
$as_echo "$ac_cv___attribute___unused" >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((noreturn)) can be applied to function pointers without warnings" >&5
-$as_echo_n "checking whether __attribute__((noreturn)) can be applied to function pointers without warnings... " >&6; }
-if ${ac_cv___attribute___noreturn_function_pointer+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-extern int (*foo)(int i)
- __attribute__ ((noreturn));
-
-int
-main(int argc, char **argv)
-{
- (*foo)(1);
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___noreturn_function_pointer=yes
-else
- ac_cv___attribute___noreturn_function_pointer=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___noreturn_function_pointer" = "yes"; then
-
-$as_echo "#define __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___noreturn_function_pointer" >&5
-$as_echo "$ac_cv___attribute___noreturn_function_pointer" >&6; }
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((format)) can be used without warnings" >&5
-$as_echo_n "checking whether __attribute__((format)) can be used without warnings... " >&6; }
-if ${ac_cv___attribute___format+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-save_CFLAGS="$CFLAGS"
-CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-extern int foo(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int
-main(int argc, char **argv)
-{
- foo("%s", "test");
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___format=yes
-else
- ac_cv___attribute___format=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-CFLAGS="$save_CFLAGS"
-if test "$ac_cv___attribute___format" = "yes"; then
-
-$as_echo "#define __ATTRIBUTE___FORMAT_OK 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___format" >&5
-$as_echo "$ac_cv___attribute___format" >&6; }
-
- if test "$ac_cv___attribute___format" = "yes"; then
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((format)) can be applied to function pointers" >&5
-$as_echo_n "checking whether __attribute__((format)) can be applied to function pointers... " >&6; }
-if ${ac_cv___attribute___format_function_pointer+:} false; then :
- $as_echo_n "(cached) " >&6
-else
-
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-
-#include <stdlib.h>
-
-extern int (*foo)(const char *fmt, ...)
- __attribute__ ((format (printf, 1, 2)));
-
-int
-main(int argc, char **argv)
-{
- (*foo)("%s", "test");
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv___attribute___format_function_pointer=yes
-else
- ac_cv___attribute___format_function_pointer=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-
-if test "$ac_cv___attribute___format_function_pointer" = "yes"; then
-
-$as_echo "#define __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS 1" >>confdefs.h
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___format_function_pointer" >&5
-$as_echo "$ac_cv___attribute___format_function_pointer" >&6; }
-
- fi
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether __attribute__((fallthrough)) can be used without warnings" >&5
$as_echo_n "checking whether __attribute__((fallthrough)) can be used without warnings... " >&6; }
if ${ac_cv___attribute___fallthrough+:} false; then :
diff --git a/configure.in b/configure.in
index a7b879fc..b342468e 100644
--- a/configure.in
+++ b/configure.in
@@ -25,11 +25,6 @@ AC_LBL_C_INLINE
AC_C___ATTRIBUTE__
if test "$ac_cv___attribute__" = "yes"; then
AC_C___ATTRIBUTE___UNUSED
- AC_C___ATTRIBUTE___NORETURN_FUNCTION_POINTER
- AC_C___ATTRIBUTE___FORMAT
- if test "$ac_cv___attribute___format" = "yes"; then
- AC_C___ATTRIBUTE___FORMAT_FUNCTION_POINTER
- fi
AC_C___ATTRIBUTE___FALLTHROUGH
fi
diff --git a/funcattrs.h b/funcattrs.h
index 63d3f565..bea98634 100644
--- a/funcattrs.h
+++ b/funcattrs.h
@@ -76,13 +76,25 @@
* HP aCC A.06.10 and later.
*/
#define NORETURN __attribute((noreturn))
+
+ /*
+ * However, GCC didn't support that for function *pointers* until GCC
+ * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481.
+ */
+ #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 401))
+ #define NORETURN_FUNCPTR
+ #else
+ #define NORETURN_FUNCPTR __attribute((noreturn))
+ #endif
#elif defined(_MSC_VER)
/*
* MSVC.
*/
#define NORETURN __declspec(noreturn)
+ #define NORETURN_FUNCPTR __declspec(noreturn)
#else
#define NORETURN
+ #define NORETURN_FUNCPTR
#endif
/*
@@ -101,8 +113,19 @@
* or HP aCC A.06.10 and later.
*/
#define PRINTFLIKE(x,y) __attribute__((__format__(__printf__,x,y)))
+
+ /*
+ * However, GCC didn't support that for function *pointers* until GCC
+ * 4.1.0; see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3481.
+ */
+ #if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) < 401))
+ #define PRINTFLIKE_FUNCPTR(x,y)
+ #else
+ #define PRINTFLIKE_FUNCPTR(x,y) __attribute__((__format__(__printf__,x,y)))
+ #endif
#else
#define PRINTFLIKE(x,y)
+ #define PRINTFLIKE_FUNCPTR(x,y)
#endif
/*
diff --git a/machdep.c b/machdep.c
index 1f086161..df16c6e2 100644
--- a/machdep.c
+++ b/machdep.c
@@ -31,20 +31,12 @@
*/
#include <netdissect-stdinc.h>
-#ifndef HAVE___ATTRIBUTE__
-#define __attribute__(x)
-#endif /* HAVE___ATTRIBUTE__ */
-
#ifdef __osf__
#include <sys/sysinfo.h>
#include <sys/proc.h>
#if !defined(HAVE_SNPRINTF)
-int snprintf(char *, size_t, const char *, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK
- __attribute__((format(printf, 3, 4)))
-#endif /* __ATTRIBUTE___FORMAT_OK */
- ;
+int snprintf(char *, size_t, const char *, ...) PRINTFLIKE(3, 4);
#endif /* !defined(HAVE_SNPRINTF) */
#endif /* __osf__ */
diff --git a/netdissect.h b/netdissect.h
index 899e4b62..26d6d47b 100644
--- a/netdissect.h
+++ b/netdissect.h
@@ -186,27 +186,15 @@ struct netdissect_options {
/* pointer to function to do regular output */
int (*ndo_printf)(netdissect_options *,
const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
- __attribute__ ((format (printf, 2, 3)))
-#endif
- ;
+ PRINTFLIKE_FUNCPTR(2, 3);
/* pointer to function to output errors */
- void (*ndo_error)(netdissect_options *,
- const char *fmt, ...)
-#ifdef __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS
- __attribute__ ((noreturn))
-#endif /* __ATTRIBUTE___NORETURN_OK_FOR_FUNCTION_POINTERS */
-#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
- __attribute__ ((format (printf, 2, 3)))
-#endif /* __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS */
- ;
+ void NORETURN_FUNCPTR (*ndo_error)(netdissect_options *,
+ const char *fmt, ...)
+ PRINTFLIKE_FUNCPTR(2, 3);
/* pointer to function to output warnings */
void (*ndo_warning)(netdissect_options *,
const char *fmt, ...)
-#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
- __attribute__ ((format (printf, 2, 3)))
-#endif
- ;
+ PRINTFLIKE_FUNCPTR(2, 3);
};
#define PT_VAT 1 /* Visual Audio Tool */
diff --git a/print.c b/print.c
index 15468d6f..20d8ab51 100644
--- a/print.c
+++ b/print.c
@@ -226,9 +226,9 @@ static const struct printer printers[] = {
static void ndo_default_print(netdissect_options *ndo, const u_char *bp,
u_int length);
-static void ndo_error(netdissect_options *ndo,
- FORMAT_STRING(const char *fmt), ...)
- NORETURN PRINTFLIKE(2, 3);
+static void NORETURN ndo_error(netdissect_options *ndo,
+ FORMAT_STRING(const char *fmt), ...)
+ PRINTFLIKE(2, 3);
static void ndo_warning(netdissect_options *ndo,
FORMAT_STRING(const char *fmt), ...)
PRINTFLIKE(2, 3);
diff --git a/tcpdump.c b/tcpdump.c
index 86ccc50c..270f79b4 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -185,17 +185,17 @@ cap_channel_t *capdns;
#endif
/* Forwards */
-static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2);
+static NORETURN void error(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2);
-static void exit_tcpdump(int) NORETURN;
+static NORETURN void exit_tcpdump(int);
static RETSIGTYPE cleanup(int);
static RETSIGTYPE child_cleanup(int);
static void print_version(void);
static void print_usage(void);
-static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN;
-static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN;
+static NORETURN void show_tstamp_types_and_exit(pcap_t *, const char *device);
+static NORETURN void show_dlts_and_exit(pcap_t *, const char *device);
#ifdef HAVE_PCAP_FINDALLDEVS
-static void show_devices_and_exit (void) NORETURN;
+static NORETURN void show_devices_and_exit(void);
#endif
static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);