Zero safe_union padding.
After discriminator and after the inner union.
This also adds some runtime sanity checks for the accuracy of the
computed padding in various situations.
Bug: 131356202
Test: HIDL's run_all_device_tests.sh
Change-Id: I589d496772a4d0cc6c0e1364de485d4fef9354fc
Merged-In: I589d496772a4d0cc6c0e1364de485d4fef9354fc
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 6f75d7c..0970148 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -1143,14 +1143,25 @@
<< fullName()
<< ", hidl_d) == 0, \"wrong offset\");\n";
+ const CompoundLayout layout = getCompoundAlignmentAndSize();
+
if (!containsPointer()) {
- CompoundLayout layout = getCompoundAlignmentAndSize();
- out << "static_assert(offsetof("
- << fullName()
- << ", hidl_u) == "
- << layout.innerStruct.offset
- << ", \"wrong offset\");\n";
+ out << "static_assert(offsetof(" << fullName()
+ << ", hidl_u) == " << layout.innerStruct.offset << ", \"wrong offset\");\n";
}
+
+ out.endl();
+
+ // union itself is zero'd when set
+ // padding after descriminator
+ size_t dpad = layout.innerStruct.offset - layout.discriminator.size;
+ emitPaddingZero(out, layout.discriminator.size /*offset*/, dpad /*size*/);
+
+ size_t innerStructEnd = layout.innerStruct.offset + layout.innerStruct.size;
+ // final padding of the struct
+ size_t fpad = layout.overall.size - innerStructEnd;
+ emitPaddingZero(out, innerStructEnd /*offset*/, fpad /*size*/);
+
out.endl();
CHECK(!mFields->empty());
@@ -2224,20 +2235,35 @@
innerStruct.offset += Layout::getPad(innerStruct.offset,
innerStruct.align);
- overall.size = innerStruct.offset + innerStruct.size;
-
// An empty struct/union still occupies a byte of space in C++.
- if (overall.size == 0) {
- overall.size = 1;
+ if (innerStruct.size == 0) {
+ innerStruct.size = 1;
}
+ overall.size = innerStruct.offset + innerStruct.size;
+
// Pad the overall structure's size
overall.align = std::max(innerStruct.align, discriminator.align);
overall.size += Layout::getPad(overall.size, overall.align);
+ if (mStyle != STYLE_SAFE_UNION) {
+ CHECK(overall.offset == innerStruct.offset) << overall.offset << " " << innerStruct.offset;
+ CHECK(overall.align == innerStruct.align) << overall.align << " " << innerStruct.align;
+ CHECK(overall.size == innerStruct.size) << overall.size << " " << innerStruct.size;
+ }
+
return compoundLayout;
}
+void CompoundType::emitPaddingZero(Formatter& out, size_t offset, size_t size) const {
+ if (size > 0) {
+ out << "::std::memset(reinterpret_cast<uint8_t*>(this) + " << offset << ", 0, " << size
+ << ");\n";
+ } else {
+ out << "// no padding to zero starting at offset " << offset << "\n";
+ }
+}
+
std::unique_ptr<ScalarType> CompoundType::getUnionDiscriminatorType() const {
static const std::vector<std::pair<int, ScalarType::Kind> > scalars {
{8, ScalarType::Kind::KIND_UINT8},