add LocalStatic test case

This commit is contained in:
Wolfgang Thaller 2023-12-09 11:37:32 +01:00
parent d2dbd28dd3
commit c0d4e00b35
2 changed files with 64 additions and 0 deletions

View File

@ -90,3 +90,6 @@ test(${CMAKE_CURRENT_BINARY_DIR}/PascalTrapCPP.cc PROPERTIES PASS_REGULAR_EXPRES
configure_file(PascalString.c PascalStringCPP.cc)
test(PascalString.c PROPERTIES PASS_REGULAR_EXPRESSION "OK")
test(${CMAKE_CURRENT_BINARY_DIR}/PascalStringCPP.cc PROPERTIES PASS_REGULAR_EXPRESSION "OK")
test(LocalStatic.cc PROPERTIES PASS_REGULAR_EXPRESSION "OK")
set_target_properties(LocalStatic PROPERTIES COMPILE_FLAGS -fno-exceptions) # just to make assembly easier to read

View File

@ -0,0 +1,61 @@
#include "Test.h"
/*
This test case is intended to check for one particular binutils/xcoff problem:
Without a patch, GNU ld fails to allocate space for weak uninitialized csects [BS],
and therefore puts both at the same address.
Minimal example:
.weak _one[BS]
.csect _one[BS]
_one:
.space 4
.weak _two[BS]
.csect _two[BS]
_two:
.space 4
powerpc-apple-macos-as test.s > test.o
powerpc-apple-macos-ld -r test.o -o linked.o
powerpc-apple-macos-objdump -t -h linked.o
Observe the size of the .bss section and the addresses of symbols _one and _two.
This test case tests for it using a thread-safe local static variable in an inline
function, which boils down to a pair of weakly-linked uninitialized csects as above.
*/
// noinline so that it doesn't get optimized away
__attribute__((noinline)) int foo()
{
return 42;
}
// the `inline` triggers a problem.
// the static var and its guard variable are marked `.weak`,
// and the XCOFF linker puts them at the same address.
inline int bar()
{
static int cachedFoo = foo();
return cachedFoo;
}
// wrap it in a noinline function to make reading the assembly easier.
__attribute__((noinline)) int baz()
{
return bar();
}
int main()
{
if (baz() != 42)
TestLog("NO");
else
TestLog("OK");
}