summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/slang/slang-check-expr.cpp38
-rw-r--r--source/slang/slang-diagnostic-defs.h9
2 files changed, 42 insertions, 5 deletions
diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp
index 9dc359a5e..587dcc2b5 100644
--- a/source/slang/slang-check-expr.cpp
+++ b/source/slang/slang-check-expr.cpp
@@ -2051,7 +2051,20 @@ namespace Slang
{
auto implicitCastExpr = as<ImplicitCastExpr>(argExpr);
- if (implicitCastExpr && _canLValueCoerce(implicitCastExpr->arguments[0]->type, implicitCastExpr->type))
+ // NOTE:
+ // This is currently only enabled for in/inout based scenarios. Ie NOT ref.
+ //
+ // Depending on the target there can be an issue around atomics.
+ // The fall back transformation with InOut/OutImplicitCast is to introduce
+ // a temporary, and do the work on that and copy back.
+ //
+ // This doesn't work with an atomic. So the work around is to not enable
+ // the transformation with ref types, which atomics are defined on.
+ //
+ // An argument can be made that transformation shouldn't apply to the ref scenario in general.
+ if (implicitCastExpr &&
+ as<OutTypeBase>(paramType) &&
+ _canLValueCoerce(implicitCastExpr->arguments[0]->type, implicitCastExpr->type))
{
// This is to work around issues like
//
@@ -2093,11 +2106,32 @@ namespace Slang
Diagnostics::argumentExpectedLValue,
pp);
+
if(implicitCastExpr)
{
+ const DiagnosticInfo* diagnostic = nullptr;
+
+ // Try and determine reason for failure
+ if (as<RefType>(paramType))
+ {
+ // Ref types are not allowed to use this mechanism because it breaks atomics
+ diagnostic = &Diagnostics::implicitCastUsedAsLValueRef;
+ }
+ else if (!_canLValueCoerce(implicitCastExpr->arguments[0]->type, implicitCastExpr->type))
+ {
+ // We restict what types can use this mechanism - currently int/uint and same sized matrix/vectors
+ // of those types.
+ diagnostic = &Diagnostics::implicitCastUsedAsLValueType;
+ }
+ else
+ {
+ // Fall back, in case there are other reasons...
+ diagnostic = &Diagnostics::implicitCastUsedAsLValue;
+ }
+
getSink()->diagnose(
argExpr,
- Diagnostics::implicitCastUsedAsLValue,
+ *diagnostic,
implicitCastExpr->arguments[pp]->type,
implicitCastExpr->type);
}
diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h
index 0fd962614..922348d61 100644
--- a/source/slang/slang-diagnostic-defs.h
+++ b/source/slang/slang-diagnostic-defs.h
@@ -270,8 +270,9 @@ DIAGNOSTIC(30031, Error, projectTypeMismatch, "'project': expression must evalua
DIAGNOSTIC(30033, Error, invalidTypeForLocalVariable, "cannot declare a local variable of this type.")
DIAGNOSTIC(30035, Error, componentOverloadTypeMismatch, "'$0': type of overloaded component mismatches previous definition.")
DIAGNOSTIC(30041, Error, bitOperationNonIntegral, "bit operation: operand must be integral type.")
+DIAGNOSTIC(30043, Error, getStringHashRequiresStringLiteral, "getStringHash parameter can only accept a string literal")
DIAGNOSTIC(30047, Error, argumentExpectedLValue, "argument passed to parameter '$0' must be l-value.")
-DIAGNOSTIC(30048, Note, implicitCastUsedAsLValue, "argument was implicitly cast from '$0' to '$1', and Slang does not support using an implicit cast as an l-value")
+
DIAGNOSTIC(30049, Note, thisIsImmutableByDefault, "a 'this' parameter is an immutable parameter by default in Slang; apply the `[mutating]` attribute to the function declaration to opt in to a mutable `this`")
DIAGNOSTIC(30050, Error, mutatingMethodOnImmutableValue, "mutating method '$0' cannot be called on an immutable value")
@@ -284,11 +285,13 @@ DIAGNOSTIC(30056, Warning, useOfNonShortCircuitingOperator, "non-short-circuitin
DIAGNOSTIC(30057, Error, assignmentInPredicateExpr, "use an assignment operation as predicate expression is not allowed, wrap the assignment with '()' to clarify the intent.")
DIAGNOSTIC(30058, Warning, danglingEqualityExpr, "result of '==' not used, did you intend '='?")
-DIAGNOSTIC(30043, Error, getStringHashRequiresStringLiteral, "getStringHash parameter can only accept a string literal")
-
DIAGNOSTIC(30060, Error, expectedAType, "expected a type, got a '$0'")
DIAGNOSTIC(30061, Error, expectedANamespace, "expected a namespace, got a '$0'")
+DIAGNOSTIC(30062, Note, implicitCastUsedAsLValueRef, "argument was implicitly cast from '$0' to '$1', and Slang does not support using an implicit cast as an l-value with a reference")
+DIAGNOSTIC(30063, Note, implicitCastUsedAsLValueType, "argument was implicitly cast from '$0' to '$1', and Slang does not support using an implicit cast as an l-value with this type")
+DIAGNOSTIC(30064, Note, implicitCastUsedAsLValue, "argument was implicitly cast from '$0' to '$1', and Slang does not support using an implicit cast as an l-value for this usage")
+
DIAGNOSTIC(30065, Error, newCanOnlyBeUsedToInitializeAClass, "`new` can only be used to initialize a class")
DIAGNOSTIC(30066, Error, classCanOnlyBeInitializedWithNew, "a class can only be initialized by a `new` clause")