1#! /bin/sh
2#
3# Check that the warning flags documented in invoke.texi match up
4# with what the compiler accepts.
5#
6# Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
7# Written by Ralf Wildenhues <Ralf.Wildenhues@gmx.de>.
8#
9# This script is Free Software, and it can be copied, distributed and
10# modified as defined in the GNU General Public License.  A copy of
11# its license can be downloaded from http://www.gnu.org/copyleft/gpl.html
12#
13# Call this script as
14#    check_warning_flags.sh path/to/invoke.texi
15# with CC set to the compiler to be tested.
16# The script scribbles in the current directory.
17
18progname=`echo "$0" | sed 's,.*/,,'`
19usage ()
20{
21  echo "usage: $progname path/to/gcc/doc"
22  echo "set \$CC to the compiler to be checked"
23  exit 1
24}
25
26ret=0
27LC_ALL=C
28export LC_ALL
29: ${CC=gcc}
30test $# = 1 || usage
31gcc_docdir=$1
32invoke_texi=$gcc_docdir/invoke.texi
33test -r "$invoke_texi" || {
34  echo "$progname: error: cannot read '$invoke_texi'" >&2
35  usage
36}
37filebase=check_warning_flags_file$$
38stderr=check_warning_flags_stderr$$
39
40remove_problematic_flags='
41  /-Wlarger-than-/d
42  /-Wframe-larger-than/d
43  /-Wdisallowed-function-list/d
44  /-W[alp],/d
45  /-Werror/d
46  /-Wpadded/d
47  /pedantic-ms-format/d
48  /=/d'
49
50# Ensure that indexed warnings are accepted.
51set x `sed '/^@opindex W/{
52  s/^@opindex /-/
53  '"$remove_problematic_flags"'
54  /-W[alp]$/d
55  p
56}
57d' <"$invoke_texi"`
58shift
59: >$filebase.c
60$CC -c $filebase.c "$@" 2>&1 |
61  grep -v 'command line option.*is valid for.*but not for' >$stderr
62if test -s $stderr; then
63  echo "options listed in @opindex but not accepted by the compiler:" >&2
64  cat $stderr >&2
65  ret=1
66fi
67rm -f $filebase.c $stderr
68
69# Check documentation of warning options.
70for lang in c c++ objc obj-c++; do
71  case $lang in
72  c)       ext=c; langmatch='[^-]C[^+].*only' ;;
73  c++)     ext=C; langmatch='[^-]C++.*only' ;;
74  objc)    ext=m; langmatch='Objective-C[^+].*only' ;;
75  obj-c++) ext=M; langmatch='Objective-C++.*only' ;;
76  esac
77  file=$filebase.$ext
78  : >$file
79  $CC -c $file 2>$stderr
80  if grep 'not installed on this system' $stderr >/dev/null ||
81    grep 'installation problem, cannot exec' $stderr >/dev/null ||
82    grep 'error trying to exec' $stderr >/dev/null
83  then
84    echo "$progname: $CC is not configured for language $lang, skipping checks" >&2
85    rm -f $file $filebase.o $filebase.obj $stderr
86    continue
87  fi
88
89  # Verify good warning flags.
90  set x `sed '
91    t a
92    :a
93    /^@item -W/{
94      /'"$langmatch"'/b x
95      / only)/d
96      b x
97    }
98    d
99    :x
100    '"$remove_problematic_flags"'
101    s/^@item //
102    s/ .*//
103    ' <"$invoke_texi"`
104  shift
105  $CC -c $file -O "$@" 2>$stderr
106  if test -s $stderr; then
107    echo failures:  >&2
108    cat $stderr >&2
109    ret=1
110  fi
111
112  # Verify bad warning flags.
113  set x `sed '
114    t a
115    :a
116    /^@item -W/{
117      / only)/!d
118      /'"$langmatch"'/d
119      b x
120    }
121    d
122    :x
123    '"$remove_problematic_flags"'
124    s/^@item //
125    s/ .*//
126    ' <"$invoke_texi"`
127  shift
128  $CC -c $file -O "$@" 2>$stderr
129  # cat $stderr >&2
130  test $# = `grep 'command line option.*valid.*but not for' <$stderr | wc -l` || {
131    for warning
132    do
133      grep "command line option.*$warning.*valid" <$stderr >&2 ||
134	echo "valid for $lang but not annotated as such: $warning"
135    done
136    ret=1
137  }
138  rm -f $file $filebase.o $filebase.obj $stderr
139done
140
141
142remove_problematic_help_flags='
143  /^W$/d
144  /^W[alp]$/d
145  /^Werror-implicit-function-declaration$/d
146  /^Wsynth$/d
147  /-$/d
148  /=/d'
149help_flags=`
150  $CC --help -v 2>/dev/null | tr ' ' '\012' |
151    sed -n '
152      b a
153      :a
154      s/^-\(W[^<,]*\).*/\1/
155      t x
156      d
157      :x
158      '"$remove_problematic_help_flags"'
159      p' | sort -u`
160: >$filebase.c
161for flag in $help_flags; do
162  $CC -c $filebase.c -$flag 2>/dev/null || {
163    echo "warning -$flag not supported" >&2
164    ret=1
165  }
166  grep "@item.*$flag" $gcc_docdir/../*/*.texi >/dev/null || {
167    # For @item, we are satisfied with either -Wfoo or -Wno-foo.
168    inverted_flag=`echo "$flag" | sed '
169      s/^Wno-/W/
170      t
171      s/^W/Wno-/'`
172    grep "@item.*$inverted_flag" $gcc_docdir/../*/*.texi >/dev/null || {
173      echo "warning -$flag not documented in $gcc_docdir/../*/*.texi" >&2
174      ret=1
175    }
176  }
177done
178rm -f $filebase.c $filebase.o
179
180exit $ret
181