浏览代码

Fixed some ConstantBuffer crashes. (#3427)

Adam Yang 4 年之前
父节点
当前提交
be5635eaa6

+ 2 - 0
tools/clang/lib/CodeGen/CGExprAgg.cpp

@@ -741,6 +741,8 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {
         LValue LV;
         if (DeclRefExpr *SrcDecl = dyn_cast<DeclRefExpr>(Src))
           LV = CGF.EmitLValue(SrcDecl);
+        else if (ArraySubscriptExpr *ArraySubExpr = dyn_cast<ArraySubscriptExpr>(Src))
+          LV = CGF.EmitLValue(ArraySubExpr);
         else
           LV = CGF.EmitAggExprToLValue(Src);
 

+ 2 - 1
tools/clang/lib/Sema/SemaHLSL.cpp

@@ -8674,7 +8674,8 @@ bool HLSLExternalSource::CanConvert(
   if ((SourceInfo.EltKind == AR_OBJECT_CONSTANT_BUFFER ||
        SourceInfo.EltKind == AR_OBJECT_TEXTURE_BUFFER) &&
       TargetInfo.ShapeKind == AR_TOBJ_COMPOUND) {
-    standard->Second = ICK_Flat_Conversion;
+    if (standard)
+      standard->Second = ICK_Flat_Conversion;
     return hlsl::GetHLSLResourceResultType(source) == target;
   }
 

+ 26 - 0
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/constantbuffer_array.hlsl

@@ -0,0 +1,26 @@
+// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+
+// Regression test for a crash when array subscript of ConstantBuffer<My_Struct>[]
+// is implicitly converted to T.
+
+// A temp `alloca ConstantBuffer<My_Struct>` was generated which couldn't be
+// cleaned up during codegen.
+
+// CHECK: %[[handle:.+]] = call %dx.types.Handle @dx.op.createHandle(i32 57, i8 2, i32 0, i32 3
+// CHECK: %[[cbufret:.+]] = call %dx.types.CBufRet.f32 @dx.op.cbufferLoadLegacy.f32(i32 59, %dx.types.Handle %[[handle]]
+// CHECK: %[[comp:.+]] = extractvalue %dx.types.CBufRet.f32 %[[cbufret]], 1
+
+struct My_Struct {
+  float a;
+  float b;
+  float c;
+  float d;
+};
+
+ConstantBuffer<My_Struct> my_cbuf[10];
+
+float main() : SV_Target {
+  My_Struct s = my_cbuf[3];
+  return s.b;
+}
+

+ 24 - 0
tools/clang/test/HLSLFileCheck/hlsl/objects/CbufferLegacy/constantbuffer_wrong_conversion.hlsl

@@ -0,0 +1,24 @@
+// RUN: %dxc -E main -T ps_6_0 %s | FileCheck %s
+
+// Regression test for a crash when array subscript of ConstantBuffer<T>
+// is assigned to a variable of a wrong type..
+
+// CHECK: error:
+
+struct My_Struct {
+  float a;
+  float b;
+  float c;
+  float d;
+};
+struct My_Struct2 {
+  float b;
+};
+
+ConstantBuffer<My_Struct> my_cbuf[10];
+
+float main() : SV_Target {
+  My_Struct2 s = my_cbuf[3];
+  return s.b;
+}
+