diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-conversion.cpp | 80 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 15 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 20 | ||||
| -rw-r--r-- | source/slang/slang-check-impl.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-check-modifier.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-check-overload.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-check-stmt.cpp | 6 |
7 files changed, 89 insertions, 48 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp index a2cb0f91b..68e5df7ce 100644 --- a/source/slang/slang-check-conversion.cpp +++ b/source/slang/slang-check-conversion.cpp @@ -137,6 +137,7 @@ bool SemanticsVisitor::_readValueFromInitializerList( outToExpr, firstInitExpr->type, firstInitExpr, + getSink(), nullptr); } @@ -491,7 +492,14 @@ bool SemanticsVisitor::_readAggregateValueFromInitializerList( if (ioArgIndex < argCount) { auto arg = fromInitializerListExpr->args[ioArgIndex++]; - return _coerce(CoercionSite::Initializer, toType, outToExpr, arg->type, arg, nullptr); + return _coerce( + CoercionSite::Initializer, + toType, + outToExpr, + arg->type, + arg, + getSink(), + nullptr); } else { @@ -882,7 +890,7 @@ bool SemanticsVisitor::_coerceInitializerList( // composition this shouldn't fail. if (!as<InitializerListType>(fromInitializerListExpr->type) && !canCoerce(toType, fromInitializerListExpr->type, nullptr)) - return _failedCoercion(toType, outToExpr, fromInitializerListExpr); + return _failedCoercion(toType, outToExpr, fromInitializerListExpr, getSink()); // Try to invoke the user-defined constructor if it exists. This call will // report error diagnostics if the used-defined constructor exists but does not @@ -921,7 +929,11 @@ bool SemanticsVisitor::_coerceInitializerList( return true; } -bool SemanticsVisitor::_failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr) +bool SemanticsVisitor::_failedCoercion( + Type* toType, + Expr** outToExpr, + Expr* fromExpr, + DiagnosticSink* sink) { if (outToExpr) { @@ -936,7 +948,10 @@ bool SemanticsVisitor::_failedCoercion(Type* toType, Expr** outToExpr, Expr* fro } else { - getSink()->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type); + if (sink) + { + sink->diagnose(fromExpr->loc, Diagnostics::typeMismatch, toType, fromExpr->type); + } } } return false; @@ -1108,6 +1123,7 @@ bool SemanticsVisitor::_coerce( Expr** outToExpr, QualType fromType, Expr* fromExpr, + DiagnosticSink* sink, ConversionCost* outCost) { // If we are about to try and coerce an overloaded expression, @@ -1227,7 +1243,7 @@ bool SemanticsVisitor::_coerce( // if (!_canModifierBeAddedDuringCoercion(modifier)) { - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } } } @@ -1246,7 +1262,7 @@ bool SemanticsVisitor::_coerce( // if (!_canModifierBeDroppedDuringCoercion(modifier)) { - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } } } @@ -1425,7 +1441,7 @@ bool SemanticsVisitor::_coerce( // if (as<ParameterGroupType>(toType)) { - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } // We allow implicit conversion of a parameter group type like @@ -1451,7 +1467,7 @@ bool SemanticsVisitor::_coerce( derefExpr->checked = true; } - if (!_coerce(site, toType, outToExpr, fromElementType, derefExpr, &subCost)) + if (!_coerce(site, toType, outToExpr, fromElementType, derefExpr, sink, &subCost)) { return false; } @@ -1503,7 +1519,7 @@ bool SemanticsVisitor::_coerce( openRefExpr = maybeOpenRef(fromExpr); } - if (!_coerce(site, toType, outToExpr, fromValueType, openRefExpr, &subCost)) + if (!_coerce(site, toType, outToExpr, fromValueType, openRefExpr, sink, &subCost)) { return false; } @@ -1550,7 +1566,7 @@ bool SemanticsVisitor::_coerce( if (cachedMethod->conversionFuncOverloadCandidate.status != OverloadCandidate::Status::Applicable) { - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } overloadContext.bestCandidateStorage = cachedMethod->conversionFuncOverloadCandidate; overloadContext.bestCandidate = &overloadContext.bestCandidateStorage; @@ -1594,7 +1610,7 @@ bool SemanticsVisitor::_coerce( { getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{}); } - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } // If all of the candidates in `bestCandidates` are applicable, @@ -1622,7 +1638,10 @@ bool SemanticsVisitor::_coerce( // if (outToExpr) { - getSink()->diagnose(fromExpr, Diagnostics::ambiguousConversion, fromType, toType); + if (sink) + { + sink->diagnose(fromExpr, Diagnostics::ambiguousConversion, fromType, toType); + } *outToExpr = CreateErrorExpr(fromExpr); } @@ -1653,7 +1672,7 @@ bool SemanticsVisitor::_coerce( { getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{}); } - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } // Next, we need to look at the implicit conversion @@ -1675,12 +1694,15 @@ bool SemanticsVisitor::_coerce( { if (cost >= kConversionCost_Explicit) { - getSink()->diagnose(fromExpr, Diagnostics::typeMismatch, toType, fromType); - getSink()->diagnoseWithoutSourceView( - fromExpr, - Diagnostics::noteExplicitConversionPossible, - fromType, - toType); + if (sink) + { + sink->diagnose(fromExpr, Diagnostics::typeMismatch, toType, fromType); + sink->diagnoseWithoutSourceView( + fromExpr, + Diagnostics::noteExplicitConversionPossible, + fromType, + toType); + } } else if (cost >= kConversionCost_Default) { @@ -1704,9 +1726,9 @@ bool SemanticsVisitor::_coerce( } } } - if (shouldEmitGeneralWarning) + if (shouldEmitGeneralWarning && sink) { - getSink()->diagnose( + sink->diagnose( fromExpr, Diagnostics::unrecommendedImplicitConversion, fromType, @@ -1714,14 +1736,14 @@ bool SemanticsVisitor::_coerce( } } - if (site == CoercionSite::Argument) + if (site == CoercionSite::Argument && sink) { auto builtinConversionKind = getImplicitConversionBuiltinKind( overloadContext.bestCandidate->item.declRef.getDecl()); if (builtinConversionKind == kBuiltinConversion_FloatToDouble) { if (!as<FloatingPointLiteralExpr>(fromExpr)) - getSink()->diagnose(fromExpr, Diagnostics::implicitConversionToDouble); + sink->diagnose(fromExpr, Diagnostics::implicitConversionToDouble); } } } @@ -1788,7 +1810,7 @@ bool SemanticsVisitor::_coerce( { getShared()->cacheImplicitCastMethod(implicitCastKey, ImplicitCastMethod{}); } - return _failedCoercion(toType, outToExpr, fromExpr); + return _failedCoercion(toType, outToExpr, fromExpr, sink); } bool SemanticsVisitor::canCoerce( @@ -1830,7 +1852,7 @@ bool SemanticsVisitor::canCoerce( // which suppresses emission of any diagnostics // during the coercion process. // - bool rs = _coerce(CoercionSite::General, toType, nullptr, fromType, fromExpr, &cost); + bool rs = _coerce(CoercionSite::General, toType, nullptr, fromType, fromExpr, getSink(), &cost); if (outCost) *outCost = cost; @@ -1887,10 +1909,14 @@ Expr* SemanticsVisitor::createModifierCastExpr(Type* toType, Expr* fromExpr) } -Expr* SemanticsVisitor::coerce(CoercionSite site, Type* toType, Expr* fromExpr) +Expr* SemanticsVisitor::coerce( + CoercionSite site, + Type* toType, + Expr* fromExpr, + DiagnosticSink* sink) { Expr* expr = nullptr; - if (!_coerce(site, toType, &expr, fromExpr->type, fromExpr, nullptr)) + if (!_coerce(site, toType, &expr, fromExpr->type, fromExpr, sink, nullptr)) { // Note(tfoley): We don't call `CreateErrorExpr` here, because that would // clobber the type on `fromExpr`, and an invariant here is that coercion diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index c2c0c2cb6..bdd59c2c5 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -1868,7 +1868,8 @@ void SemanticsDeclHeaderVisitor::checkVarDeclCommon(VarDeclBase* varDecl) if (auto initExpr = varDecl->initExpr) { initExpr = CheckTerm(initExpr); - initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr); + initExpr = + coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr, getSink()); varDecl->initExpr = initExpr; maybeInferArraySizeForVariable(varDecl); @@ -2348,7 +2349,7 @@ void SemanticsDeclBodyVisitor::checkVarDeclCommon(VarDeclBase* varDecl) if (initExpr->type.isWriteOnly) getSink()->diagnose(initExpr, Diagnostics::readingFromWriteOnly); - initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr); + initExpr = coerce(CoercionSite::Initializer, varDecl->type.Ptr(), initExpr, getSink()); varDecl->initExpr = initExpr; // We need to ensure that any variable doesn't introduce @@ -4948,7 +4949,7 @@ bool SemanticsVisitor::trySynthesizeMethodRequirementWitness( // so we also need to coerce the result of the call to // the expected type. // - auto coercedCall = subVisitor.coerce(CoercionSite::Return, resultType, checkedCall); + auto coercedCall = subVisitor.coerce(CoercionSite::Return, resultType, checkedCall, getSink()); // If our overload resolution or type coercion failed, // then we have not been able to synthesize a witness @@ -5803,7 +5804,7 @@ bool SemanticsVisitor::synthesizeAccessorRequirements( // the expected type of the property. // auto coercedMemberRef = - subVisitor.coerce(CoercionSite::Return, resultType, synBoundStorageExpr); + subVisitor.coerce(CoercionSite::Return, resultType, synBoundStorageExpr, getSink()); auto synReturn = m_astBuilder->create<ReturnStmt>(); synReturn->expression = coercedMemberRef; @@ -8092,7 +8093,7 @@ void SemanticsDeclBodyVisitor::visitEnumCaseDecl(EnumCaseDecl* decl) if (auto initExpr = decl->tagExpr) { initExpr = CheckTerm(initExpr); - initExpr = coerce(CoercionSite::General, tagType, initExpr); + initExpr = coerce(CoercionSite::General, tagType, initExpr, getSink()); // We want to enforce that this is an integer constant // expression. @@ -9139,7 +9140,7 @@ void SemanticsDeclBodyVisitor::visitParamDecl(ParamDecl* paramDecl) // actual type of the parameter. // initExpr = CheckTerm(initExpr); - initExpr = coerce(CoercionSite::Initializer, typeExpr.type, initExpr); + initExpr = coerce(CoercionSite::Initializer, typeExpr.type, initExpr, getSink()); paramDecl->initExpr = initExpr; // TODO: a default argument expression needs to @@ -9284,7 +9285,7 @@ void SemanticsDeclBodyVisitor::synthesizeCtorBodyForBases( invoke->arguments.addRange(argumentList); auto assign = m_astBuilder->create<AssignExpr>(); - assign->left = coerce(CoercionSite::Initializer, declRefType, thisExpr); + assign->left = coerce(CoercionSite::Initializer, declRefType, thisExpr, getSink()); assign->right = invoke; auto stmt = m_astBuilder->create<ExpressionStmt>(); diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index d151d37be..41f945763 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -518,7 +518,11 @@ Expr* SemanticsVisitor::constructDerefExpr(Expr* base, QualType elementType, Sou { if (auto resPtrType = as<DescriptorHandleType>(base->type)) { - return coerce(CoercionSite::ExplicitCoercion, resPtrType->getElementType(), base); + return coerce( + CoercionSite::ExplicitCoercion, + resPtrType->getElementType(), + base, + getSink()); } auto derefExpr = m_astBuilder->create<DerefExpr>(); @@ -2254,7 +2258,7 @@ IntVal* SemanticsVisitor::CheckIntegerConstantExpression( switch (coercionType) { case IntegerConstantExpressionCoercionType::SpecificType: - expr = coerce(CoercionSite::General, expectedType, inExpr); + expr = coerce(CoercionSite::General, expectedType, inExpr, sink); break; case IntegerConstantExpressionCoercionType::AnyInteger: if (isScalarIntegerType(inExpr->type)) @@ -2262,7 +2266,7 @@ IntVal* SemanticsVisitor::CheckIntegerConstantExpression( else if (isEnumType(inExpr->type)) expr = inExpr; else - expr = coerce(CoercionSite::General, m_astBuilder->getIntType(), inExpr); + expr = coerce(CoercionSite::General, m_astBuilder->getIntType(), inExpr, sink); break; default: break; @@ -2527,7 +2531,7 @@ Expr* SemanticsVisitor::checkAssignWithCheckedOperands(AssignExpr* expr) type = atomicType->getElementType(); } auto right = maybeOpenRef(expr->right); - expr->right = coerce(CoercionSite::Assignment, type, right); + expr->right = coerce(CoercionSite::Assignment, type, right, getSink()); if (!expr->left->type.isLeftValue) { @@ -2956,7 +2960,7 @@ Expr* SemanticsExprVisitor::convertToLogicOperatorExpr(InvokeExpr* expr) // to handle if this expression doesn't support short-circuiting. for (auto& arg : expr->arguments) { - arg = coerce(CoercionSite::Argument, m_astBuilder->getBoolType(), arg); + arg = coerce(CoercionSite::Argument, m_astBuilder->getBoolType(), arg, getSink()); } expr->functionExpr = CheckTerm(expr->functionExpr); @@ -3920,7 +3924,11 @@ Expr* SemanticsExprVisitor::visitTypeCastExpr(TypeCastExpr* expr) auto checkedInitListExpr = visitInitializerListExpr(initListExpr); - return coerce(CoercionSite::General, typeExp.type, checkedInitListExpr); + return coerce( + CoercionSite::General, + typeExp.type, + checkedInitListExpr, + getSink()); } } } diff --git a/source/slang/slang-check-impl.h b/source/slang/slang-check-impl.h index 6c9a0409d..f0884503f 100644 --- a/source/slang/slang-check-impl.h +++ b/source/slang/slang-check-impl.h @@ -1646,7 +1646,7 @@ public: InitializerListExpr* fromInitializerListExpr); /// Report that implicit type coercion is not possible. - bool _failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr); + bool _failedCoercion(Type* toType, Expr** outToExpr, Expr* fromExpr, DiagnosticSink* sink); /// Central engine for implementing implicit coercion logic /// @@ -1674,6 +1674,7 @@ public: Expr** outToExpr, QualType fromType, Expr* fromExpr, + DiagnosticSink* sink, ConversionCost* outCost); /// Check whether implicit type coercion from `fromType` to `toType` is possible. @@ -1698,7 +1699,7 @@ public: Expr* createCastToInterfaceExpr(Type* toType, Expr* fromExpr, Val* witness); /// Implicitly coerce `fromExpr` to `toType` and diagnose errors if it isn't possible - Expr* coerce(CoercionSite site, Type* toType, Expr* fromExpr); + Expr* coerce(CoercionSite site, Type* toType, Expr* fromExpr, DiagnosticSink* sink); // Fill in default substitutions for the 'subtype' part of a type constraint decl void CheckConstraintSubType(TypeExp& typeExp); diff --git a/source/slang/slang-check-modifier.cpp b/source/slang/slang-check-modifier.cpp index cebcbe540..f9ad3a02f 100644 --- a/source/slang/slang-check-modifier.cpp +++ b/source/slang/slang-check-modifier.cpp @@ -828,7 +828,7 @@ Modifier* SemanticsVisitor::validateAttribute( if (!typeChecked) { arg = CheckTerm(arg); - arg = coerce(CoercionSite::Argument, paramDecl->getType(), arg); + arg = coerce(CoercionSite::Argument, paramDecl->getType(), arg, getSink()); } } paramIndex++; diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index 44fdf45cf..f13f9a99e 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -481,7 +481,11 @@ bool SemanticsVisitor::TryCheckGenericOverloadCandidateTypes( } else { - arg = coerce(CoercionSite::Argument, getType(m_astBuilder, valParamRef), arg); + arg = coerce( + CoercionSite::Argument, + getType(m_astBuilder, valParamRef), + arg, + getSink()); } // If we have an argument to work with, then we will @@ -712,7 +716,7 @@ bool SemanticsVisitor::TryCheckOverloadCandidateTypes( } else { - Expr* coercedExpr = coerce(CoercionSite::Argument, paramType, arg.argExpr); + Expr* coercedExpr = coerce(CoercionSite::Argument, paramType, arg.argExpr, getSink()); // Check if concrete-to-interface coercion caused loss of l-valueness. if (coercedExpr && !coercedExpr->type.isLeftValue && paramType.isLeftValue && @@ -2650,6 +2654,7 @@ Expr* SemanticsVisitor::ResolveInvoke(InvokeExpr* expr) &resultExpr, expr->arguments[0]->type, expr->arguments[0], + &tempSink, &conversionCost); if (coerceResult) return resultExpr; diff --git a/source/slang/slang-check-stmt.cpp b/source/slang/slang-check-stmt.cpp index 0e5ed92aa..2dc8c2685 100644 --- a/source/slang/slang-check-stmt.cpp +++ b/source/slang/slang-check-stmt.cpp @@ -255,7 +255,7 @@ Expr* SemanticsVisitor::checkPredicateExpr(Expr* expr) } Expr* e = expr; e = CheckTerm(e); - e = coerce(CoercionSite::General, m_astBuilder->getBoolType(), e); + e = coerce(CoercionSite::General, m_astBuilder->getBoolType(), e, getSink()); return e; } @@ -408,7 +408,7 @@ void SemanticsStmtVisitor::visitCaseStmt(CaseStmt* stmt) // Check that the type for the `case` is consistent with the type for the `switch`. auto expr = CheckExpr(stmt->expr); - expr = coerce(CoercionSite::Argument, switchStmt->condition->type, expr); + expr = coerce(CoercionSite::Argument, switchStmt->condition->type, expr, getSink()); // coerce to type being switch on, and ensure that value is a compile-time constant // The Vals in the AST are pointer-unique, making them easy to check for duplicates @@ -574,7 +574,7 @@ void SemanticsStmtVisitor::visitReturnStmt(ReturnStmt* stmt) if (!m_parentLambdaExpr && expectedReturnType) { stmt->expression = - coerce(CoercionSite::Return, expectedReturnType, stmt->expression); + coerce(CoercionSite::Return, expectedReturnType, stmt->expression, getSink()); } } } |
