[Bug c/67433] New: ?: expresion returns unexpected value when condition is a bool variable and it's value above 1

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

Bug ID: 67433
   Summary: ?: expresion returns unexpected value when condition
is a bool variable and it's value above 1
   Product: gcc
   Version: 6.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: xuejuncao at gmail dot com
  Target Milestone: ---


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

xuejuncao  changed:

   What|Removed |Added

Summary|?: expresion returns|?: expression returns
   |unexpected value when   |unexpected value when
   |condition is a bool |condition is a bool
   |variable and it's value |variable which memory is
   |above 1 |not true/false

--- Comment #1 from xuejuncao  ---
#include 
#include 
#include 

int main()
{
union u {
bool b;
char c;
} u;
memset((void *)&u, -1, sizeof(u));
bool b = (u.b ? 1 : 0);
int i = (u.b ? 1 : 0);
int j = (u.b ? 1 : 2);
printf("b = %d, i = %d, j = %d\n", b, i, j);
return 0;
}

without optimisation, the output is:
b = 1, i = 255, j = 1

with -O2, is:
b = 255, i = 255, j = 1


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

--- Comment #3 from xuejuncao  ---
(In reply to Andrew Pinski from comment #2)
> Bool can only be 0 or 1, any other value causes undefined behavior.

but it seems like a trap, the below code will not work fine, and will make
program abort.
(expect to write "1/0" that only takes 1 byte, but write 2 bytes when value is
negative)

https://github.com/google/protobuf/blob/master/src/google/protobuf/wire_format_lite_inl.h

inline void WireFormatLite::WriteBoolNoTag(bool value,
   io::CodedOutputStream* output) {
  output->WriteVarint32(value ? 1 : 0);
}


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

--- Comment #4 from xuejuncao  ---
btw, the same code works fine on Mac:

$gcc --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr
--with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

--- Comment #8 from xuejuncao  ---
thanks, i get the below result with -fsanitize=undefined 

boolmagic.c:12:16: runtime error: load of value 255, which is not a valid value
for type '_Bool'
boolmagic.c:13:15: runtime error: load of value 255, which is not a valid value
for type '_Bool'
boolmagic.c:14:15: runtime error: load of value 255, which is not a valid value
for type '_Bool'
b = 1, i = 1, j = 1

but, can i say the "-fsanitize=undefined" will _corrects_ the undefined
behaviour?

or replace the code by if/else, which works fine (lucky?)

int i; // = (u.b ? 1 : 0);
if (u.b) i = 1; else i = 0;


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

--- Comment #10 from xuejuncao  ---
when bool value read from unpacked stream or file, wen can not ensure it's 1 or
0;
so maybe the best solution is compile with "-D_Bool=char" for now :-/


[Bug c/67433] ?: expression returns unexpected value when condition is a bool variable which memory is not true/false

2015-09-02 Thread xuejuncao at gmail dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67433

--- Comment #12 from xuejuncao  ---
(In reply to Richard Biener from comment #11)
> (In reply to xuejuncao from comment #10)
> > when bool value read from unpacked stream or file, wen can not ensure it's 1
> > or 0;
> > so maybe the best solution is compile with "-D_Bool=char" for now :-/
> 
> You can always do the read with 'char' and then convert to _Bool.
> 
> You can also "fix" your testcase (I think, didn't try) by using
> 
> union u {
>   bool b : 1;
>   char c;
> } u;
> 
> (in case unions allow bitfield members)

yes, it works, but likes a trick:-)

bit operation to bool is also undefined
int i = (u.b & 1 ? 1 : 0); // works without -O2, useless with -O2