Bug 81580 - [ARM] C++ zero-sized array generates undefined instruction.
Summary: [ARM] C++ zero-sized array generates undefined instruction.
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: target (show other bugs)
Version: 8.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-27 08:58 UTC by Tejas Belagod
Modified: 2017-07-27 09:28 UTC (History)
1 user (show)

See Also:
Host:
Target: arm-none-eabi
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tejas Belagod 2017-07-27 08:58:14 UTC
This piece of code:

#include <array>

std::array<int,0> arr;

int foo (int i)
{
  return arr[i];
}

When compiled with:

$ arm-none-eabi-g++ -march=armv7-a -marm za.cc -S -O2 -o -

	.arm
	.fpu softvfp
	.type	_Z3fooi, %function
_Z3fooi:
	.fnstart
.LFB1017:
	@ Volatile: function does not return.
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	mov	r3, #0
	ldr	r3, [r3]
	.inst	0xe7f000f0
	.cantunwind
	.fnend
	.size	_Z3fooi, .-_Z3fooi
	.global	arr
	.bss
	.align	2
	.type	arr, %object
	.size	arr, 1
arr:
	.space	1
	.ident	"GCC: (GNU) 8.0.0 20170725 (experimental)"

The C++ Std '23.3.2.8 Zero sized arrays' does say that data() returned from zero-sized arrays is unspecified, but I don't think the compiler should be generating UNDEFINED instructions?

$ arm-none-eabi-g++ -v                                       
Using built-in specs.
COLLECT_GCC=/work/embedded/dev-builds/trunk/install/bin/arm-none-eabi-g++
COLLECT_LTO_WRAPPER=/data/embedded/dev-builds/trunk/install/libexec/gcc/arm-none-eabi/8.0.0/lto-wrapper
Target: arm-none-eabi
Configured with: /data/embedded/dev-builds/trunk/src/configure --prefix=/data/embedded/dev-builds/trunk/install --target=arm-none-eabi --enable-languages=c,c++ --with-cpu=cortex-m3 --with-mode=thumb --with-newlib --enable-newlib-io-long-long --enable-newlib-register-fini --enable-newlib-retargetable-locking --disable-newlib-supplied-syscalls --disable-multilib --with-libexpat --with-system-zlib --disable-gdbtk --enable-plugins --disable-threads --disable-tls --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-rda --disable-sid --disable-tui --disable-utils --disable-werror --disable-fixed-point
Thread model: single
gcc version 8.0.0 20170725 (experimental) (GCC)
Comment 1 ktkachov 2017-07-27 09:28:26 UTC
That inst is the trap instruction that is inserted by the isolate-paths pass because it detects undefined behaviour.

While the result of calling data() is unspecified, this is not what the testcase is doing. It's using operator[] which performs an access to the underlying storage directly and is thus out of bounds and undefined