Comment #0 by bearophile_hugs — 2011-01-04T04:52:27Z
Studying bug reports in Linux kernel I've seen many cases like:
!x & y
That were meant to be:
!(x & y)
So I suggest to turn an expression like the first one (!x & y) into a D2 syntax error.
So the D2 compiler asks the programmer for explicit parentheses like (the two following cases are both accepted, the error message may show both examples):
!(x & y)
Or even:
(!x) & y
The following case is not covered, this enhancement request is about the bitwise "&" case only:
!x && y
--------------------------
The Coccinelle tool is able to catch bugs like that with this little semantic patch:
// Copyright: (C) 2009 Gilles Muller, Julia Lawall, INRIA, DIKU. GPLv2.
@@ expression E1,E2; @@
(
!E1 & !E2
|
- !E1 & E2
+ !(E1 & E2)
)
For some of the (!x & y) Linux bugs caught by Coccinelle see:
http://coccinelle.lip6.fr/impact_linux.php
searching for "Correct occurrences of !x&y".
An example:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=b2d7c7f7a69fd953626c3e507bac70e18b21f70e
Comment #1 by bearophile_hugs — 2011-05-06T10:14:02Z
Comment #2 by bearophile_hugs — 2011-07-09T11:08:24Z
*** Issue 5814 has been marked as a duplicate of this issue. ***
Comment #3 by bearophile_hugs — 2011-10-19T15:35:52Z
One more case found here, in the source code of the Chrome browser:
http://www.viva64.com/en/b/0113/
Fragment N3:
#define SEC_ASN1_CHOICE 0x100000
typedef struct sec_ASN1Template_struct {
unsigned long kind;
...
} SEC_ASN1Template;
PRBool SEC_ASN1IsTemplateSimple(
const SEC_ASN1Template *theTemplate)
{
...
if (!theTemplate->kind & SEC_ASN1_CHOICE) {
...
}
A related case (Fragment N4), that I think too is worth catching (probably it's a less common bug):
bool GetPlatformFileInfo(...) {
...
info->is_directory =
file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
...
}
The probably right code for Fragment N4:
info->is_directory =
(file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
Comment #4 by timon.gehr — 2011-10-23T01:19:22Z
(In reply to comment #3)
> A related case (Fragment N4), that I think too is worth catching (probably it's
> a less common bug):
>
>
> bool GetPlatformFileInfo(...) {
> ...
> info->is_directory =
> file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY != 0;
> ...
> }
>
That is already caught with the current compiler.
Comment #5 by bearophile_hugs — 2011-11-13T09:57:46Z
I think one of those bugs are present in DMD sources too:
http://article.gmane.org/gmane.comp.lang.d.dmd.devel/2648
dmd\src\backend\cgreg.c(51):
> void cgreg_init()
> {
> if (!config.flags4 & CFG4optimized)
> return;
.\backend\cgreg.c(53) : warning C4806: '&' : unsafe operation: no value
of type 'bool' promoted to type 'int' can equal the given constant
Comment #6 by bearophile_hugs — 2011-11-25T15:55:36Z
One more example found in the Doom3 sources:
http://www.viva64.com/en/b/0120/
#define BIT( num ) ( 1 << ( num ) )
const int BUTTON_ATTACK = BIT(0);
void idTarget_WaitForButton::Think( void ) {
...
if ( player &&
( !player->oldButtons & BUTTON_ATTACK ) &&
( player->usercmd.buttons & BUTTON_ATTACK ) ) {
...
}
I hope people like Kenji Hara will create a patch to fix this situation in D language.
Comment #7 by bearophile_hugs — 2012-04-23T18:29:55Z