Browse Source

[spirv] fix invalid index of member in derived class (#2657)

When a derived struct inherits a base struct and the derived one has a
member function, accessing its member variable in the member function
emits an invalid index. This CL fixes it.
Jaebaek Seo 5 years ago
parent
commit
77a1b530ba

+ 6 - 2
tools/clang/lib/SPIRV/SpirvEmitter.cpp

@@ -6421,8 +6421,12 @@ const Expr *SpirvEmitter::collectArrayStructIndices(
     // If we are accessing a derived struct, we need to account for the number
     // of base structs, since they are placed as fields at the beginning of the
     // derived struct.
-    const uint32_t index = getNumBaseClasses(indexing->getBase()->getType()) +
-                           fieldDecl->getFieldIndex();
+    auto baseType = indexing->getBase()->getType();
+    if (baseType->isPointerType()) {
+      baseType = baseType->getPointeeType();
+    }
+    const uint32_t index =
+        getNumBaseClasses(baseType) + fieldDecl->getFieldIndex();
     if (rawIndex) {
       rawIndices->push_back(index);
     } else {

+ 21 - 0
tools/clang/test/CodeGenSPIRV/oo.inheritance.member.function.hlsl

@@ -0,0 +1,21 @@
+// Run: %dxc -T ps_6_0 -E main
+
+struct Base {
+    int a;
+};
+
+struct Derived : Base {
+    float b;
+
+// CHECK: %Derived_increase = OpFunction %void None
+// CHECK: %param_this = OpFunctionParameter %_ptr_Function_Derived
+// CHECK: OpLabel
+// CHECK: OpAccessChain %_ptr_Function_float %param_this %int_1
+
+    void increase() { ++b; }
+};
+
+void main() {
+  Derived foo;
+  foo.increase();
+}

+ 3 - 0
tools/clang/unittests/SPIRV/CodeGenSpirvTest.cpp

@@ -578,6 +578,9 @@ TEST_F(FileTest, MethodCallOnStaticVar) {
   runFileTest("oo.method.on-static-var.hlsl");
 }
 TEST_F(FileTest, Inheritance) { runFileTest("oo.inheritance.hlsl"); }
+TEST_F(FileTest, InheritanceMemberFunction) {
+  runFileTest("oo.inheritance.member.function.hlsl");
+}
 TEST_F(FileTest, InheritanceStageIOVS) {
   runFileTest("oo.inheritance.stage-io.vs.hlsl");
 }