diff --git a/source/modules/soul_core/compiler/soul_HeartGenerator.h b/source/modules/soul_core/compiler/soul_HeartGenerator.h index 9f785f2..1df9424 100644 --- a/source/modules/soul_core/compiler/soul_HeartGenerator.h +++ b/source/modules/soul_core/compiler/soul_HeartGenerator.h @@ -102,9 +102,11 @@ struct HEARTGenerator : public ASTVisitor } heart::Variable& createVariableDeclaration (AST::VariableDeclaration& v, - heart::Variable::Role role) + heart::Variable::Role role, + bool canBeReference) { - auto& av = module.allocate (v.context.location, v.getType(), + auto& av = module.allocate (v.context.location, + canBeReference ? v.getType() : v.getType().removeReferenceIfPresent(), convertIdentifier (v.name), role); v.generatedVariable = av; @@ -118,7 +120,7 @@ struct HEARTGenerator : public ASTVisitor heart::Variable& addExternalVariable (AST::VariableDeclaration& v) { SOUL_ASSERT (v.isExternal); - auto& hv = createVariableDeclaration (v, heart::Variable::Role::external); + auto& hv = createVariableDeclaration (v, heart::Variable::Role::external, false); module.stateVariables.add (hv); return hv; } @@ -399,7 +401,7 @@ struct HEARTGenerator : public ASTVisitor for (auto p : f.parameters) { - auto& v = createVariableDeclaration (p, heart::Variable::Role::parameter); + auto& v = createVariableDeclaration (p, heart::Variable::Role::parameter, true); if (af.functionType.isEvent() && v.getType().isNonConstReference()) p->context.throwError (Errors::eventParamsCannotBeNonConstReference()); @@ -897,12 +899,12 @@ struct HEARTGenerator : public ASTVisitor // Skip writing constant or unwritten-to variables to the state if (! (v.numWrites == 0 && (type.isPrimitive() || type.isBoundedInt()))) - module.stateVariables.add (createVariableDeclaration (v, heart::Variable::Role::state)); + module.stateVariables.add (createVariableDeclaration (v, heart::Variable::Role::state, false)); } } else { - auto& target = createVariableDeclaration (v, heart::Variable::Role::mutableLocal); + auto& target = createVariableDeclaration (v, heart::Variable::Role::mutableLocal, false); if (v.initialValue != nullptr) visitWithDestination (target, *v.initialValue); diff --git a/source/modules/soul_core/compiler/soul_ResolutionPass.h b/source/modules/soul_core/compiler/soul_ResolutionPass.h index cc25975..27dbe54 100644 --- a/source/modules/soul_core/compiler/soul_ResolutionPass.h +++ b/source/modules/soul_core/compiler/soul_ResolutionPass.h @@ -1482,9 +1482,7 @@ struct ResolutionPass final void resolveVariableDeclarationInitialValue (AST::VariableDeclaration& v, const Type& type) { if (AST::isResolvedAsValue (v.initialValue)) - SanityCheckPass::expectSilentCastPossible (v.context, - type, - *v.initialValue); + SanityCheckPass::expectSilentCastPossible (v.context, type, *v.initialValue); if (! (AST::isResolvedAsValue (v.initialValue) && v.initialValue->getResultType().isIdentical (type))) v.initialValue = allocator.allocate (v.initialValue->context, type, *v.initialValue); diff --git a/source/modules/soul_core/types/soul_TypeRules.h b/source/modules/soul_core/types/soul_TypeRules.h index b874116..e9acc80 100644 --- a/source/modules/soul_core/types/soul_TypeRules.h +++ b/source/modules/soul_core/types/soul_TypeRules.h @@ -106,10 +106,19 @@ struct TypeRules if ((dest.isPrimitive() || dest.isVectorOfSize1()) && source.isPrimitive() && ! dest.isReference()) return getCastType (dest.getPrimitiveType(), source.getPrimitiveType()); - if (source.isEqual (dest, Type::ignoreConst)) - if (! (dest.isReference() || source.isReference())) - return CastType::identity; - + if (! dest.isReference()) + { + if (source.isReference()) + { + if (source.isConst() && source.isEqual (dest, Type::ignoreConst | Type::ignoreReferences)) + return CastType::identity; + } + else + { + if (source.isEqual (dest, Type::ignoreConst)) + return CastType::identity; + } + } if (dest.isArray()) {