https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104359
Bug ID: 104359
Summary: GCC Treats bool with value != 1 as falsey when picking
branches
Product: gcc
Version: 11.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: will at willusher dot io
Target Milestone: ---
The following code when compiled with -O0 (or no -O option), will incorrectly
take both if branches:
#include <iostream>
#include <cstring>
int main() {
bool b = false;
std::memset(&b, 255, 1);
if (!b) {
std::cout << "!b = true branch\n";
} else {
std::cout << "!b = false branch\n";
}
if (b) {
std::cout << "b = true branch\n";
} else {
std::cout << "b = false branch\n";
}
return 0;
}
the resulting incorrect output is:
!b = true branch
b = true branch
However, b's "value" is 255, which should evaluate to "true". Recompiling the
program with -O1 or higher results in the correct output:
!b = false branch
b = true branch
Looking at compiler explorer: https://godbolt.org/z/TeMvMEc19 , it looks like
the if (!b) branch is compiled to:
movzx eax, BYTE PTR [rbp-1]
xor eax, 1
test al, al
je .L2
Which will evaluate to true for values != 1
This version of the code: https://godbolt.org/z/rhrP5W36v adds a loop and we
can see in -O1 and higher, the condition looks to just be a comparison vs. 0:
cmp BYTE PTR [rbp+0+rbx], 0
jne .L2