virt-compile-warnings.m4 9.0 KB
Newer Older
1
dnl
2 3
dnl Enable all known GCC compiler warnings, except for those
dnl we can't yet cope with
4 5 6 7 8 9
dnl
AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[
    dnl ******************************
    dnl More compiler warnings
    dnl ******************************

10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
    AC_ARG_ENABLE([werror],
                  AS_HELP_STRING([--enable-werror], [Use -Werror (if supported)]),
                  [set_werror="$enableval"],
                  [if test -d $srcdir/.git; then
                     is_git_version=true
                     set_werror=yes
                   else
                     set_werror=no
                   fi])

    # List of warnings that are not relevant / wanted

    # Don't care about C++ compiler compat
    dontwarn="$dontwarn -Wc++-compat"
    dontwarn="$dontwarn -Wabi"
    dontwarn="$dontwarn -Wdeprecated"
    # Don't care about ancient C standard compat
    dontwarn="$dontwarn -Wtraditional"
    # Don't care about ancient C standard compat
    dontwarn="$dontwarn -Wtraditional-conversion"
    # Ignore warnings in /usr/include
    dontwarn="$dontwarn -Wsystem-headers"
    # Happy for compiler to add struct padding
    dontwarn="$dontwarn -Wpadded"
    # GCC very confused with -O2
    dontwarn="$dontwarn -Wunreachable-code"
    # Too many to deal with
    dontwarn="$dontwarn -Wconversion"
    # Too many to deal with
    dontwarn="$dontwarn -Wsign-conversion"
    # GNULIB gettext.h violates
    dontwarn="$dontwarn -Wvla"
    # Many GNULIB header violations
    dontwarn="$dontwarn -Wundef"
    # Need to allow bad cast for execve()
    dontwarn="$dontwarn -Wcast-qual"
    # We need to use long long in many places
    dontwarn="$dontwarn -Wlong-long"
    # We allow manual list of all enum cases without default:
    dontwarn="$dontwarn -Wswitch-default"
    # We allow optional default: instead of listing all enum values
    dontwarn="$dontwarn -Wswitch-enum"
    # Not a problem since we don't use -fstrict-overflow
    dontwarn="$dontwarn -Wstrict-overflow"
    # Not a problem since we don't use -funsafe-loop-optimizations
    dontwarn="$dontwarn -Wunsafe-loop-optimizations"
    # Things like virAsprintf mean we can't use this
    dontwarn="$dontwarn -Wformat-nonliteral"
58 59
    # Gnulib's stat-time.h violates this
    dontwarn="$dontwarn -Waggregate-return"
E
Eric Blake 已提交
60 61
    # gcc 4.4.6 complains this is C++ only; gcc 4.7.0 implies this from -Wall
    dontwarn="$dontwarn -Wenum-compare"
E
Eric Blake 已提交
62 63
    # gcc 5.1 -Wformat-signedness mishandles enums, not ready for prime time
    dontwarn="$dontwarn -Wformat-signedness"
64

65 66
    # gcc 4.2 treats attribute(format) as an implicit attribute(nonnull),
    # which triggers spurious warnings for our usage
67
    AC_CACHE_CHECK([whether the C compiler's -Wformat allows NULL strings],
68 69 70 71 72 73 74 75 76 77 78 79 80 81
      [lv_cv_gcc_wformat_null_works], [
      save_CFLAGS=$CFLAGS
      CFLAGS='-Wunknown-pragmas -Werror -Wformat'
      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
        #include <stddef.h>
        static __attribute__ ((__format__ (__printf__, 1, 2))) int
        foo (const char *fmt, ...) { return !fmt; }
      ]], [[
        return foo(NULL);
      ]])],
      [lv_cv_gcc_wformat_null_works=yes],
      [lv_cv_gcc_wformat_null_works=no])
      CFLAGS=$save_CFLAGS])

