8300080: offset_of for GCC/Clang exhibits undefined behavior and is not always a compile-time constant

Reviewed-by: stefank, jsjolen
This commit is contained in:
Kim Barrett 2025-09-04 05:42:18 +00:00
parent 90a2db1ecb
commit 62bc7b7c42
4 changed files with 6 additions and 21 deletions

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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