]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Handle attributes for function pointers by checking the compiler version.
authorGuy Harris <[email protected]>
Sat, 19 Aug 2017 18:25:24 +0000 (11:25 -0700)
committerGuy Harris <[email protected]>
Sat, 19 Aug 2017 18:25:24 +0000 (11:25 -0700)
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.

aclocal.m4
config.h.in
configure
configure.in
funcattrs.h
machdep.c
netdissect.h
print.c
tcpdump.c

index cfd59afd5671eb47999b054206c4b9bc33acd997..a00314128f4de696522debae9fa3f434c1c6f13c 100644 (file)
@@ -1233,96 +1233,6 @@ fi
 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
index 6388afdc25da1eb247c135872e1cfa28d938ca95..6adf589ff6c10d94ee96e2e395d1403ca1793aff 100644 (file)
    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
 
index a369590db65c93dc0546f17f6d130d4e00089277..64b05e0e6803def67ae59b594377a2cfc0f349ff 100755 (executable)
--- 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 :
index a7b879fc6e8c6b9e51eded92ef8469f1b311a18e..b342468e00285ff5203381efe97e74bcceb2638e 100644 (file)
@@ -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
 
index 63d3f5656cf0900a8ec614cf3f27daedd586e620..bea986342cd3378db38ca738bac4d999ff92d55d 100644 (file)
    * 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
 
 /*
    * 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
 
 /*
index 1f0861611326b7e9828fad42072d56097c44aff3..df16c6e2708f4ffee8ff2009249b7e62a8891005 100644 (file)
--- a/machdep.c
+++ b/machdep.c
  */
 #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__ */
 
index 899e4b620f1d64caf54602ca8d0b808fa4dce525..26d6d47b3d1260d5da05ff481df3f25954977a7c 100644 (file)
@@ -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 15468d6f7b30b4e6f896580980c024a5aa2309fd..20d8ab51e2e49a4cf474f75efbaff17375747b78 100644 (file)
--- 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);
index 86ccc50c9c27139aa2bb03a09159e1a782d52215..270f79b4b92658d2188727f8b475b8ecc395e1ca 100644 (file)
--- 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 *);