E
Eric Blake 已提交
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
    # Gnulib uses '#pragma GCC diagnostic push' to silence some
    # warnings, but older gcc doesn't support this.
    AC_CACHE_CHECK([whether pragma GCC diagnostic push works],
      [lv_cv_gcc_pragma_push_works], [
      save_CFLAGS=$CFLAGS
      CFLAGS='-Wunknown-pragmas -Werror'
      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
        #pragma GCC diagnostic push
        #pragma GCC diagnostic pop
      ]])],
      [lv_cv_gcc_pragma_push_works=yes],
      [lv_cv_gcc_pragma_push_works=no])
      CFLAGS=$save_CFLAGS])
    if test $lv_cv_gcc_pragma_push_works = no; then
      dontwarn="$dontwarn -Wmissing-prototypes"
      dontwarn="$dontwarn -Wmissing-declarations"
98
      dontwarn="$dontwarn -Wcast-align"
99 100 101
    else
      AC_DEFINE_UNQUOTED([WORKING_PRAGMA_PUSH], 1,
       [Define to 1 if gcc supports pragma push/pop])
E
Eric Blake 已提交
102 103
    fi

104 105
    dnl Check whether strchr(s, char variable) causes a bogus compile
    dnl warning, which is the case with GCC < 4.6 on some glibc
106
    AC_CACHE_CHECK([whether the C compiler's -Wlogical-op gives bogus warnings],
107 108 109 110 111 112 113 114 115 116 117 118 119
      [lv_cv_gcc_wlogical_op_broken], [
      save_CFLAGS="$CFLAGS"
      CFLAGS="-O2 -Wlogical-op -Werror"
      AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
        #include <string.h>
        ]], [[
        const char *haystack;
        char needle;
        return strchr(haystack, needle) == haystack;]])],
        [lv_cv_gcc_wlogical_op_broken=no],
        [lv_cv_gcc_wlogical_op_broken=yes])
      CFLAGS="$save_CFLAGS"])

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
    # We might fundamentally need some of these disabled forever, but
    # ideally we'd turn many of them on
    dontwarn="$dontwarn -Wfloat-equal"
    dontwarn="$dontwarn -Wdeclaration-after-statement"
    dontwarn="$dontwarn -Wpacked"
    dontwarn="$dontwarn -Wunused-macros"
    dontwarn="$dontwarn -Woverlength-strings"
    dontwarn="$dontwarn -Wstack-protector"

    # Get all possible GCC warnings
    gl_MANYWARN_ALL_GCC([maybewarn])

    # Remove the ones we don't want, blacklisted earlier
    gl_MANYWARN_COMPLEMENT([wantwarn], [$maybewarn], [$dontwarn])

    # GNULIB uses '-W' (aka -Wextra) which includes a bunch of stuff.
    # Unfortunately, this means you can't simply use '-Wsign-compare'
    # with gl_MANYWARN_COMPLEMENT
    # So we have -W enabled, and then have to explicitly turn off...
139
    wantwarn="$wantwarn -Wno-sign-compare"
140 141 142

    # GNULIB expects this to be part of -Wc++-compat, but we turn
    # that one off, so we need to manually enable this again
143
    wantwarn="$wantwarn -Wjump-misses-init"
144 145

    # GNULIB turns on -Wformat=2 which implies -Wformat-nonliteral,
146 147 148 149
    # so we need to manually re-exclude it.  Also, older gcc 4.2
    # added an implied ATTRIBUTE_NONNULL on any parameter marked
    # ATTRIBUTE_FMT_PRINT, which causes -Wformat failure on our
    # intentional use of virReportError(code, NULL).
150
    wantwarn="$wantwarn -Wno-format-nonliteral"
151
    if test $lv_cv_gcc_wformat_null_works = no; then
152
      wantwarn="$wantwarn -Wno-format"
153
    fi
