On 30/12/2011 05:59, Ian Lance Taylor wrote:
Vincent Lefevre<vincent+gcc@xxxxxxxxxx> writes:
On 2011-12-29 16:20:48 -0800, Ian Lance Taylor wrote:
To me this only proves that the compiler is not smart enough to see that
(s>> 1 == 0) implies that ((s& 0xffff) == 0xffff) can not be true.
Are you suggesting that the compiler should never warn if there is a
conditional guarding the array access? Would that in practice be better
or worse than the current behaviour?
I think there should be two different options:
* one that would trigger the warning if the compiler can prove
that there will always be an out-of-bound access when the
function is executed (unless the compiler can prove that the
function will never be executed);
* one that would trigger the warning if there may be an out-of-bound
access.
I wonder how often the first one would actually trigger. And I wonder
how much correct code the second one triggers on today. I personally
think it would be reasonable to rewrite the original example to avoid
the warning, since the code certainly looks like it can generate an out
of bounds access.
The first one quickly reduces to the halting problem, amongst other
issues. Consider :
static int a[10];
extern int foo(int x);
void bar(void) {
if (foo(1)) a[100]++;
}
You can't make a "no false negatives" warning here - it depends entirely
on foo, what it returns, and /if/ it returns.
If code looks dodgy, it should be warned as dodgy - that's what warnings
are for. If you want to write code that looks dodgy but isn't, as one
sometimes does, then disable the warning - either omit it from the
command line, or use "#pragma GCC diagnostic" around the code in question.
Warnings are there to help people write clearer code and avoid common or
accidental mistakes - a warning that triggers on /possible/ out-of-bound
array access fits that purpose fine (IMHO, of course).
If the compiler could tell without any doubt that the array is being
accessed illegally, then maybe an error would be better (since the code
has undefined behaviour at run-time, is the compiler allowed to reject it?).
BTW, can the user inform the compiler that some condition holds?
i.e. some kind of assert() but specifically for the compiler.
As far as I know there is no way to do this directly. The closest you
can come is something like
if (!condition_which_must_be_true ())
__builtin_unreachable ();
This will help the compiler in some cases but it won't track a complex
condition in any useful way.
Ian
Some sort of general way to provide information to the compiler via
assertions would be /really/ nice. The most useful case I could think
of would be to specify ranges of a variable or expression - if the
compiler could track those ranges and use them for warnings and
optimisation. Imagine the possibilities of a generalised "nonnull"
function parameter attribute with range limits, and the benefits that
would have for compile-time error checking!