Переглянути джерело

Fix #604 by handling scalar functional inits in ICE and evaluation (#605)

Marcelo Lopez Ruiz 8 роки тому
батько
коміт
6322c8ca3f

+ 3 - 3
tools/clang/lib/AST/ExprConstant.cpp

@@ -4279,7 +4279,7 @@ public:
   bool VisitInitListExpr(const InitListExpr *E) {
   bool VisitInitListExpr(const InitListExpr *E) {
     if (E->getNumInits() == 0)
     if (E->getNumInits() == 0)
       return DerivedZeroInitialization(E);
       return DerivedZeroInitialization(E);
-    if (Info.getLangOpts().HLSL && !IsHLSLVecInitList(E)) return Error(E); // HLSL Change
+    if (Info.getLangOpts().HLSL && !E->getType()->isScalarType() && !IsHLSLVecInitList(E)) return Error(E); // HLSL Change
     if (E->getNumInits() == 1)
     if (E->getNumInits() == 1)
       return StmtVisitorTy::Visit(E->getInit(0));
       return StmtVisitorTy::Visit(E->getInit(0));
     return Error(E);
     return Error(E);
@@ -4323,7 +4323,7 @@ public:
     // HLSL Change Begins
     // HLSL Change Begins
     if (Info.getLangOpts().HLSL) {
     if (Info.getLangOpts().HLSL) {
       const auto* subExpr = E->getSubExpr();
       const auto* subExpr = E->getSubExpr();
-      if (subExpr->getStmtClass() == Stmt::InitListExprClass && !IsHLSLVecInitList(subExpr))
+      if (subExpr->getStmtClass() == Stmt::InitListExprClass && !IsHLSLVecInitList(subExpr) && !subExpr->getType()->isScalarType())
         return Error(E);
         return Error(E);
     }
     }
     // HLSL Change Ends
     // HLSL Change Ends
@@ -8915,7 +8915,7 @@ static ICEDiag CheckICE(const Expr* E, const ASTContext &Ctx) {
     // form "T x = { a };" is equivalent to "T x = a;".
     // form "T x = { a };" is equivalent to "T x = a;".
     // Unless we're initializing a reference, T is a scalar as it is known to be
     // Unless we're initializing a reference, T is a scalar as it is known to be
     // of integral or enumeration type.
     // of integral or enumeration type.
-    if (E->isRValue())
+    if (E->isRValue() && (!Ctx.getLangOpts().HLSL || E->getType()->isScalarType() || IsHLSLVecInitList(E))) // HLSL Change
       if (cast<InitListExpr>(E)->getNumInits() == 1)
       if (cast<InitListExpr>(E)->getNumInits() == 1)
         return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
         return CheckICE(cast<InitListExpr>(E)->getInit(0), Ctx);
     return ICEDiag(IK_NotICE, E->getLocStart());
     return ICEDiag(IK_NotICE, E->getLocStart());

+ 31 - 0
tools/clang/test/HLSL/const-expr.hlsl

@@ -350,5 +350,36 @@ void fn_const_eval() {
 //    (UINT)hlsl::IntrinsicOp::IOP_trunc, 2, g_Intrinsics_Args154,
 //    (UINT)hlsl::IntrinsicOp::IOP_trunc, 2, g_Intrinsics_Args154,
 }
 }
 
 
+//////////////////////////////////////////////////////////////////////////////
+// ICE.
+void fn_ice() {
+  // Scalar ints.
+  static uint s_One = 1;
+  static uint s_Two = uint(s_One) + 1;
+  float arr_s_One[s_One];    /* expected-error {{variable length arrays are not supported in HLSL}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+  float arr_s_Two[s_Two];    /* expected-error {{variable length arrays are not supported in HLSL}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+
+  static const uint sc_One = 1;
+  static const uint sc_Two = uint(sc_One) + 1;
+  float arr_sc_One[sc_One];
+  float arr_sc_Two[sc_Two];
+
+  // Vector ints.
+  static uint1 v_One = 1;
+  static uint1 v_Two = uint1(v_One) + 1;
+  float arr_v_One[v_One];    /* expected-error {{size of array has non-integer type 'uint1'}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+  float arr_v_Two[v_Two];    /* expected-error {{size of array has non-integer type 'uint1'}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+
+  static const uint1 vc_One = 1;
+  static const uint1 vc_Two = uint1(vc_One) + 1;
+  float arr_vc_One[vc_One];  /* expected-error {{size of array has non-integer type 'uint1'}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+  float arr_vc_Two[vc_Two];  /* expected-error {{size of array has non-integer type 'uint1'}} fxc-error {{X3058: array dimensions must be literal scalar expressions}} */
+
+  // Note: here dxc is different from fxc, where a const integral vector can be used in ICE.
+  // It would be desirable to have this supported.
+  float arr_vc_One[vc_One.x];  /* expected-error {{variable length arrays are not supported in HLSL}} */
+  float arr_vc_Two[vc_Two.x];  /* expected-error {{variable length arrays are not supported in HLSL}} */
+}
+
 void cs_main() {
 void cs_main() {
 }
 }