summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-check-conversion.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2025-07-22 08:47:50 -0700
committerGitHub <noreply@github.com>2025-07-22 15:47:50 +0000
commit52a45890b5ab71d7dbfdd01955afce129728d67e (patch)
tree141491e9c36cfa6a1a890765682d69ac4bfd2270 /source/slang/slang-check-conversion.cpp
parent0d26dbaad90f5eac604e148971d14e552bf9d5b8 (diff)
Fix crash when private ctor is used for coercion. (#7858)
* Fix crash when private ctor is used for coercion. * Fix tests. * Fix. * Fix test error.
Diffstat (limited to 'source/slang/slang-check-conversion.cpp')
-rw-r--r--source/slang/slang-check-conversion.cpp31
1 files changed, 26 insertions, 5 deletions
diff --git a/source/slang/slang-check-conversion.cpp b/source/slang/slang-check-conversion.cpp
index 3ace9f999..61d132627 100644
--- a/source/slang/slang-check-conversion.cpp
+++ b/source/slang/slang-check-conversion.cpp
@@ -346,6 +346,8 @@ Expr* SemanticsVisitor::_createCtorInvokeExpr(
auto* varExpr = getASTBuilder()->create<VarExpr>();
varExpr->type = (QualType)getASTBuilder()->getTypeType(toType);
varExpr->declRef = isDeclRefTypeOf<Decl>(toType);
+ varExpr->loc = loc;
+ varExpr->checked = true;
auto* constructorExpr = getASTBuilder()->create<ExplicitCtorInvokeExpr>();
constructorExpr->functionExpr = varExpr;
@@ -382,6 +384,8 @@ bool SemanticsVisitor::createInvokeExprForExplicitCtor(
fromInitializerListExpr->args);
DiagnosticSink tempSink(getSourceManager(), nullptr);
+ tempSink.setFlags(getSink()->getFlags());
+
SemanticsVisitor subVisitor(withSink(&tempSink));
ctorInvokeExpr = subVisitor.CheckTerm(ctorInvokeExpr);
@@ -395,6 +399,12 @@ bool SemanticsVisitor::createInvokeExprForExplicitCtor(
getSink()->diagnoseRaw(
Severity::Error,
static_cast<char const*>(blob->getBufferPointer()));
+ // For non-c-style types, we will always return true when there
+ // is a ctor, so that we do not fallback to legacy initializer list logic
+ // in `_coerceInitializerList()` and produce unrelated errors.
+ if (outExpr)
+ *outExpr = CreateErrorExpr(ctorInvokeExpr);
+ return true;
}
return false;
}
@@ -956,13 +966,13 @@ bool SemanticsVisitor::_coerceInitializerList(
}
// We will fall back to the legacy logic of initialize list.
+ Expr* outInitListExpr = nullptr;
if (!_readAggregateValueFromInitializerList(
toType,
- outToExpr,
+ &outInitListExpr,
fromInitializerListExpr,
argIndex))
return false;
-
if (argIndex != argCount)
{
if (outToExpr)
@@ -974,6 +984,8 @@ bool SemanticsVisitor::_coerceInitializerList(
argCount);
}
}
+ if (outToExpr)
+ *outToExpr = outInitListExpr;
return true;
}
@@ -1868,9 +1880,18 @@ bool SemanticsVisitor::_coerce(
castExpr->arguments.add(args[0]);
}
if (!cachedMethod)
- getShared()->cacheImplicitCastMethod(
- implicitCastKey,
- ImplicitCastMethod{*overloadContext.bestCandidate, cost});
+ {
+ // We can only cache the method if it is a public, otherwise we may not be able to
+ // use this method depending on where we are performing the coercion.
+ if (overloadContext.bestCandidate->item.declRef &&
+ getDeclVisibility(overloadContext.bestCandidate->item.declRef.getDecl()) ==
+ DeclVisibility::Public)
+ {
+ getShared()->cacheImplicitCastMethod(
+ implicitCastKey,
+ ImplicitCastMethod{*overloadContext.bestCandidate, cost});
+ }
+ }
return true;
}
if (!cachedMethod)