On 11/11/2014 05:26 PM, Richard Biener wrote:
On Tue, Nov 11, 2014 at 3:15 PM, Jakub Jelinek <ja...@redhat.com> wrote:
On Tue, Nov 11, 2014 at 05:02:55PM +0300, Marat Zakirov wrote:
I found that UBSan uses vrp pass to optimize generated checks. Keeping in
mind that vrp pass is about performance not stability I found example where
UBSan may skip true positive.
Example came from spec2006 perlbench:
int ext;
int
Perl_do_sv_dump()
{
int freq[10];
int i;
int max = 0;
int t = INT_MAX - 20;
if (max < ext)
max = ext;
for (i = 0; i <= max; i++)
if (freq[i])
ext = 0;
t += i; <<< (*)
return t;
}
vrp pass here sets vrp('i') to [0..10] in assumption that 'freq[i]' wont
violate array bound (vrp uses loop iteration number calculation, see
adjust_range_with_scev in tree-vrp.c). This means that UBSAN_CHECK_ADD build
for (*) should be deleted as redundant (and actually it is deleted by vrp
pass). So if at the execution max = 30, freq[5] != 0 uncaught overflow will
occur.
Well, if max is >= 10, then you should get -fsanitize=bounds error already.
-fsanitize=undefined already disables -faggressive-loop-optimizations,
perhaps it can also disable other optimizations (I thought deriving number
of iterations from assuming undefined behavior doesn't occur in loop stmts
is already guarded by -faggressive-loop-optimizations though).
You could use -fno-strict-overflow ...
There are also some unsafe code in functions
ubsan_expand_si_overflow_addsub_check, ubsan_expand_si_overflow_mul_check
which uses get_range_info to reduce checks number. As seen before vrp usage
for sanitizers may decrease quality of error detection.
Using VRP is completely intentional there, we don't want to generate too
slow code if you decide you want to optimize your code (for -O0 VRP isn't
performed of course).
Indeed. Note that the strict-overflow warnings are already a bad burden
on VRP quality - a way out to me was always to track two lattices,
one assuming strict-overflow and one assuming wrapping overflow.
For strict-overflow warnings you then can compare simplification outcome
against two lattices and warn if the result differs. Instead of that odd
+-INF(OVF) saturation.
Richard.
Jakub
It is seems that -fsanitize=something do not set
flag_aggressive_loop_optimizations to 0 in current GCC version. I made a
watchpoint on it but changes after init_options_struct weren't found. I
will make fix for both
flag_aggressive_loop_optimizationsno-strict-overflow and
flag_strict_overflow.
--Marat