From 649f34ae24fc67ebb67def6a29ca80d40ef9e637 Mon Sep 17 00:00:00 2001 From: Thierry Treyer Date: Wed, 10 Jan 2024 07:07:47 -0800 Subject: [PATCH 1/3] Fix static_assert failure for zero-length array The recursive template implemented for `validate_size` does not support incomplete types, like zero-length array. By splitting the `validate_size` struct in two parts: 1. `validate_size_eq` that does the actual size check, and 2. `validate_size` that preserves the previous interface and inherit from `validate_size_eq`, we get the same interface and feature than previously, but without the recursive template that doesn't support incomplete types. --- oi/OITraceCode.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/oi/OITraceCode.cpp b/oi/OITraceCode.cpp index a1009002..323c83e3 100644 --- a/oi/OITraceCode.cpp +++ b/oi/OITraceCode.cpp @@ -160,15 +160,14 @@ template struct DummyAllocator : DummyAllocatorBase {}; -template -struct validate_size { +template +struct validate_size_eq { static constexpr bool value = true; static_assert(ExpectedSize == ActualSize); }; template -struct validate_size - : validate_size {}; +struct validate_size : validate_size_eq {}; template struct validate_offset { From 4d8506d9ff4e2203e535d9634e3f0eaf4da887e0 Mon Sep 17 00:00:00 2001 From: Thierry Treyer Date: Wed, 10 Jan 2024 08:14:30 -0800 Subject: [PATCH 2/3] Fix TreeBuilder processing of zero-length array TreeBuilder did not consider a zero-length array like a container and never read the array's sizeof stored in the data buffer, leading to a mismatch between bytes written vs read out of the buffer. Now, `TreeBuilder::isContainer` does consider zero-length array like a container and properly consume all the object sizes in the buffer. --- oi/TreeBuilder.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/oi/TreeBuilder.cpp b/oi/TreeBuilder.cpp index 954b293d..2ff1102a 100644 --- a/oi/TreeBuilder.cpp +++ b/oi/TreeBuilder.cpp @@ -378,9 +378,20 @@ uint64_t TreeBuilder::next() { } bool TreeBuilder::isContainer(const Variable& variable) { - return th->containerTypeMap.contains(variable.type) || - (drgn_type_kind(variable.type) == DRGN_TYPE_ARRAY && - drgn_type_length(variable.type) > 0); + if (th->containerTypeMap.contains(variable.type)) { + return true; + } + + if (drgn_type_kind(variable.type) == DRGN_TYPE_ARRAY) { + /* CodeGen v1 does not consider zero-length array as containers, + * but CodeGen v2 does. This discrepancy is handled here. + * TODO: Cleanup this workaround once CodeGen v1 is gone. See #453 + */ + return config.features[Feature::TypeGraph] || + drgn_type_length(variable.type) > 0; + } + + return false; } bool TreeBuilder::isPrimitive(struct drgn_type* type) { From 6a26f9ae8ed39713f1a31ccf74dc90c41c0deaff Mon Sep 17 00:00:00 2001 From: Thierry Treyer Date: Wed, 10 Jan 2024 08:49:39 -0800 Subject: [PATCH 3/3] Enable test arrays_member_int0 --- test/integration/arrays.toml | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/test/integration/arrays.toml b/test/integration/arrays.toml index 5074b624..25e542a4 100644 --- a/test/integration/arrays.toml +++ b/test/integration/arrays.toml @@ -42,10 +42,6 @@ definitions = ''' "capacity":10 }]}]''' [cases.member_int0] - oil_skip = 'zero length arrays fail codegen v2' # https://github.com/facebookexperimental/object-introspection/issues/295 - # WARNING: zero-length arrays are handled differently to non-empty arrays. - # They end up not being treated as containers. This should probably change - # in the future. param_types = ["const Foo0&"] setup = "return {};" expect_json = '''[{ @@ -56,13 +52,13 @@ definitions = ''' "dynamicSize":0 }]}]''' expect_json_v2 = '''[{ - "staticSize":1, - "exclusiveSize":1, - "size":1, + "staticSize":0, + "exclusiveSize":0, + "size":0, "members":[{ "staticSize":0, "exclusiveSize":0, - "size":1 + "size":0 }]}]''' [cases.multidim_legacy] # Test for legacy behaviour. Remove with OICodeGen oil_disable = 'oil only runs on codegen v2'