]> The Tcpdump Group git mirrors - tcpdump/commitdiff
Check for __attribute__ ((fallthrough)) (GCC 7).
authorDenis Ovsienko <[email protected]>
Fri, 21 Jul 2017 21:04:15 +0000 (22:04 +0100)
committerDenis Ovsienko <[email protected]>
Sat, 22 Jul 2017 18:33:49 +0000 (19:33 +0100)
The documentation claims that recent GCC is now better by default at
spotting cases of code flow falling through (which is true) and that it
avoids false positives by matching nearby source code comments with
regexps. However, the latter feature doesn't seem to work as reliably
as the manual describes it, so let's have a macro for this purpose.

Tested to work on:
* x86_64, Fedora 26, GCC 7.1.1 (w/__attribute__, w/fallthrough)
* x86_64, Ubuntu 16.04, GCC 5.4.0 (w/__attribute__, w/o fallthrough)
* x86_64, FreeBSD 11.0, CLang 3.8.0 (w/__attribute__, w/o fallthrough)
* SPARC, Solaris 10, SolStudio 12.4 (w/__attribute__, w/o fallthrough)
* SPARC, Solaris 10, SunStudio 11 (w/o __attribute__)

aclocal.m4
config.h.in
configure
configure.in
netdissect-stdinc.h

index 637054fd1f2a19eff20cb61be5dd49c003ea471c..cfd59afd5671eb47999b054206c4b9bc33acd997 100644 (file)
@@ -1323,6 +1323,47 @@ fi
 AC_MSG_RESULT($ac_cv___attribute___noreturn_function_pointer)
 ])
 
+dnl
+dnl Test whether __attribute__((fallthrough)) can be used without warnings
+dnl
+
+AC_DEFUN(AC_C___ATTRIBUTE___FALLTHROUGH, [
+AC_MSG_CHECKING([whether __attribute__((fallthrough)) can be used without warnings])
+AC_CACHE_VAL(ac_cv___attribute___fallthrough, [
+save_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS $ac_lbl_cc_force_warning_errors"
+AC_COMPILE_IFELSE([
+  AC_LANG_SOURCE([[
+#include <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+       int x = 1;
+       switch (x)
+       {
+       case 1:
+               printf ("x == %d\n", x);
+               __attribute__ ((fallthrough));
+       case 2:
+               printf ("x == %d\n", x);
+               break;
+       default:
+               return 0;
+       }
+       return x;
+}
+  ]])],
+ac_cv___attribute___fallthrough=yes,
+ac_cv___attribute___fallthrough=no)])
+CFLAGS="$save_CFLAGS"
+if test "$ac_cv___attribute___fallthrough" = "yes"; then
+  AC_DEFINE(__ATTRIBUTE___FALLTHROUGH_OK, 1,
+    [define if your compiler allows __attribute__((fallthrough)) without a warning])
+fi
+AC_MSG_RESULT($ac_cv___attribute___fallthrough)
+])
+
 AC_DEFUN(AC_LBL_SSLEAY,
     [
        #
index bbe1811b5b329c8db9338443ed87b8726cd0993c..6388afdc25da1eb247c135872e1cfa28d938ca95 100644 (file)
    #define below would cause a syntax error. */
 #undef _UINT8_T
 
+/* define if your compiler allows __attribute__((fallthrough)) without a
+   warning */
+#undef __ATTRIBUTE___FALLTHROUGH_OK
+
 /* define if your compiler allows __attribute__((format)) without a warning */
 #undef __ATTRIBUTE___FORMAT_OK
 
index 3eba815eb434eb22563147135b21192ea433b084..a369590db65c93dc0546f17f6d130d4e00089277 100755 (executable)
--- a/configure
+++ b/configure
@@ -3794,6 +3794,57 @@ fi
 $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 :
+  $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 <stdio.h>
+
+int
+main(int argc, char **argv)
+{
+       int x = 1;
+       switch (x)
+       {
+       case 1:
+               printf ("x == %d\n", x);
+               __attribute__ ((fallthrough));
+       case 2:
+               printf ("x == %d\n", x);
+               break;
+       default:
+               return 0;
+       }
+       return x;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_cv___attribute___fallthrough=yes
+else
+  ac_cv___attribute___fallthrough=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+CFLAGS="$save_CFLAGS"
+if test "$ac_cv___attribute___fallthrough" = "yes"; then
+
+$as_echo "#define __ATTRIBUTE___FALLTHROUGH_OK 1" >>confdefs.h
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv___attribute___fallthrough" >&5
+$as_echo "$ac_cv___attribute___fallthrough" >&6; }
+
 fi
 
 ac_ext=c
index 9b06fd9255308cb0a65f134cf679545fd9553463..a7b879fc6e8c6b9e51eded92ef8469f1b311a18e 100644 (file)
@@ -30,6 +30,7 @@ if test "$ac_cv___attribute__" = "yes"; then
        if test "$ac_cv___attribute___format" = "yes"; then
                AC_C___ATTRIBUTE___FORMAT_FUNCTION_POINTER
        fi
+       AC_C___ATTRIBUTE___FALLTHROUGH
 fi
 
 AC_CHECK_HEADERS(fcntl.h rpc/rpc.h rpc/rpcent.h netdnet/dnetdb.h)
index c7070f0a04c25453fc7aba7e50da66c4d1aa1401..fb385fb9c5cd01cdabd88169552bab2388c936eb 100644 (file)
@@ -401,4 +401,10 @@ struct in6_addr {
 #define max(a,b) ((b)>(a)?(b):(a))
 #endif
 
+#ifdef __ATTRIBUTE___FALLTHROUGH_OK
+#  define ND_FALL_THROUGH __attribute__ ((fallthrough))
+#else
+#  define ND_FALL_THROUGH
+#endif /* __ATTRIBUTE___FALLTHROUGH_OK */
+
 #endif /* netdissect_stdinc_h */