Uninitialized _Bool: "faa = (faa == 1) ? 0 : 1" is allways != 0

Asked by Juha Hautamäki on 2017-09-02

Hello

Toggling (uninitialized _Bool -variable) seems give randomly allways "true". Compiler generate code that toggle only lowest bit, and not mask out waste bits. If uninitialized memory value is other than 0 or 1, is result then allways true (!= 0). Compiler gives warning only when optimization is turned on (example "-Os"). Is this bug?

--------------------------

c:\test>type test.c

void foo2(_Bool);

void foo(void) {
        _Bool bar;

        while(1)
        {
                bar = (bar == 1) ? 0 : 1;
                foo2(bar);
        }
}

c:\test>arm-none-eabi-gcc -Wall -Wextra -c test.c

c:\test>arm-none-eabi-objdump -d test.o

test.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <foo>:
   0: e92d4800 push {fp, lr}
   4: e28db004 add fp, sp, #4
   8: e24dd008 sub sp, sp, #8
   c: e55b3005 ldrb r3, [fp, #-5]
  10: e2233001 eor r3, r3, #1
  14: e54b3005 strb r3, [fp, #-5]
  18: e55b3005 ldrb r3, [fp, #-5]
  1c: e1a00003 mov r0, r3
  20: ebfffffe bl 0 <foo2>
  24: eafffff8 b c <foo+0xc>

c:\test>arm-none-eabi-gcc -Wall -Wextra -Os -c test.c
test.c: In function 'foo':
test.c:8:7: warning: 'bar' may be used uninitialized in this function [-Wmaybe-uninitialized]
   bar = (bar == 1) ? 0 : 1;
   ~~~~^~~~~~~~~~~~~~~~~~~~

c:\test>arm-none-eabi-objdump -d test.o

test.o: file format elf32-littlearm

Disassembly of section .text:

00000000 <foo>:
   0: e92d4010 push {r4, lr}
   4: e2244001 eor r4, r4, #1
   8: e20440ff and r4, r4, #255 ; 0xff
   c: e1a00004 mov r0, r4
  10: ebfffffe bl 0 <foo2>
  14: eafffffa b 4 <foo+0x4>

c:\test>arm-none-eabi-objdump -d test.o

c:\test>arm-none-eabi-gcc -v
Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=c:/program\ files\ (x86)/gnu\ tools\ arm\ embedded/6\ 2017-q2-update/bin/../lib/gcc/arm-none-eabi/6.3.1/lto-wrapper.exe
Target: arm-none-eabi
Configured with: /tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/src/gcc/configure --build=x86_64-linux-gnu --host=i686-w64-mingw32 --target=arm-none-eabi --prefix=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw --libexecdir=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/lib --infodir=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/share/doc/gcc-arm-none-eabi/info --mandir=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/share/doc/gcc-arm-none-eabi/man --htmldir=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/share/doc/gcc-arm-none-eabi/html --pdfdir=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/share/doc/gcc-arm-none-eabi/pdf --enable-languages=c,c++ --enable-mingw-wildcard --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --with-gnu-as --with-gnu-ld --with-headers=yes --with-newlib --with-python-dir=share/gcc-arm-none-eabi --with-sysroot=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/install-mingw/arm-none-eabi --with-libiconv-prefix=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-gmp=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-mpfr=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-mpc=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-isl=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-libelf=/tmp/jenkins-GCC-6-buildandreg-223_20170621_1498033910/build-mingw/host-libs/usr --with-host-libstdcxx='-static-libgcc -Wl,-Bstatic,-lstdc++,-Bdynamic -lm' --with-pkgversion='GNU Tools for ARM Embedded Processors 6-2017-q2-update' --with-multilib-list=rmprofile
Thread model: single
gcc version 6.3.1 20170620 (release) [ARM/embedded-6-branch revision 249437] (GNU Tools for ARM Embedded Processors 6-2017-q2-update)

Question information

Language:
English Edit question
Status:
Solved
For:
GNU ARM Embedded Toolchain Edit question
Assignee:
No assignee Edit question
Solved by:
Thomas Preud'homme
Solved:
2017-09-04
Last query:
2017-09-04
Last reply:
2017-09-04

Hi Juha,

Since you are reading uninitialized data I would say that the compiler can pretty much do whatever it wants. You could try making it volatile which could "solve" the issue but it would be safer to construct a volatile pointer to a given location and read from it. I'm not sure how well defined are reads of uninitialized volatile local variables.

Best regards.

Hello

Many thanks for the prompt reply. The problem was solved by initializing the variables to value 0 or 1 before the before loop. Also, i found free analysis tool that can catch this kinds sourcecode errors (uninitialized local variables). The problem did not arised with old toolchain (5-2016-q1-update) because it did not leave a variable to unintialized state (when no optimization).

Thanks Thomas Preud'homme, that solved my question.