More stringently verify expected alignment of fields in hidl compound types.

Change-Id: I222d78163ac5d7cc5af405b0c3d0586ed7528213
Bug: 33846034
Test: make
diff --git a/ArrayType.cpp b/ArrayType.cpp
index b47ba3b..8b75c94 100644
--- a/ArrayType.cpp
+++ b/ArrayType.cpp
@@ -504,6 +504,10 @@
     return mElementType->isJavaCompatible();
 }
 
+bool ArrayType::containsPointer() const {
+    return mElementType->containsPointer();
+}
+
 void ArrayType::getAlignmentAndSize(size_t *align, size_t *size) const {
     mElementType->getAlignmentAndSize(align, size);
 
diff --git a/ArrayType.h b/ArrayType.h
index a0c2a08..ae58d28 100644
--- a/ArrayType.h
+++ b/ArrayType.h
@@ -125,6 +125,7 @@
     status_t emitVtsTypeDeclarations(Formatter &out) const override;
 
     bool isJavaCompatible() const override;
+    bool containsPointer() const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;
 
diff --git a/CompoundType.cpp b/CompoundType.cpp
index 19b1896..3d2a697 100644
--- a/CompoundType.cpp
+++ b/CompoundType.cpp
@@ -345,7 +345,7 @@
 
     Scope::emitTypeDeclarations(out);
 
-    if (!isJavaCompatible()) {
+    if (containsPointer()) {
         for (const auto &field : *mFields) {
             out << field->type().getCppStackType()
                 << " "
@@ -387,7 +387,9 @@
                     << ", \"wrong offset\");\n";
             }
 
-            offset += fieldSize;
+            if (mStyle == STYLE_STRUCT) {
+                offset += fieldSize;
+            }
         }
 
         if (pass == 0) {
@@ -1039,8 +1041,23 @@
     return true;
 }
 
+bool CompoundType::containsPointer() const {
+    if (Scope::containsPointer()) {
+        return true;
+    }
+
+    for (const auto &field : *mFields) {
+        if (field->type().containsPointer()) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 void CompoundType::getAlignmentAndSize(size_t *align, size_t *size) const {
     *align = 1;
+    *size = 0;
 
     size_t offset = 0;
     for (const auto &field : *mFields) {
@@ -1056,20 +1073,26 @@
             offset += fieldAlign - pad;
         }
 
-        offset += fieldSize;
+        if (mStyle == STYLE_STRUCT) {
+            offset += fieldSize;
+        } else {
+            *size = std::max(*size, fieldSize);
+        }
 
         if (fieldAlign > (*align)) {
             *align = fieldAlign;
         }
     }
 
-    // Final padding to account for the structure's alignment.
-    size_t pad = offset % (*align);
-    if (pad > 0) {
-        offset += (*align) - pad;
+    if (mStyle == STYLE_STRUCT) {
+        *size = offset;
     }
 
-    *size = offset;
+    // Final padding to account for the structure's alignment.
+    size_t pad = (*size) % (*align);
+    if (pad > 0) {
+        (*size) += (*align) - pad;
+    }
 
     if (*size == 0) {
         // An empty struct still occupies a byte of space in C++.
diff --git a/CompoundType.h b/CompoundType.h
index f761933..aa395ba 100644
--- a/CompoundType.h
+++ b/CompoundType.h
@@ -128,6 +128,7 @@
     status_t emitVtsAttributeType(Formatter &out) const override;
 
     bool isJavaCompatible() const override;
+    bool containsPointer() const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const;
 
diff --git a/FmqType.cpp b/FmqType.cpp
index 221a47a..989f613 100644
--- a/FmqType.cpp
+++ b/FmqType.cpp
@@ -137,6 +137,12 @@
     return false;
 }
 
+void FmqType::getAlignmentAndSize(
+        size_t *align, size_t *size) const {
+    *align = 8;  // MQDescriptor<>
+    *size = 32;
+}
+
 bool FmqType::needsEmbeddedReadWrite() const {
     return true;
 }
diff --git a/FmqType.h b/FmqType.h
index d243e55..d0ce997 100644
--- a/FmqType.h
+++ b/FmqType.h
@@ -56,6 +56,8 @@
 
     bool isJavaCompatible() const override;
 
+    void getAlignmentAndSize(size_t *align, size_t *size) const override;
+
     bool needsEmbeddedReadWrite() const override;
     bool resultNeedsDeref() const override;
     bool isCompatibleElementType(Type *elementType) const override;
diff --git a/HandleType.cpp b/HandleType.cpp
index 5c8059e..10c5f57 100644
--- a/HandleType.cpp
+++ b/HandleType.cpp
@@ -160,7 +160,8 @@
 }
 
 void HandleType::getAlignmentAndSize(size_t *align, size_t *size) const {
-    *align = *size = 8;
+    *align = 8;  // hidl_handle
+    *size = 16;
 }
 
 status_t HandleType::emitVtsTypeDeclarations(Formatter &out) const {
diff --git a/MemoryType.cpp b/MemoryType.cpp
index 3243cd4..614f368 100644
--- a/MemoryType.cpp
+++ b/MemoryType.cpp
@@ -141,7 +141,8 @@
 }
 
 void MemoryType::getAlignmentAndSize(size_t *align, size_t *size) const {
-    *align = *size = 8;
+    *align = 8;  // hidl_memory
+    *size = 40;
 }
 
 status_t MemoryType::emitVtsTypeDeclarations(Formatter &out) const {
diff --git a/PointerType.cpp b/PointerType.cpp
index 8349cfd..058141f 100644
--- a/PointerType.cpp
+++ b/PointerType.cpp
@@ -66,8 +66,8 @@
     return false;
 }
 
-void PointerType::getAlignmentAndSize(size_t *align, size_t *size) const {
-    *align = *size = 0; // this object should only be used in passthrough mode
+bool PointerType::containsPointer() const {
+    return true;
 }
 
 status_t PointerType::emitVtsTypeDeclarations(Formatter &out) const {
diff --git a/PointerType.h b/PointerType.h
index cd0f839..415ba9f 100644
--- a/PointerType.h
+++ b/PointerType.h
@@ -49,8 +49,7 @@
     bool resultNeedsDeref() const override;
 
     bool isJavaCompatible() const override;
-
-    void getAlignmentAndSize(size_t *align, size_t *size) const override;
+    bool containsPointer() const override;
 
     status_t emitVtsTypeDeclarations(Formatter &out) const override;
 };
diff --git a/RefType.cpp b/RefType.cpp
index 34aa224..f2a3f7d 100644
--- a/RefType.cpp
+++ b/RefType.cpp
@@ -245,5 +245,9 @@
     return false;
 }
 
+bool RefType::containsPointer() const {
+    return true;
+}
+
 }  // namespace android
 
diff --git a/RefType.h b/RefType.h
index 3c91316..8fd2668 100644
--- a/RefType.h
+++ b/RefType.h
@@ -70,6 +70,7 @@
     bool resultNeedsDeref() const override;
 
     bool isJavaCompatible() const override;
+    bool containsPointer() const override;
 
  private:
     DISALLOW_COPY_AND_ASSIGN(RefType);
diff --git a/Scope.cpp b/Scope.cpp
index df8651b..aad55c9 100644
--- a/Scope.cpp
+++ b/Scope.cpp
@@ -180,6 +180,16 @@
     return true;
 }
 
+bool Scope::containsPointer() const {
+    for (const auto &type : mTypes) {
+        if (type->containsPointer()) {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 void Scope::appendToExportedTypesVector(
         std::vector<const Type *> *exportedTypes) const {
     forEachType([&](Type *type) {
diff --git a/Scope.h b/Scope.h
index 0b34182..de53974 100644
--- a/Scope.h
+++ b/Scope.h
@@ -65,6 +65,7 @@
     status_t emitVtsTypeDeclarations(Formatter &out) const override;
 
     bool isJavaCompatible() const override;
+    bool containsPointer() const override;
 
     void appendToExportedTypesVector(
             std::vector<const Type *> *exportedTypes) const override;
diff --git a/Type.cpp b/Type.cpp
index 585afc9..8ad1ce5 100644
--- a/Type.cpp
+++ b/Type.cpp
@@ -450,8 +450,13 @@
     return true;
 }
 
-void Type::getAlignmentAndSize(size_t *, size_t *) const {
-    CHECK(!"Should not be here");
+void Type::getAlignmentAndSize(
+        size_t * /* align */, size_t * /* size */) const {
+    CHECK(!"Should not be here.");
+}
+
+bool Type::containsPointer() const {
+    return false;
 }
 
 void Type::appendToExportedTypesVector(
diff --git a/Type.h b/Type.h
index ce2a03a..80401a1 100644
--- a/Type.h
+++ b/Type.h
@@ -215,7 +215,7 @@
 
     // Returns true iff this type is supported through the Java backend.
     virtual bool isJavaCompatible() const;
-
+    virtual bool containsPointer() const;
     virtual void getAlignmentAndSize(size_t *align, size_t *size) const;
 
     void setAnnotations(std::vector<Annotation *> *annotations);
diff --git a/VectorType.cpp b/VectorType.cpp
index b6267c6..6a0542e 100644
--- a/VectorType.cpp
+++ b/VectorType.cpp
@@ -736,6 +736,10 @@
     return true;
 }
 
+bool VectorType::containsPointer() const {
+    return mElementType->containsPointer();
+}
+
 void VectorType::getAlignmentAndSize(size_t *align, size_t *size) const {
     *align = 8;  // hidl_vec<T>
     *size = 16;
diff --git a/VectorType.h b/VectorType.h
index c267ba9..73ce814 100644
--- a/VectorType.h
+++ b/VectorType.h
@@ -121,6 +121,7 @@
     bool resultNeedsDeref() const override;
 
     bool isJavaCompatible() const override;
+    bool containsPointer() const override;
 
     void getAlignmentAndSize(size_t *align, size_t *size) const override;