aboutsummaryrefslogtreecommitdiff
blob: 449bf236275cf5052e8ea0b26f762a1d777e348a (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
# Check for important gcc warnings
# TODO: adapt for clang?
# TODO: add -Wformat-security

gcc_warn_check() {
	local f

	# Evaluate misc gcc warnings
	if [[ -n ${PORTAGE_LOG_FILE} && -r ${PORTAGE_LOG_FILE} ]] ; then
		# In debug mode, this variable definition and corresponding grep calls
		# will produce false positives if they're shown in the trace.
		local reset_debug=0
		if [[ ${-/x/} != $- ]] ; then
			set +x
			reset_debug=1
		fi

		local m msgs=(
			# only will and does, no might :)
			'warning: .*will.*\[-Wstrict-aliasing\]'
			'warning: .*does.*\[-Wstrict-aliasing\]'
			'warning: .*\[-Wrestrict\]'
			# strict aliasing violation in C++ (Clang)
			'warning: .*\[-Wundefined-reinterpret-cast\]'

			# implicit declaration of function ‘...’
			'warning: .*\[-Wimplicit-function-declaration\]'
			# with -Wall, goes in pair with -Wimplicit-function-declaration
			# but without -Wall, we need to assert for it alone
			'warning: .*incompatible implicit declaration of built-in function'
			'warning: .*\[-Wbuiltin-declaration-mismatch\]'

			# 'is used uninitialized in this function' and some more
			'warning: .*\[-Wuninitialized\]'
			# comparisons like ‘X<=Y<=Z’ do not have their mathematical meaning
			'warning: .*mathematical meaning*\[-Wparentheses\]'
			# null argument where non-null required
			'warning: .*\[-Wnonnull\]'

			# array subscript is above/below/outside array bounds (FORTIFY_SOURCE)
			'warning: .*\[-Warray-bounds\]'
			# attempt to free a non-heap object
			'warning: .*\[-Wfree-nonheap-object\]'
			# those three do not have matching -W flags, it seems
			'warning: .*will always overflow destination buffer'
			# compile-time part of FORTIFY_SOURCE
			'warning: .*\[-Wstringop-overflow\]'
			'warning: .*\[-Wstringop-overread\]'
			'warning: .*\[-Wstringop-truncation\]'
			# clang-only, equivalent of -Wstringop-overflow
			'warning: .*\[-Wfortify-source\]'
			'warning: .*assuming pointer wraparound does not occur'
			'warning: .*escape sequence out of range'

			# all clang
			'warning: .*\[-Wstrlcpy-strlcat-size\]'
			'warning: .*\[-Wstrncat-size\]'
			'warning: .*\[-Wsuspicious-bzero\]'
			'warning: .*\[-Wvarargs\]'

			# left-hand operand of comma expression has no effect
			'warning: .*left.*comma.*\[-Wunused-value\]'
			# converting to non-pointer type ... from NULL and likes
			'warning: .*\[-Wconversion-null\]'
			# NULL used in arithmetic
			'warning: .*NULL.*\[-Wpointer-arith\]'
			# pointer to a function used in arithmetic and likes
			'warning: .*function.*\[-Wpointer-arith\]'
			# the address of ... will never be NULL and likes
			# (uses of function refs & string constants in conditionals)
			'warning: .*\[-Waddress\]'

			# TODO: we want to enable these but bash currently triggers
			# them with a trick in random.c where it intentionally wants
			# some truncation :(
			#
			# warning: assignment/initialization to ... from ... makes integer from pointer without cast
			#'warning: .*\[-Wint-conversion\]'
			# warning: cast to ... from integer of different size (or smaller size)
			#'warning: .*\[-Wint-to-pointer-cast\]'
			# warning: cast to ... from (smaller) integer type
			#'warning: .*\[-Wint-to-void-pointer-cast\]'
			# warning: cast from ... to integer of different size
			#'warning: .*\[-Wpointer-to-int-cast\]'

			# -Wformat
			# TODO: comment out some time in future for time_t & LFS preparedness
			#'warning: .*\[-Wformat=\]'
			# -Wformat variants
			'warning: .*too few arguments for format'
			'warning: .*missing sentinel in function call.*\[-Wformat=\]'
			'warning: .*\[-Wformat-truncation\]'
			# format ... expects a matching ... argument
			# (iow, too few arguments for format in new wording :))
			'warning: .*matching.*\[-Wformat=\]'

			# function returns address of local variable
			'warning: .*\[-Wreturn-local-addr\]'
			# missing return at end of function, or non-void return in a void function
			# (clang at least aggressively optimises on this)
			'warning: .*\[-Wreturn-type\]'
			# argument to sizeof ... is the same expression as the source
			'warning: .*\[-Wsizeof-pointer-memaccess\]'
			# iteration invokes undefined behavior
			'warning: .*\[-Waggressive-loop-optimizations\]'
			# conversion between pointers that have incompatible types
			'warning: .*\[-Wincompatible-pointer-types\]'
			# more specific form of -Wincompatible-pointer-types (Clang)
			'warning: .*\[-Wincompatible-function-pointer-types\]'
			# these will fail with CFI (https://reviews.llvm.org/D134831)
			# (gcc lacks -strict)
			#'warning: .*\[-Wcast-function-type\]'
			'warning: .*\[-Wcast-function-type-strict\]'
			# using wrong deallocator, e.g. using free() on object allocated using my_malloc()
			# when my_malloc() is annotated as needing my_free().
			'warning: .*\[-Wmismatched-dealloc\]'
			# clobbered: Warn for variables that might be changed by longjmp or vfork
			# (This warning is also enabled by -Wextra.)
			'warning: .*\[-Wclobbered\]'
			# LTO type mismatch (https://wiki.gentoo.org/wiki/Project:Toolchain/LTO)
			'warning: .*\[-Wlto-type-mismatch\]'
			# ODR (https://wiki.gentoo.org/wiki/Project:Toolchain/LTO)
			'warning: .*\[-Wodr\]'
			# warning: argument value A will result in undefined behaviour (Clang)
			'warning: .*\[-Wargument-undefined-behaviour\]'
			'warning: .*\[-Wnull-dereference\]'

			# general sensible warnings (will be rejected by modern compilers soon)
			'warning: .*\[-Wmain\]'
			'warning: .*\[-Wimplicit-int\]'
			'warning: .*\[-Wstring-compare\]'

			# this may be valid code :/
			#': warning: multi-character character constant'
			# need to check these two ...
			#': warning: assuming signed overflow does not occur when'
			#': warning: comparison with string literal results in unspecified behav'
			# yacc/lex likes to trigger this one
			#': warning: extra tokens at end of .* directive'
			# only gcc itself triggers this ?
			#': warning: .*noreturn.* function does return'
			# these throw false positives when 0 is used instead of NULL
			#': warning: missing sentinel in function call'
			#': warning: not enough variable arguments to fit a sentinel'
		)

		# join all messages into one grep-expression
		local joined_msgs
		printf -v joined_msgs '%s|' "${msgs[@]}"
		joined_msgs=${joined_msgs%|}

		local abort="no"
		local grep_cmd=grep
		[[ ${PORTAGE_LOG_FILE} = *.gz ]] && grep_cmd=zgrep

		# Force C locale to work around slow multibyte locales, bug #160234
		# Force text mode as newer grep will treat non-ASCII (e.g. UTF-8) as
		# binary when we run in the C locale.
		f=$(LC_CTYPE=C LC_COLLATE=C "${grep_cmd}" -E -a "${joined_msgs}" "${PORTAGE_LOG_FILE}" | uniq)
		if [[ -n ${f} ]] ; then
			abort="yes"

			# for now, don't make this fatal (see bug #337031)
			#if [[ ${f} == *'will always overflow destination buffer'* ]]; then
			#	always_overflow=yes
			#fi

			# Disabled for now because too many failures. bug #870412.
			#if [[ ${f} == *'[-Wimplicit-function-declaration]'* ]] ; then
			#	implicit_func_decl=yes
			#fi

			if [[ ${always_overflow} = yes || ${implicit_func_decl} = yes ]] ; then
				eerror
				eerror "QA Notice: Package triggers severe warnings which indicate that it"
				eerror "           may exhibit random runtime failures."
				eerror
				eerror "${f}"
				eerror
				eerror " Please file a bug about this at https://bugs.gentoo.org/"
				eerror " with the maintainer of the package."
				eerror
			else
				__vecho -ne '\n'
				eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
				eqawarn "           may exhibit random runtime failures."
				eqawarn "${f}"
				__vecho -ne '\n'
			fi
		fi

		[[ ${reset_debug} = 1 ]] && set -x

		if [[ ${abort} == "yes" ]] ; then
			if [[ ${gentoo_bug} = yes || ${always_overflow} = yes || ${implicit_func_decl} = yes ]] ; then
				die "install aborted due to severe warnings shown above"
			else
				echo "Please do not file a Gentoo bug and instead" \
				"report the above QA issues directly to the upstream" \
				"developers of this software." | fmt -w 70 | \
				while read -r line ; do eqawarn "${line}" ; done
				eqawarn "Homepage: ${HOMEPAGE}"
				has stricter ${FEATURES} && \
					die "install aborted due to severe warnings shown above"
			fi
		fi
	fi
}

gcc_warn_check
: # guarantee successful exit

# vim:ft=sh