Re: Do not misuse Coverity please

From: Paulo Marques
Date: Wed Mar 30 2005 - 14:24:26 EST


Shankar Unni wrote:
Jean Delvare wrote:

v = p->field;
if (!p) return;

can be seen as equivalent to

if (!p) return;
v = p->field;


Heck, no.

You're missing the side-effect of a null pointer dereference crash (for p->field) (even though v is unused before the return). The optimizer is not allowed to make exceptions go away as a result of the hoisting.

I just had to try this out :)

Using gcc 3.3.2 this code sample:

struct test {
int code;
};

int test_func(struct test *a)
{
int ret;
if (!a) return -1;
ret = a->code;
return ret;
}

is compiled into:

0: 8b 54 24 04 mov 0x4(%esp,1),%edx
4: 83 c8 ff or $0xffffffff,%eax
7: 85 d2 test %edx,%edx
9: 74 02 je d <test_func+0xd>
b: 8b 02 mov (%edx),%eax
d: c3 ret

whereas this one:

int test_func(struct test *a)
{
int ret;
ret = a->code;
if (!a) return -1;
return ret;
}

is simply compiled into:

0: 8b 44 24 04 mov 0x4(%esp,1),%eax
4: 8b 00 mov (%eax),%eax
6: c3 ret

It seems that gcc is smart enough to know that after we've dereferenced a pointer, if it was NULL, it doesn't matter any more. So it just assumes that if execution reaches that "if" statement then the pointer can not be NULL at all.

So the 2 versions aren't equivalent, and gcc doesn't treat them as such either.

Just a minor nitpick, though: wouldn't it be possible for an application to catch the SIGSEGV and let the code proceed, making invalid the assumption made by gcc?

--
Paulo Marques - www.grupopie.com

All that is necessary for the triumph of evil is that good men do nothing.
Edmund Burke (1729 - 1797)
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/