소스 검색

Fix ternary operator for enum result type (#4838)

Note: existing path that limits operator to basic numeric types still allowed enum due to it being AR_TOBJ_BASIC, rather than using a new ArTypeObjectKind.
It's questionable whether this was intentional, but changing it would require another special case to allow enums, like exists for object types, and it might have other side effects as well.
Tex Riddell 2 년 전
부모
커밋
6caeb266ff
2개의 변경된 파일45개의 추가작업 그리고 2개의 파일을 삭제
  1. 9 2
      tools/clang/lib/Sema/SemaHLSL.cpp
  2. 36 0
      tools/clang/test/HLSLFileCheck/hlsl/operators/ternary-enum.hlsl

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

@@ -9855,8 +9855,15 @@ clang::QualType HLSLExternalSource::CheckVectorConditional(
     return QualType();
   }
 
-  // Here, element kind is combined with dimensions for result type.
-  ResultTy = NewSimpleAggregateType(AR_TOBJ_INVALID, resultElementKind, 0, rowCount, colCount)->getCanonicalTypeInternal();
+  // Here, element kind is combined with dimensions for primitive types.
+  if (IS_BASIC_PRIMITIVE(resultElementKind)) {
+    ResultTy = NewSimpleAggregateType(AR_TOBJ_INVALID, resultElementKind, 0, rowCount, colCount)->getCanonicalTypeInternal();
+  } else {
+    DXASSERT(rowCount == 1 && colCount == 1,
+             "otherwise, attempting to construct vector or matrix with "
+             "non-primitive component type");
+    ResultTy = ResultTy.getUnqualifiedType();
+  }
 
   // Cast condition to RValue
   if (Cond.get()->isLValue())

+ 36 - 0
tools/clang/test/HLSLFileCheck/hlsl/operators/ternary-enum.hlsl

@@ -0,0 +1,36 @@
+// RUN: %dxc -ast-dump -T vs_6_0 %s | FileCheck %s
+// RUN: %dxc -ast-dump -T vs_6_0 -HV 2021 %s | FileCheck %s
+// RUN: %dxc -ast-dump -T vs_6_0 -DCLASS %s | FileCheck %s
+// RUN: %dxc -ast-dump -T vs_6_0 -DCLASS -HV 2021 %s | FileCheck %s
+
+// CHECK: VarDecl
+// CHECK-SAME: referenced g_c 'const MyEnum' static cinit
+// CHECK-NEXT: ConditionalOperator
+// CHECK-SAME: 'MyEnum'
+// CHECK-NEXT: CXXBoolLiteralExpr
+// CHECK-SAME: 'bool' true
+// CHECK-NEXT: DeclRefExpr
+// CHECK-SAME: 'MyEnum' EnumConstant
+// CHECK-SAME: 'One' 'MyEnum'
+// CHECK-NEXT: DeclRefExpr
+// CHECK-SAME: 'MyEnum' EnumConstant
+// CHECK-SAME: 'Two' 'MyEnum'
+
+enum
+#ifdef CLASS
+  class
+#endif
+MyEnum {
+    One,
+    Two,
+};
+
+#ifdef CLASS
+static const MyEnum g_c = true ? MyEnum::One : MyEnum::Two;
+#else
+static const MyEnum g_c = true ? One : Two;
+#endif
+
+int main() : OUT {
+  return (int)g_c;
+}