Bug 79828 - missing div-by-zero warning
Summary: missing div-by-zero warning
Status: NEW
Alias: None
Product: gcc
Classification: Unclassified
Component: tree-optimization (show other bugs)
Version: 7.0.1
: P3 enhancement
Target Milestone: ---
Assignee: Not yet assigned to anyone
Keywords: diagnostic
Depends on:
Reported: 2017-03-03 10:21 UTC by Arnd Bergmann
Modified: 2017-03-03 16:11 UTC (History)
2 users (show)

See Also:
Known to work:
Known to fail:
Last reconfirmed: 2017-03-03 00:00:00


Note You need to log in before you can comment on or make changes to this bug.
Description Arnd Bergmann 2017-03-03 10:21:30 UTC
Building the kernel with gcc-7.0.1 (r245831 at the time of testing), we ran into a warning from objtool about a function ending in an undefined instruction:

drivers/pwm/pwm-hibvt.o: warning: objtool: hibvt_pwm_get_state() falls through to next function hibvt_pwm_apply()

I reduced the test case to a trivial division by zero:

  static inline int return0(void) { return 0; }
  int provoke_div0_warning(void) { return 1 / return0(); }

which gets turned into a single trapping instruction

0000000000000018 <provoke_div0_warning>:
  18:	d4207d00 	brk	#0x3e8
0000000000000010 <provoke_div0_warning>:
  10:	0f 0b                	ud2    

This seems to be a result of r242636, and in the discussion
on that patch, I found a remark from Jeff Law that there
should be a warning for it:

I think that having this gcc warning would have been
rather useful in debugging the kernel build warning.
Any chance this could be added?
Comment 1 Richard Biener 2017-03-03 10:27:27 UTC
The warning exists in the frontends only at the moment.  Note such warning in the middle-end has the chance of false positives from (for example) path isolation.
Comment 2 Arnd Bergmann 2017-03-03 11:06:08 UTC
(In reply to Richard Biener from comment #1)
> Note such warning in the middle-end has the chance of false
> positives from (for example) path isolation.

Would it be possible to warn if a function always traps? The
kernel function that found this does not get inlined and has
only one return statement, which never gets reached.
Comment 3 Jakub Jelinek 2017-03-03 11:16:00 UTC
I'm afraid the warning would be huge amounts of false positives due to path isolation/jump threading and similar optimization.
Comment 4 Jakub Jelinek 2017-03-03 11:16:26 UTC
s/would be/would have/
Comment 5 Marc Glisse 2017-03-03 11:48:31 UTC
If we only warn when the trap is always executed as Arnd suggests (determined in a similar way as uninitialized vs maybe-uninitialized), I guess there should be fewer false positive (only cloning seems likely to produce them). On the other hand, it would likely miss most interesting warnings (although it would have helped the kernel this once, apparently).
Comment 6 Jakub Jelinek 2017-03-03 11:56:11 UTC
If the warning has false positives, then I'm sure the kernel will turn it off anyway like it does with tons of other warnings.
Comment 7 Jeffrey A. Law 2017-03-03 15:55:37 UTC
The thing is, if we could prove the trap is always executed, then we'd just zap everything prior to the trap without visible side effects and everything after the trap.  It's actually not an interesting case.

It's critical to remember that a trap introduced by the compiler is on a *path* through the CFG and a series of conditionals has to be met for the trap to be executed.  The compiler has already tried  to prove the path is infeasible and failed.

In fact, that pass was originally introduced specifically because there are cases where the compiler will never be able to prove a particular problem path can't execute and as a result it must keep the path in the CFG, which in turn leads to false positives from -Wuninitialized later.  By isolating the path and introducing a trap on that path, the CFG simplifies in useful ways *and* if the program were to erroneously get on the path, it gets halted prior to execution of undefined behavior which is desirable from a security standpoint.

There is some code in tree-ssa-uninit.c which does predicate analysis to further reduce the set of false positives for -Wuninitialized.  However, that code won't solve the problems that folks are looking at here (if it did, we wouldn't have erroneous path isolation to begin with).
Comment 8 Arnd Bergmann 2017-03-03 16:11:59 UTC
(In reply to Jakub Jelinek from comment #6)
> If the warning has false positives, then I'm sure the kernel will turn it
> off anyway like it does with tons of other warnings.

That is well possible. I try to catch new warnings early by building lots of kernels with random configurations and sending kernel fixes, but if there are more than a few dozen instances and none of them are interesting kernel bugs, I'd also turn off that warning.

I have started going through all available warnings to see how much output they generate (97GB on an allmodconfig kernel build when turning them all on with gcc, more with clang), with the intention of re-enabling the more useful ones, but will take a while to get there as I can only enable them after having fixed all the warnings we get.