On Tue, 5 May 2026 11:08:50 GMT, Anton Artemov <[email protected]> wrote:
>> Hi, please consider the following changes:
>>
>> This PR re-enables stringop-overflow warnings.
>>
>> It was assumed that the assert in `Thread::current()`, which calls the
>> `ATTRIBUTE_NORETURN` report function on failure, would be sufficient to
>> inform the GCC compiler that the current thread is always non-null. However,
>> it turns out that the assert is weakened by the `DebuggingContext`:
>>
>> Instead of having
>> `assert(current != nullptr, "Thread::current() called on detached thread");`
>>
>> in fact one gets this:
>> `if ( !(DebuggingContext::is_enabled() || current != null) ) {
>> report_vm_error(...); }`
>>
>> If `DebuggingContext` is enabled then the error will not be triggered
>> regardless of what `current` is. This makes GCC consider the virtually
>> impossible path and emit false positive warnings about atomics.
>>
>> The same problem is found in the Shenandoah code.
>>
>> The fix is to strengthen the assertion by
>> `DEBUG_ONLY(guarantee(current != nullptr, "...");)`
>> which removes the assertion completely in product builds, but for debug
>> builds makes it clear for the compiler that the operand cannot be nullptr.
>>
>> With this findings I conclude that it is not a compiler bug.
>>
>> Tested in tiers 1-5 and GHA.
>>
>> Separate builds with Shenandoah done.
>>
>> ---------
>> - [x] I confirm that I make this contribution in accordance with the
>> [OpenJDK Interim AI Policy](https://openjdk.org/legal/ai).
>
> Anton Artemov has updated the pull request incrementally with one additional
> commit since the last revision:
>
> 8320353: Fixed build issue on aarch64 and riscv64-debug
FYI
Using the new commit, JDK **fastdebug** build on linux-aarch64 with GCC 13
fails with the following error.
In this time, the warning is raised when compiling file `jvmtiTagMap.cpp`
In file included from
/tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:859,
from
/tmp/work/jdk-src/src/hotspot/share/runtime/atomic.hpp:31,
from
/tmp/work/jdk-src/src/hotspot/share/utilities/exceptions.hpp:30,
from /tmp/work/jdk-src/src/hotspot/share/oops/metadata.hpp:28,
from /tmp/work/jdk-src/src/hotspot/share/oops/oop.hpp:34,
from
/tmp/work/jdk-src/src/hotspot/share/runtime/handles.hpp:29,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/vmClasses.hpp:30,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/javaClasses.hpp:28,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/javaClasses.inline.hpp:28,
from
/tmp/work/jdk-src/src/hotspot/share/precompiled/precompiled.hpp:32:
In member function ‘void AtomicAccess::PlatformOrderedStore<byte_size,
RELEASE_X>::operator()(volatile T*, T) const [with T = unsigned int; long
unsigned int byte_size = 4]’,
inlined from ‘void AtomicAccess::StoreImpl<T, T, PlatformOp, typename
std::enable_if<PrimitiveConversions::Translate<T>::value,
void>::type>::operator()(volatile T*, T) const
[with T = JavaThreadState; PlatformOp = AtomicAccess::PlatformOrderedStore<4,
RELEASE_X>]’ at /tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:605
:17,
inlined from ‘static void AtomicAccess::release_store(volatile D*, T) [with
D = JavaThreadState; T = JavaThreadState]’ at /tmp/work/jdk-src/src/hotspot/sh
are/runtime/atomicAccess.hpp:903:65,
inlined from ‘void JavaThread::set_thread_state(JavaThreadState)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/javaThread.inline.hpp:156:30,
inlined from ‘static void
ThreadStateTransition::transition_from_vm(JavaThread*, JavaThreadState, bool)’
at /tmp/work/jdk-src/src/hotspot/share/runtime/in
terfaceSupport.inline.hpp:123:31,
inlined from
‘ThreadBlockInVMPreprocess<PRE_PROC>::ThreadBlockInVMPreprocess(JavaThread*,
PRE_PROC&, bool) [with PRE_PROC = void(JavaThread*)]’ at /tmp/wo
rk/jdk-src/src/hotspot/share/runtime/interfaceSupport.inline.hpp:209:23,
inlined from ‘ThreadBlockInVM::ThreadBlockInVM(JavaThread*, bool)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/interfaceSupport.inline.hpp:226:63,
inlined from ‘static void JvmtiTagMap::flush_all_object_free_events()’ at
/tmp/work/jdk-src/src/hotspot/share/prims/jvmtiTagMap.cpp:3141:34:
/tmp/work/jdk-src/src/hotspot/os_cpu/linux_aarch64/atomicAccess_linux_aarch64.hpp:213:61:
error: ‘void __atomic_store_4(volatile void*, unsigned int, int)’ wr
iting 4 bytes into a region of size 0 overflows the destination
[-Werror=stringop-overflow=]
213 | void operator()(volatile T* p, T v) const {
__atomic_store(const_cast<T*>(p), &v, __ATOMIC_RELEASE); }
|
~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In static member function ‘static void
JvmtiTagMap::flush_all_object_free_events()’:
cc1plus: note: destination object is likely at address zero
In member function ‘void AtomicAccess::PlatformOrderedStore<byte_size,
RELEASE_X>::operator()(volatile T*, T) const [with T = unsigned int; long
unsigned int byte_size = 4]’,
inlined from ‘void AtomicAccess::StoreImpl<T, T, PlatformOp, typename
std::enable_if<PrimitiveConversions::Translate<T>::value,
void>::type>::operator()(volatile T*, T) const
[with T = JavaThreadState; PlatformOp = AtomicAccess::PlatformOrderedStore<4,
RELEASE_X>]’ at /tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:605
:17,
inlined from ‘static void AtomicAccess::release_store(volatile D*, T) [with
D = JavaThreadState; T = JavaThreadState]’ at /tmp/work/jdk-src/src/hotspot/sh
are/runtime/atomicAccess.hpp:903:65,
inlined from ‘void JavaThread::set_thread_state(JavaThreadState)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/javaThread.inline.hpp:156:30,
inlined from ‘void JavaThread::set_thread_state_fence(JavaThreadState)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/javaThread.inline.hpp:163:19,
inlined from
‘ThreadBlockInVMPreprocess<PRE_PROC>::~ThreadBlockInVMPreprocess() [with
PRE_PROC = void(JavaThread*)]’ at /tmp/work/jdk-src/src/hotspot/shar
e/runtime/interfaceSupport.inline.hpp:214:36,
inlined from ‘ThreadBlockInVM::~ThreadBlockInVM()’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/interfaceSupport.inline.hpp:223:7,
inlined from ‘static void JvmtiTagMap::flush_all_object_free_events()’ at
/tmp/work/jdk-src/src/hotspot/share/prims/jvmtiTagMap.cpp:3142:5:
/tmp/work/jdk-src/src/hotspot/os_cpu/linux_aarch64/atomicAccess_linux_aarch64.hpp:213:61:
error: ‘void __atomic_store_4(volatile void*, unsigned int, int)’ wr
iting 4 bytes into a region of size 0 overflows the destination
[-Werror=stringop-overflow=]
213 | void operator()(volatile T* p, T v) const {
__atomic_store(const_cast<T*>(p), &v, __ATOMIC_RELEASE); }
|
~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In static member function ‘static void
JvmtiTagMap::flush_all_object_free_events()’:
cc1plus: note: destination object is likely at address zero
In member function ‘T AtomicAccess::PlatformOrderedLoad<byte_size,
X_ACQUIRE>::operator()(const volatile T*) const [with T = unsigned int; long
unsigned int byte_size = 4]’,
inlined from ‘T AtomicAccess::LoadImpl<T, PlatformOp, typename
std::enable_if<PrimitiveConversions::Translate<T>::value,
void>::type>::operator()(const volatile T*) const [wit
h T = JavaThreadState; PlatformOp = AtomicAccess::PlatformOrderedLoad<4,
X_ACQUIRE>]’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:536:34,
inlined from ‘static T AtomicAccess::load_acquire(const volatile T*) [with
T = JavaThreadState]’ at /tmp/work/jdk-src/src/hotspot/share/runtime/atomicAcce
ss.hpp:884:67,
inlined from ‘JavaThreadState JavaThread::thread_state() const’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/javaThread.inline.hpp:144:36,
inlined from
‘ThreadBlockInVMPreprocess<PRE_PROC>::~ThreadBlockInVMPreprocess() [with
PRE_PROC = void(JavaThread*)]’ at /tmp/work/jdk-src/src/hotspot/shar
e/runtime/interfaceSupport.inline.hpp:212:5,
inlined from ‘ThreadBlockInVM::~ThreadBlockInVM()’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/interfaceSupport.inline.hpp:223:7,
inlined from ‘static void JvmtiTagMap::flush_all_object_free_events()’ at
/tmp/work/jdk-src/src/hotspot/share/prims/jvmtiTagMap.cpp:3142:5:
/tmp/work/jdk-src/src/hotspot/os_cpu/linux_aarch64/atomicAccess_linux_aarch64.hpp:206:66:
error: ‘unsigned int __atomic_load_4(const volatile void*, int)’ wri
ting 4 bytes into a region of size 0 overflows the destination
[-Werror=stringop-overflow=]
206 | T operator()(const volatile T* p) const { T data;
__atomic_load(const_cast<T*>(p), &data, __ATOMIC_ACQUIRE); return data; }
|
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In static member function ‘static void
JvmtiTagMap::flush_all_object_free_events()’:
cc1plus: note: destination object is likely at address zero
In member function ‘T AtomicAccess::PlatformOrderedLoad<byte_size,
X_ACQUIRE>::operator()(const volatile T*) const [with T = long unsigned int;
long unsigned int byte_size = 8]’,
inlined from ‘T AtomicAccess::LoadImpl<T, PlatformOp, typename
std::enable_if<(std::is_integral<_Tp>::value || std::is_pointer<_Tp>::value),
void>::type>::operator()(const vol
atile T*) const [with T = long unsigned int; PlatformOp =
AtomicAccess::PlatformOrderedLoad<8, X_ACQUIRE>]’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/ato
micAccess.hpp:515:24,
inlined from ‘static T AtomicAccess::load_acquire(const volatile T*) [with
T = long unsigned int]’ at /tmp/work/jdk-src/src/hotspot/share/runtime/atomicAc
cess.hpp:884:67,
inlined from ‘uintptr_t SafepointMechanism::ThreadData::get_polling_word()’
at /tmp/work/jdk-src/src/hotspot/share/runtime/safepointMechanism.inline.hpp:5
1:36,
inlined from ‘static bool
SafepointMechanism::local_poll_armed(JavaThread*)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/safepointMechanism.inline.hpp:
55:47,
inlined from ‘static void
SafepointMechanism::process_if_requested(JavaThread*, bool, bool)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/safepointMecha
nism.inline.hpp:89:23,
inlined from
‘ThreadBlockInVMPreprocess<PRE_PROC>::~ThreadBlockInVMPreprocess() [with
PRE_PROC = void(JavaThread*)]’ at /tmp/work/jdk-src/src/hotspot/shar
e/runtime/interfaceSupport.inline.hpp:218:47,
inlined from
‘ThreadBlockInVMPreprocess<PRE_PROC>::~ThreadBlockInVMPreprocess() [with
PRE_PROC = void(JavaThread*)]’ at /tmp/work/jdk-src/src/hotspot/shar
e/runtime/interfaceSupport.inline.hpp:211:3,
inlined from ‘ThreadBlockInVM::~ThreadBlockInVM()’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/interfaceSupport.inline.hpp:223:7,
inlined from ‘static void JvmtiTagMap::flush_all_object_free_events()’ at
/tmp/work/jdk-src/src/hotspot/share/prims/jvmtiTagMap.cpp:3142:5:
/tmp/work/jdk-src/src/hotspot/os_cpu/linux_aarch64/atomicAccess_linux_aarch64.hpp:206:66:
error: ‘long unsigned int __atomic_load_8(const volatile void*, int)
’ writing 8 bytes into a region of size 0 overflows the destination
[-Werror=stringop-overflow=]
206 | T operator()(const volatile T* p) const { T data;
__atomic_load(const_cast<T*>(p), &data, __ATOMIC_ACQUIRE); return data; }
|
~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In static member function ‘static void
JvmtiTagMap::flush_all_object_free_events()’:
cc1plus: note: destination object is likely at address zero
cc1plus: all warnings being treated as errors
gmake[3]: *** [lib/CompileJvm.gmk:182:
/tmp/work/build-fastdebug/hotspot/variant-server/libjvm/objs/jvmtiTagMap.o]
Error 1
gmake[3]: *** Waiting for unfinished jobs....
gmake[2]: *** [make/Main.gmk:242: hotspot-server-libs] Error 2
ERROR: Build failed for target 'images' in configuration
'/tmp/work/build-fastdebug' (exit code 2)
=== Output from failing command(s) repeated here ===
* For target hotspot_variant-server_libjvm_objs_jvmtiTagMap.o:
In file included from
/tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:859,
from /tmp/work/jdk-src/src/hotspot/share/runtime/atomic.hpp:31,
from
/tmp/work/jdk-src/src/hotspot/share/utilities/exceptions.hpp:30,
from /tmp/work/jdk-src/src/hotspot/share/oops/metadata.hpp:28,
from /tmp/work/jdk-src/src/hotspot/share/oops/oop.hpp:34,
from
/tmp/work/jdk-src/src/hotspot/share/runtime/handles.hpp:29,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/vmClasses.hpp:30,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/javaClasses.hpp:28,
from
/tmp/work/jdk-src/src/hotspot/share/classfile/javaClasses.inline.hpp:28,
from
/tmp/work/jdk-src/src/hotspot/share/precompiled/precompiled.hpp:32:
In member function ‘void AtomicAccess::PlatformOrderedStore<byte_size,
RELEASE_X>::operator()(volatile T*, T) const [with T = unsigned int; long
unsigned int byte_size = 4]’,
inlined from ‘void AtomicAccess::StoreImpl<T, T, PlatformOp, typename
std::enable_if<PrimitiveConversions::Translate<T>::value,
void>::type>::operator()(volatile T*, T) const
[with T = JavaThreadState; PlatformOp = AtomicAccess::PlatformOrderedStore<4,
RELEASE_X>]’ at /tmp/work/jdk-src/src/hotspot/share/runtime/atomicAccess.hpp:605
:17,
inlined from ‘static void AtomicAccess::release_store(volatile D*, T) [with
D = JavaThreadState; T = JavaThreadState]’ at /tmp/work/jdk-src/src/hotspot/sh
are/runtime/atomicAccess.hpp:903:65,
inlined from ‘void JavaThread::set_thread_state(JavaThreadState)’ at
/tmp/work/jdk-src/src/hotspot/share/runtime/javaThread.inline.hpp:156:30,
inlined from ‘static void
ThreadStateTransition::transition_from_vm(JavaThread*, JavaThreadState, bool)’
at /tmp/work/jdk-src/src/hotspot/share/runtime/in
terfaceSupport.inline.hpp:123:31,
... (rest of output omitted)
* All command lines available in
/tmp/work/build-fastdebug/make-support/failure-logs.
=== End of repeated output ===
-------------
PR Comment: https://git.openjdk.org/jdk/pull/31025#issuecomment-4379814595