From 8c68434d6fa6ff1b2e54586637869cceace9d1bb Mon Sep 17 00:00:00 2001 From: Tim Foley Date: Fri, 25 Aug 2017 15:18:10 -0700 Subject: Fix some resources-in-structs bugs Fixes #171 Fixes #172 These two bugs related to bad logic in handling of splitting resource-containing `cbuffer` declarations. - Issue #171 was the case where a `cbuffer` *only* had resource fields, in which case we crashed whenever referencing any field (some code was assuming there had to be non-resource fields) - Issue #172 was a case where two fields were declared with a single declaration (`Texture2D a, b;`), and the logic we had for tracking resource-type fields was accidentally tagging *both* fields with a single modifier so that field `b` would get confused for `a` in some contexts, and attempts to access `b` would crash. Both issues are now fixed, and regression tests have been added. --- source/slang/lower.cpp | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source/slang/lower.cpp') diff --git a/source/slang/lower.cpp b/source/slang/lower.cpp index 70c153902..a1b6dcf17 100644 --- a/source/slang/lower.cpp +++ b/source/slang/lower.cpp @@ -308,6 +308,11 @@ struct LoweredExpr return (getFlavor() == Flavor::VaryingTuple) ? getVaryingTupleExpr() : nullptr; } + bool operator!() + { + return !value; + } + private: RefPtr value; Flavor flavor; @@ -1820,6 +1825,12 @@ struct LoweringVisitor baseTuple->primaryExpr = loweredPrimary; return baseTuple; } + else + { + // No primary expression? Then there is nothing + // to dereference. + return baseTuple; + } } else if (auto baseVaryingTuple = loweredBase.asVaryingTuple()) { @@ -1847,8 +1858,16 @@ struct LoweringVisitor LoweredExpr visitMemberExpr( MemberExpr* expr) { + assert(expr->BaseExpression); auto loweredBase = lowerExprOrTuple(expr->BaseExpression); + if( !loweredBase ) + { + loweredBase = lowerExprOrTuple(expr->BaseExpression); + } + + assert(loweredBase); + auto loweredDeclRef = translateDeclRef(expr->declRef); @@ -1872,7 +1891,11 @@ struct LoweringVisitor } if (!tupleFieldMod->hasAnyNonTupleFields) + { + // We need to have found something! + assert(tupleFieldExpr); return tupleFieldExpr; + } auto tupleFieldTupleExpr = tupleFieldExpr.asTuple(); SLANG_RELEASE_ASSERT(tupleFieldTupleExpr); @@ -1885,6 +1908,8 @@ struct LoweringVisitor loweredPrimaryExpr->declRef = loweredDeclRef.As(); loweredPrimaryExpr->name = expr->name; + assert(loweredPrimaryExpr->BaseExpression); + tupleFieldTupleExpr->primaryExpr = loweredPrimaryExpr; return tupleFieldTupleExpr; } @@ -1892,6 +1917,7 @@ struct LoweringVisitor // If the field was a non-tuple field, then we can // simply fall through to the ordinary case below. loweredBase = LoweredExpr(baseTuple->primaryExpr); + assert(baseTuple->primaryExpr); } else if (auto baseVaryingTuple = loweredBase.asVaryingTuple()) { @@ -1901,6 +1927,7 @@ struct LoweringVisitor if (expr->declRef.getDecl() == elem.originalFieldDeclRef.getDecl()) { // We found the field! + assert(elem.expr); return elem.expr; } } @@ -1916,6 +1943,8 @@ struct LoweringVisitor loweredExpr->declRef = loweredDeclRef.As(); loweredExpr->name = expr->name; + assert(loweredExpr->BaseExpression); + return LoweredExpr(loweredExpr); } -- cgit v1.2.3