From 62bc7b7c4247a62c23ea93cd960c3c0434925c49 Mon Sep 17 00:00:00 2001 From: Kim Barrett Date: Thu, 4 Sep 2025 05:42:18 +0000 Subject: [PATCH] 8300080: offset_of for GCC/Clang exhibits undefined behavior and is not always a compile-time constant Reviewed-by: stefank, jsjolen --- make/hotspot/lib/CompileJvm.gmk | 4 +++- .../share/utilities/globalDefinitions.hpp | 3 +++ .../share/utilities/globalDefinitions_gcc.hpp | 18 ------------------ .../utilities/globalDefinitions_visCPP.hpp | 2 -- 4 files changed, 6 insertions(+), 21 deletions(-) diff --git a/make/hotspot/lib/CompileJvm.gmk b/make/hotspot/lib/CompileJvm.gmk index 6b5edc85b23..bf92c50576a 100644 --- a/make/hotspot/lib/CompileJvm.gmk +++ b/make/hotspot/lib/CompileJvm.gmk @@ -97,11 +97,13 @@ CFLAGS_VM_VERSION := \ DISABLED_WARNINGS_gcc := array-bounds comment delete-non-virtual-dtor \ empty-body format-zero-length implicit-fallthrough int-in-bool-context \ + invalid-offsetof \ maybe-uninitialized missing-field-initializers \ shift-negative-value unknown-pragmas unused-but-set-variable \ unused-local-typedefs unused-variable -DISABLED_WARNINGS_clang := delete-non-abstract-non-virtual-dtor missing-braces \ +DISABLED_WARNINGS_clang := delete-non-abstract-non-virtual-dtor \ + invalid-offsetof missing-braces \ sometimes-uninitialized unknown-pragmas unused-but-set-variable \ unused-function unused-local-typedef unused-private-field unused-variable diff --git a/src/hotspot/share/utilities/globalDefinitions.hpp b/src/hotspot/share/utilities/globalDefinitions.hpp index 1ef548d6510..64ccae539a3 100644 --- a/src/hotspot/share/utilities/globalDefinitions.hpp +++ b/src/hotspot/share/utilities/globalDefinitions.hpp @@ -85,6 +85,9 @@ class oopDesc; // they cannot be defined and potential callers will fail to compile. #define NONCOPYABLE(C) C(C const&) = delete; C& operator=(C const&) = delete /* next token must be ; */ +// offset_of was a workaround for UB with offsetof uses that are no longer an +// issue. This can be removed once all uses have been converted. +#define offset_of(klass, field) offsetof(klass, field) //---------------------------------------------------------------------------------------------------- // Printf-style formatters for fixed- and variable-width types as pointers and diff --git a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp index 41b7868f8c7..f82f9b1386a 100644 --- a/src/hotspot/share/utilities/globalDefinitions_gcc.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_gcc.hpp @@ -84,24 +84,6 @@ inline int g_isnan(double f) { return isnan(f); } inline int g_isfinite(jfloat f) { return isfinite(f); } inline int g_isfinite(jdouble f) { return isfinite(f); } - -// gcc warns about applying offsetof() to non-POD object or calculating -// offset directly when base address is null. The -Wno-invalid-offsetof -// option could be used to suppress this warning, but we instead just -// avoid the use of offsetof(). -// -// FIXME: This macro is complex and rather arcane. Perhaps we should -// use offsetof() instead, with the invalid-offsetof warning -// temporarily disabled. -#define offset_of(klass,field) \ -([]() { \ - alignas(16) char space[sizeof (klass)]; \ - klass* dummyObj = (klass*)space; \ - char* c = (char*)(void*)&dummyObj->field; \ - return (size_t)(c - space); \ -}()) - - #if defined(_LP64) && defined(__APPLE__) #define JLONG_FORMAT "%ld" #define JLONG_FORMAT_W(width) "%" #width "ld" diff --git a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp index 536b79165ae..b9d25096cd5 100644 --- a/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp +++ b/src/hotspot/share/utilities/globalDefinitions_visCPP.hpp @@ -85,8 +85,6 @@ inline int g_isnan(jdouble f) { return _isnan(f); } inline int g_isfinite(jfloat f) { return _finite(f); } inline int g_isfinite(jdouble f) { return _finite(f); } -#define offset_of(klass,field) offsetof(klass,field) - #define THREAD_LOCAL __declspec(thread) // Inlining support