summaryrefslogtreecommitdiff
path: root/m4/virt-compile-warnings.m4
blob: eb689e2f88a664cdb7b9e2d9b83306731d2d2300 (plain)
1
2
3
4
5
6
7
8
9
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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
dnl
dnl Enable all known GCC compiler warnings, except for those
dnl we can't yet cope with
dnl
AC_DEFUN([LIBVIRT_COMPILE_WARNINGS],[
    dnl ******************************
    dnl More compiler warnings
    dnl ******************************

    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"
    # Gnulib's stat-time.h violates this
    dontwarn="$dontwarn -Waggregate-return"
    # gcc 4.4.6 complains this is C++ only; gcc 4.7.0 implies this from -Wall
    dontwarn="$dontwarn -Wenum-compare"
    # gcc 5.1 -Wformat-signedness mishandles enums, not ready for prime time
    dontwarn="$dontwarn -Wformat-signedness"

    # gcc 4.2 treats attribute(format) as an implicit attribute(nonnull),
    # which triggers spurious warnings for our usage
    AC_CACHE_CHECK([whether the C compiler's -Wformat allows NULL strings],
      [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])

    # 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"
      dontwarn="$dontwarn -Wcast-align"
    else
      AC_DEFINE_UNQUOTED([WORKING_PRAGMA_PUSH], 1,
       [Define to 1 if gcc supports pragma push/pop])
    fi

    dnl Check whether strchr(s, char variable) causes a bogus compile
    dnl warning, which is the case with GCC < 4.6 on some glibc
    AC_CACHE_CHECK([whether the C compiler's -Wlogical-op gives bogus warnings],
      [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"])

    AC_CACHE_CHECK([whether gcc gives bogus warnings for -Wlogical-op],
      [lv_cv_gcc_wlogical_op_equal_expr_broken], [
        save_CFLAGS="$CFLAGS"
        CFLAGS="-O2 -Wlogical-op -Werror"
        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
          #define TEST1 1
          #define TEST2 TEST1
        ]], [[
          int test = 0;
          return test == TEST1 || test == TEST2;]])],
        [lv_cv_gcc_wlogical_op_equal_expr_broken=no],
        [lv_cv_gcc_wlogical_op_equal_expr_broken=yes])
        CFLAGS="$save_CFLAGS"])

    # 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...
    wantwarn="$wantwarn -Wno-sign-compare"

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

    # GNULIB turns on -Wformat=2 which implies -Wformat-nonliteral,
    # 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).
    wantwarn="$wantwarn -Wno-format-nonliteral"
    if test $lv_cv_gcc_wformat_null_works = no; then
      wantwarn="$wantwarn -Wno-format"
    fi

    # 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
    wantwarn="$wantwarn -Wframe-larger-than=4096"
    dnl wantwarn="$wantwarn -Wframe-larger-than=256"

    # Extra special flags
    dnl -fstack-protector stuff passes gl_WARN_ADD with gcc
    dnl on Mingw32, but fails when actually used
    case $host in
       aarch64-*-*)
       dnl "error: -fstack-protector not supported for this target [-Werror]"
       ;;
       *-*-linux*)
       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.
       dnl
       dnl We also don't need ssp-buffer-size with -all or -strong,
       dnl since functions are protected regardless of buffer size.
       dnl wantwarn="$wantwarn --param=ssp-buffer-size=4"
       wantwarn="$wantwarn -fstack-protector-strong"
       ;;
       *-*-freebsd*)
       dnl FreeBSD ships old gcc 4.2.1 which doesn't handle
       dnl -fstack-protector-all well
       wantwarn="$wantwarn -fstack-protector"

       wantwarn="$wantwarn -Wno-unused-command-line-argument"
       ;;
    esac
    wantwarn="$wantwarn -fexceptions"
    wantwarn="$wantwarn -fasynchronous-unwind-tables"

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

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

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

    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

    case $WARN_CFLAGS in
        *-Wsuggest-attribute=format*)
           AC_DEFINE([HAVE_SUGGEST_ATTRIBUTE_FORMAT], [1], [Whether -Wsuggest-attribute=format works])
        ;;
    esac

    # 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
    ])

    if test "$gl_cv_warn_c__Wlogical_op" = yes &&
       test "$lv_cv_gcc_wlogical_op_broken" = yes; then
      AC_DEFINE_UNQUOTED([BROKEN_GCC_WLOGICALOP_STRCHR], 1,
       [Define to 1 if gcc -Wlogical-op reports false positives on strchr])
    fi

    if test "$gl_cv_warn_c__Wlogical_op" = yes &&
       test "$lv_cv_gcc_wlogical_op_equal_expr_broken" = yes; then
      AC_DEFINE_UNQUOTED([BROKEN_GCC_WLOGICALOP_EQUAL_EXPR], 1,
        [Define to 1 if gcc -Wlogical-op reports false positive 'or' equal expr])
    fi
])