From 09a9d673322ebf4ca2fcb7d48f13a44e015ea33f Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 9 Dec 2024 04:48:03 -0800 Subject: Allow pointers to existential values. (#5793) * Fix pointer offset logic and add executable tests. * Fix. * Fix test. * Add existential ptr test. * Allow pointers to existential values. * Fix. * Fix. --------- Co-authored-by: Ellie Hermaszewska --- source/slang/slang-check-expr.cpp | 47 +++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 12 deletions(-) (limited to 'source/slang/slang-check-expr.cpp') diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index 2840cdd39..1f2776ba0 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -2307,7 +2307,10 @@ Expr* SemanticsVisitor::CheckSimpleSubscriptExpr(IndexExpr* subscriptExpr, Type* Expr* SemanticsExprVisitor::visitIndexExpr(IndexExpr* subscriptExpr) { bool needDeref = false; - auto baseExpr = checkBaseForMemberExpr(subscriptExpr->baseExpression, needDeref); + auto baseExpr = checkBaseForMemberExpr( + subscriptExpr->baseExpression, + CheckBaseContext::Subscript, + needDeref); // If the base expression is a type, it means that this is an array declaration, // then we should disable short-circuit in case there is logical expression in @@ -2951,7 +2954,10 @@ Expr* SemanticsExprVisitor::visitInvokeExpr(InvokeExpr* expr) auto operatorName = getName("()"); bool needDeref = false; - expr->functionExpr = maybeInsertImplicitOpForMemberBase(expr->functionExpr, needDeref); + expr->functionExpr = maybeInsertImplicitOpForMemberBase( + expr->functionExpr, + CheckBaseContext::Member, + needDeref); LookupResult lookupResult = lookUpMember( m_astBuilder, @@ -4060,19 +4066,29 @@ void SemanticsExprVisitor::maybeCheckKnownBuiltinInvocation(Expr* invokeExpr) } } -Expr* SemanticsVisitor::MaybeDereference(Expr* inExpr) +Expr* SemanticsVisitor::maybeDereference(Expr* inExpr, CheckBaseContext checkBaseContext) { Expr* expr = inExpr; for (;;) { auto baseType = expr->type; + QualType elementType; if (auto pointerLikeType = as(baseType)) { - auto elementType = QualType(pointerLikeType->getElementType()); + elementType = QualType(pointerLikeType->getElementType()); elementType.isLeftValue = baseType.isLeftValue; elementType.hasReadOnlyOnTarget = baseType.hasReadOnlyOnTarget; elementType.isWriteOnly = baseType.isWriteOnly; - + } + else if (auto ptrType = as(baseType)) + { + if (checkBaseContext == CheckBaseContext::Subscript) + return expr; + elementType = QualType(ptrType->getValueType()); + elementType.isLeftValue = true; + } + if (elementType.type) + { auto derefExpr = m_astBuilder->create(); derefExpr->base = expr; derefExpr->type = elementType; @@ -4080,7 +4096,6 @@ Expr* SemanticsVisitor::MaybeDereference(Expr* inExpr) expr = derefExpr; continue; } - // Default case: just use the expression as-is return expr; } @@ -4751,7 +4766,7 @@ Expr* SemanticsExprVisitor::visitStaticMemberExpr(StaticMemberExpr* expr) expr->baseExpression = CheckTerm(expr->baseExpression); // Not sure this is needed -> but guess someone could do - expr->baseExpression = MaybeDereference(expr->baseExpression); + expr->baseExpression = maybeDereference(expr->baseExpression, CheckBaseContext::Member); // If the base of the member lookup has an interface type // *without* a suitable this-type substitution, then we are @@ -4779,9 +4794,12 @@ Expr* SemanticsVisitor::lookupMemberResultFailure( return expr; } -Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase(Expr* baseExpr, bool& outNeedDeref) +Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase( + Expr* baseExpr, + CheckBaseContext checkBaseContext, + bool& outNeedDeref) { - auto derefExpr = MaybeDereference(baseExpr); + auto derefExpr = maybeDereference(baseExpr, checkBaseContext); if (derefExpr != baseExpr) outNeedDeref = true; @@ -4834,11 +4852,15 @@ Expr* SemanticsVisitor::maybeInsertImplicitOpForMemberBase(Expr* baseExpr, bool& return baseExpr; } -Expr* SemanticsVisitor::checkBaseForMemberExpr(Expr* inBaseExpr, bool& outNeedDeref) +Expr* SemanticsVisitor::checkBaseForMemberExpr( + Expr* inBaseExpr, + CheckBaseContext checkBaseContext, + bool& outNeedDeref) { auto baseExpr = inBaseExpr; baseExpr = CheckTerm(baseExpr); - return maybeInsertImplicitOpForMemberBase(baseExpr, outNeedDeref); + + return maybeInsertImplicitOpForMemberBase(baseExpr, checkBaseContext, outNeedDeref); } Expr* SemanticsVisitor::checkGeneralMemberLookupExpr(MemberExpr* expr, Type* baseType) @@ -4861,7 +4883,8 @@ Expr* SemanticsVisitor::checkGeneralMemberLookupExpr(MemberExpr* expr, Type* bas Expr* SemanticsExprVisitor::visitMemberExpr(MemberExpr* expr) { bool needDeref = false; - expr->baseExpression = checkBaseForMemberExpr(expr->baseExpression, needDeref); + expr->baseExpression = + checkBaseForMemberExpr(expr->baseExpression, CheckBaseContext::Member, needDeref); if (!needDeref && as(expr) && !as(expr->baseExpression->type)) { -- cgit v1.2.3