2
0
Эх сурвалжийг харах

Carry BasePath within CK_HLSLDerivedToBase casts (#1047)

This will enable us to trace back the whole base chain.
Lei Zhang 7 жил өмнө
parent
commit
9503f80c18

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

@@ -7058,7 +7058,13 @@ clang::ExprResult HLSLExternalSource::PerformHLSLConversion(
       break;
     }
     case ICK_HLSL_Derived_To_Base: {
-      From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_HLSLDerivedToBase, From->getValueKind(), /*BasePath=*/0, CCK).get();
+      CXXCastPath BasePath;
+      if (m_sema->CheckDerivedToBaseConversion(
+              sourceType, targetType.getNonReferenceType(), From->getLocStart(),
+              From->getSourceRange(), &BasePath, /*IgnoreAccess=*/true))
+        return ExprError();
+
+      From = m_sema->ImpCastExprToType(From, targetType.getUnqualifiedType(), CK_HLSLDerivedToBase, From->getValueKind(), &BasePath, CCK).get();
       break;
     }
     case ICK_HLSLVector_Splat: {
@@ -7672,7 +7678,13 @@ lSuccess:
     if (sourceExpr->isLValue())
     {
       if (needsLValueToRValue) {
-        standard->First = ICK_Lvalue_To_Rvalue;
+        // We don't need LValueToRValue cast before casting a derived object
+        // to its base.
+        if (Second == ICK_HLSL_Derived_To_Base) {
+          standard->First = ICK_Identity;
+        } else {
+          standard->First = ICK_Lvalue_To_Rvalue;
+        }
       } else {
         switch (Second)
         {

+ 62 - 0
tools/clang/test/HLSL/derived-to-base.hlsl

@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -ffreestanding -verify %s
+
+struct Base {
+    float4 a;
+    float4 b;
+};
+
+struct Derived : Base {
+    float4 b;
+    float4 c;
+};
+
+struct DerivedAgain : Derived {
+    float4 c;
+    float4 d;
+};
+
+float main() : A {
+    DerivedAgain da1, da2;
+
+    (Derived)da1 = (Derived)da2;
+    /*verify-ast
+      BinaryOperator <col:5, col:29> 'Derived' '='
+      |-CStyleCastExpr <col:5, col:14> 'Derived' lvalue <NoOp>
+      | `-ImplicitCastExpr <col:14> 'Derived' lvalue <HLSLDerivedToBase (Derived)>
+      |   `-DeclRefExpr <col:14> 'DerivedAgain' lvalue Var 'da1' 'DerivedAgain'
+      `-ImplicitCastExpr <col:20, col:29> 'Derived' <LValueToRValue>
+        `-CStyleCastExpr <col:20, col:29> 'Derived' lvalue <NoOp>
+          `-ImplicitCastExpr <col:29> 'Derived' lvalue <HLSLDerivedToBase (Derived)>
+            `-DeclRefExpr <col:29> 'DerivedAgain' lvalue Var 'da2' 'DerivedAgain'
+    */
+
+    (Base)da1    = (Base)da2;
+    /*verify-ast
+      BinaryOperator <col:5, col:26> 'Base' '='
+      |-CStyleCastExpr <col:5, col:11> 'Base' lvalue <NoOp>
+      | `-ImplicitCastExpr <col:11> 'Base' lvalue <HLSLDerivedToBase (Derived -> Base)>
+      |   `-DeclRefExpr <col:11> 'DerivedAgain' lvalue Var 'da1' 'DerivedAgain'
+      `-ImplicitCastExpr <col:20, col:26> 'Base' <LValueToRValue>
+        `-CStyleCastExpr <col:20, col:26> 'Base' lvalue <NoOp>
+          `-ImplicitCastExpr <col:26> 'Base' lvalue <HLSLDerivedToBase (Derived -> Base)>
+            `-DeclRefExpr <col:26> 'DerivedAgain' lvalue Var 'da2' 'DerivedAgain'
+    */
+
+    Derived d;
+
+    (Base)d      = (Base)da2;
+    /*verify-ast
+      BinaryOperator <col:5, col:26> 'Base' '='
+      |-CStyleCastExpr <col:5, col:11> 'Base' lvalue <NoOp>
+      | `-ImplicitCastExpr <col:11> 'Base' lvalue <HLSLDerivedToBase (Base)>
+      |   `-DeclRefExpr <col:11> 'Derived' lvalue Var 'd' 'Derived'
+      `-ImplicitCastExpr <col:20, col:26> 'Base' <LValueToRValue>
+        `-CStyleCastExpr <col:20, col:26> 'Base' lvalue <NoOp>
+          `-ImplicitCastExpr <col:26> 'Base' lvalue <HLSLDerivedToBase (Derived -> Base)>
+            `-DeclRefExpr <col:26> 'DerivedAgain' lvalue Var 'da2' 'DerivedAgain'
+    */
+
+    da1          = (DerivedAgain)d; // expected-error {{cannot convert from 'Derived' to 'DerivedAgain'}}
+
+    return 1.0;
+}

+ 5 - 0
tools/clang/unittests/HLSL/VerifierTest.cpp

@@ -68,6 +68,7 @@ public:
   TEST_METHOD(RunTypemodsSyntax);
   TEST_METHOD(RunSemantics);
   TEST_METHOD(RunImplicitCasts);
+  TEST_METHOD(RunDerivedToBaseCasts);
   TEST_METHOD(RunLiterals);
   TEST_METHOD(RunEffectsSyntax);
   TEST_METHOD(RunVectorConditional);
@@ -277,6 +278,10 @@ TEST_F(VerifierTest, RunImplicitCasts) {
   CheckVerifiesHLSL(L"implicit-casts.hlsl");
 }
 
+TEST_F(VerifierTest, RunDerivedToBaseCasts) {
+  CheckVerifiesHLSL(L"derived-to-base.hlsl");
+}
+
 TEST_F(VerifierTest, RunLiterals) {
   CheckVerifiesHLSL(L"literals.hlsl");
 }