154 155 156 157

    # This should be < 256 really. Currently we're down to 4096,
    # but using 1024 bytes sized buffers (mostly for virStrerror)
    # stops us from going down further
158 159
    wantwarn="$wantwarn -Wframe-larger-than=4096"
    dnl wantwarn="$wantwarn -Wframe-larger-than=256"
160 161 162 163 164

    # Extra special flags
    dnl -fstack-protector stuff passes gl_WARN_ADD with gcc
    dnl on Mingw32, but fails when actually used
    case $host in
165 166 167
       aarch64-*-*)
       dnl "error: -fstack-protector not supported for this target [-Werror]"
       ;;
168
       *-*-linux*)
169 170 171
       dnl Prefer -fstack-protector-strong if it's available.
       dnl There doesn't seem to be great overhead in adding
       dnl -fstack-protector-all instead of -fstack-protector.
J
Ján Tomko 已提交
172
       dnl
173
       dnl We also don't need ssp-buffer-size with -all or -strong,
J
Ján Tomko 已提交
174 175
       dnl since functions are protected regardless of buffer size.
       dnl wantwarn="$wantwarn --param=ssp-buffer-size=4"
176
       wantwarn="$wantwarn -fstack-protector-strong"
177
       ;;
178 179 180
       *-*-freebsd*)
       dnl FreeBSD ships old gcc 4.2.1 which doesn't handle
       dnl -fstack-protector-all well
181
       wantwarn="$wantwarn -fstack-protector"
182

183
       wantwarn="$wantwarn -Wno-unused-command-line-argument"
184
       ;;
185
    esac
186 187
    wantwarn="$wantwarn -fexceptions"
    wantwarn="$wantwarn -fasynchronous-unwind-tables"
188 189 190

    # Need -fipa-pure-const in order to make -Wsuggest-attribute=pure
    # fire even without -O.
191
    wantwarn="$wantwarn -fipa-pure-const"
192 193
    # We should eventually enable this, but right now there are at
    # least 75 functions triggering warnings.
194 195
    wantwarn="$wantwarn -Wno-suggest-attribute=pure"
    wantwarn="$wantwarn -Wno-suggest-attribute=const"
196 197 198

    if test "$set_werror" = "yes"
    then
199
      wantwarn="$wantwarn -Werror"
200
    fi
201

202 203 204 205 206
    # Check for $CC support of each warning
    for w in $wantwarn; do
      gl_WARN_ADD([$w])
    done

207 208 209 210 211 212 213 214 215 216 217 218 219
    case $host in
        *-*-linux*)
        dnl Fall back to -fstack-protector-all if -strong is not available
        case $WARN_CFLAGS in
        *-fstack-protector-strong*)
        ;;
        *)
            gl_WARN_ADD(["-fstack-protector-all"])
        ;;
        esac
        ;;
    esac

220 221 222 223 224 225
    case $WARN_CFLAGS in
        *-Wsuggest-attribute=format*)
           AC_DEFINE([HAVE_SUGGEST_ATTRIBUTE_FORMAT], [1], [Whether -Wsuggest-attribute=format works])
        ;;
    esac

226 227 228 229 230 231 232 233 234 235 236
    # Silence certain warnings in gnulib, and use improved glibc headers
    AC_DEFINE([lint], [1],
      [Define to 1 if the compiler is checking for lint.])
    AH_VERBATIM([FORTIFY_SOURCE],
    [/* Enable compile-time and run-time bounds-checking, and some warnings,
        without upsetting newer glibc. */
     #if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
     # define _FORTIFY_SOURCE 2
     #endif
    ])

237 238 239 240 241
    if test "$gl_cv_warn_c__Wlogical_op" = yes &&
       test "$lv_cv_gcc_wlogical_op_broken" = yes; then
      AC_DEFINE_UNQUOTED([BROKEN_GCC_WLOGICALOP], 1,
       [Define to 1 if gcc -Wlogical-op reports false positives on strchr])
    fi
242
])