Bug 5735 – non-scalar types implicitly converted to boolean.

Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2011-03-14T11:04:00Z
Last change time
2015-06-09T05:10:42Z
Keywords
accepts-invalid, diagnostic, patch
Assigned to
nobody
Creator
ibuclaw

Attachments

IDFilenameSummaryContent-TypeSize
944issue5735.patchissue5735text/plain1039

Comments

Comment #0 by ibuclaw — 2011-03-14T11:04:05Z
Example code: struct A {} void foo(bool cond){} void main() { A a; int i; assert(a); // type A does not have a boolean value assert(i || a); // type A does not have a boolean value assert(0 || a); // OK if(a) {} // type A does not have a boolean value if(i || a) {} // type A does not have a boolean value if(0 || a) {} // type A does not have a boolean value foo(a); // cannot implicitly convert type A to bool foo(i || a); // OK foo(0 || a); // OK } The three examples that pass really should be errors. Regards
Comment #1 by ibuclaw — 2011-03-15T17:53:51Z
Note, this is also the same issue for static arrays and unions. int[1] arr; assert(arr); // type int[1u] does not have a boolean value assert(0 || arr); // OK union B {} B b; assert(b); // type B does not have a boolean value assert(0 || b); // OK Regards
Comment #2 by ibuclaw — 2011-04-06T03:22:23Z
Rough fix for 2.052 - will try out trunk later on today. Regards --- dmd.orig/cast.c 2011-02-18 01:15:38.000000000 +0000 +++ dmd/cast.c 2011-04-06 11:13:50.536604547 +0100 @@ -144,6 +144,10 @@ type = Type::terror; } Expression *e = optimize(WANTvalue | WANTflags); + if (t->ty == Tbool) + { // See if we can really convert the type to boolean. + e->checkToBoolean(NULL); + } if (e->type == t) return MATCHexact; if (e != this) --- dmd.orig/optimize.c 2011-02-18 01:15:38.000000000 +0000 +++ dmd/optimize.c 2011-04-06 10:55:18.075088167 +0100 @@ -990,6 +990,8 @@ e = new IntegerExp(loc, n1 || n2, type); } + else if (! e2->type->checkBoolean()) + ; // Don't convert e2 to bool if it's type disallows it. else if (e1->isBool(FALSE)) e = new BoolExp(loc, e2, type); }
Comment #3 by bugzilla — 2011-04-18T12:25:14Z
The patch seg faults building phobos because the argument to checkToBoolean is NULL.
Comment #4 by bugzilla — 2011-04-18T14:28:14Z
// Suitable for inclusion in test suite struct A {} void foo(bool cond){} void main() { A a; int i; static assert(!__traits(compiles, assert(a))); // type A does not have a boolean value static assert(!__traits(compiles, assert(i || a))); // type A does not have a boolean value static assert(!__traits(compiles, assert(0 || a))); // OK // if(a) {} // type A does not have a boolean value // if(i || a) {} // type A does not have a boolean value // if(0 || a) {} // type A does not have a boolean value static assert(!__traits(compiles, foo(a))); // cannot implicitly convert type A to bool static assert(!__traits(compiles, foo(i || a))); // OK static assert(!__traits(compiles, foo(0 || a))); // OK }
Comment #5 by ibuclaw — 2011-04-18T14:47:20Z
It can happen with '(1 && cond)' too.
Comment #6 by ibuclaw — 2011-04-18T14:58:27Z
Created attachment 944 issue5735 OK, Scrap the above, this is a check is in a better place - though it can cause duplicate errors to emit for the same line. I'm sure you'll know what's best to do though about that. :)
Comment #7 by bugzilla — 2011-04-18T15:58:09Z
Comment #8 by bugzilla — 2011-04-18T22:34:19Z