From 21a66267c661a55c8ad27248c0765276dd6f72ea Mon Sep 17 00:00:00 2001 From: Gangzheng Tong Date: Tue, 15 Jul 2025 16:39:22 -0700 Subject: Emit additional diagnostic for invalid pointer taking operations (#7663) * Emit special diagnostic for invalid pointer taking operations * Update source/slang/slang-diagnostic-defs.h Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> * Add OperatorAddressOf KnownBuiltin modifier * update error message for non-l-value assignment * update the diagnostics in the tests * Use enum based KnownBuiltinDeclName * format code (#7772) Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --------- Co-authored-by: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Co-authored-by: slangbot Co-authored-by: slangbot <186143334+slangbot@users.noreply.github.com> --- source/slang/slang-check-expr.cpp | 49 +++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 17 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 9325eda61..41c3bd510 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -2663,7 +2663,7 @@ Expr* SemanticsExprVisitor::visitTupleExpr(TupleExpr* expr) return expr; } -void SemanticsVisitor::maybeDiagnoseThisNotLValue(Expr* expr) +void SemanticsVisitor::maybeDiagnoseConstVariableAssignment(Expr* expr) { // We will try to handle expressions of the form: // @@ -2688,15 +2688,11 @@ void SemanticsVisitor::maybeDiagnoseThisNotLValue(Expr* expr) break; } } - // - // Now we check to see if we have a `this` expression, - // and if it is immutable. - if (auto thisExpr = as(e)) + + // Check if we're trying to assign to a non-l-value (const variable, immutable member, etc.) + if (!expr->type.isLeftValue) { - if (!thisExpr->type.isLeftValue) - { - getSink()->diagnoseWithoutSourceView(thisExpr, Diagnostics::thisIsImmutableByDefault); - } + getSink()->diagnoseWithoutSourceView(expr, Diagnostics::attemptingToAssignToConstVariable); } } @@ -2722,14 +2718,10 @@ Expr* SemanticsVisitor::checkAssignWithCheckedOperands(AssignExpr* expr) } else { - getSink()->diagnose(expr, Diagnostics::assignNonLValue); + // Provide a more helpful diagnostic about const variable assignment + maybeDiagnoseConstVariableAssignment(expr->left); - // As a special case, check if the LHS expression is derived - // from a `this` parameter (implicitly or explicitly), which - // is immutable. We can give the user a bit more context into - // what is going on. - // - maybeDiagnoseThisNotLValue(expr->left); + getSink()->diagnose(expr, Diagnostics::assignNonLValue); } } expr->type = type; @@ -2963,6 +2955,29 @@ Expr* SemanticsVisitor::CheckInvokeExprWithCheckedOperands(InvokeExpr* expr) } else if (!as(argExpr->type)) { + // Emit additional diagnostic for invalid pointer taking operations + auto funcDeclRef = getDeclRef(m_astBuilder, funcDeclRefExpr); + if (funcDeclRef) + { + auto knownBuiltinAttr = + funcDeclRef.getDecl() + ->findModifier(); + if (knownBuiltinAttr) + { + if (auto constantIntVal = + as(knownBuiltinAttr->name)) + { + if (constantIntVal->getValue() == + (int)KnownBuiltinDeclName::OperatorAddressOf) + { + getSink()->diagnose( + argExpr, + Diagnostics::cannotTakeConstantPointers); + } + } + } + } + getSink()->diagnose( argExpr, Diagnostics::argumentExpectedLValue, @@ -3000,7 +3015,7 @@ Expr* SemanticsVisitor::CheckInvokeExprWithCheckedOperands(InvokeExpr* expr) implicitCastExpr->type); } - maybeDiagnoseThisNotLValue(argExpr); + maybeDiagnoseConstVariableAssignment(argExpr); } } } -- cgit v1.2.3