diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 38 | ||||
| -rw-r--r-- | source/slang/slang-diagnostic-defs.h | 9 |
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") |
