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

Asked by Juha Hautamäki

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:
Last query:
Last reply:
Revision history for this message
Best Thomas Preud'homme (thomas-preudhomme) said :
#1

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.

Revision history for this message
Juha Hautamäki (juhahautamaki) said :
#2

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).

Revision history for this message
Juha Hautamäki (juhahautamaki) said :
#3

Thanks Thomas Preud'homme, that solved my question.