From 69a38bbf19094003cf9de3083b61eeea9bac4293 Mon Sep 17 00:00:00 2001 From: Marc Auberer Date: Wed, 17 Jan 2024 21:34:20 +0100 Subject: [PATCH] Fix const ref assign (#433) --- media/test-project/test.spice | 14 +--- src/CMakeLists.txt | 2 +- src/SourceFile.cpp | 4 +- src/ast/ASTBuilder.cpp | 2 +- src/irgenerator/GenControlStructures.cpp | 2 +- src/symboltablebuilder/Scope.cpp | 4 +- src/symboltablebuilder/Scope.h | 2 +- src/symboltablebuilder/SymbolType.cpp | 2 +- src/symboltablebuilder/SymbolType.h | 10 +-- src/typechecker/OpRuleManager.cpp | 83 ++++++++++--------- src/typechecker/OpRuleManager.h | 54 ++++++------ src/typechecker/TypeChecker.cpp | 74 ++++++++--------- src/typechecker/TypeMatcher.cpp | 5 -- .../exception.out | 5 ++ .../error-reassign-const-ref-var/source.spice | 8 ++ .../error-reassign-const-var/exception.out | 2 +- 16 files changed, 138 insertions(+), 135 deletions(-) create mode 100644 test/test-files/typechecker/variables/error-reassign-const-ref-var/exception.out create mode 100644 test/test-files/typechecker/variables/error-reassign-const-ref-var/source.spice diff --git a/media/test-project/test.spice b/media/test-project/test.spice index 0f42e8a41..078d6bc4d 100644 --- a/media/test-project/test.spice +++ b/media/test-project/test.spice @@ -1,15 +1,9 @@ -import "std/os/thread-pool"; +f fn(int& ref) { + return false; +} f main() { - int testVar = 123; - ThreadPool tp = ThreadPool(3s); - dyn proc = p() { - printf("Test: %d\n", testVar); - }; - tp.enqueue(proc); - tp.start(); - tp.join(); - printf("TestVar: %d\n", testVar); + fn(123); } /*f main() { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1ac447f11..040c36c8e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -154,7 +154,7 @@ set(SOURCES add_executable(spice ${SOURCES} ${ANTLR_Spice_CXX_OUTPUTS}) # Enable pedantic warnings -target_compile_options(spice PRIVATE -Wpedantic -Wall) +target_compile_options(spice PRIVATE -Wpedantic -Wall -Wno-unknown-pragmas) # Include Antlr components include_directories(../lib/antlr4/runtime/Cpp/runtime/src) diff --git a/src/SourceFile.cpp b/src/SourceFile.cpp index 1ec34b06e..1335970de 100644 --- a/src/SourceFile.cpp +++ b/src/SourceFile.cpp @@ -24,8 +24,8 @@ namespace spice::compiler { SourceFile::SourceFile(GlobalResourceManager &resourceManager, SourceFile *parent, std::string name, const std::filesystem::path &filePath, bool stdFile) - : resourceManager(resourceManager), tout(resourceManager.tout), name(std::move(name)), filePath(filePath), stdFile(stdFile), - parent(parent) { + : name(std::move(name)), filePath(filePath), stdFile(stdFile), parent(parent), resourceManager(resourceManager), + tout(resourceManager.tout) { // Deduce fileName and fileDir fileName = std::filesystem::path(filePath).filename().string(); fileDir = std::filesystem::path(filePath).parent_path().string(); diff --git a/src/ast/ASTBuilder.cpp b/src/ast/ASTBuilder.cpp index 2fc3407c2..e8f05dfed 100644 --- a/src/ast/ASTBuilder.cpp +++ b/src/ast/ASTBuilder.cpp @@ -1138,7 +1138,7 @@ std::any ASTBuilder::visitDataType(SpiceParser::DataTypeContext *ctx) { auto dataTypeNode = createNode(ctx); // Enrich - for (int i = 0; i < ctx->children.size(); i++) { + for (size_t i = 0; i < ctx->children.size(); i++) { antlr4::tree::ParseTree *subTree = ctx->children[i]; if (auto t1 = dynamic_cast(subTree); t1 != nullptr && t1->getSymbol()->getType() == SpiceParser::MUL) { dataTypeNode->tmQueue.emplace(DataTypeNode::TYPE_PTR, false, 0); diff --git a/src/irgenerator/GenControlStructures.cpp b/src/irgenerator/GenControlStructures.cpp index b047ae0cb..a9b649f64 100644 --- a/src/irgenerator/GenControlStructures.cpp +++ b/src/irgenerator/GenControlStructures.cpp @@ -362,7 +362,7 @@ std::any IRGenerator::visitSwitchStmt(const SwitchStmtNode *node) { llvm::Value *exprValue = resolveValue(node->assignExpr()); // Generate switch instruction - llvm::SwitchInst *switchInst = builder.CreateSwitch(exprValue, bDefault ?: bExit, caseBranches.size()); + llvm::SwitchInst *switchInst = builder.CreateSwitch(exprValue, bDefault ? bDefault : bExit, caseBranches.size()); // Generate case branches for (size_t i = 0; i < caseBranches.size(); i++) { diff --git a/src/symboltablebuilder/Scope.cpp b/src/symboltablebuilder/Scope.cpp index aeef95ac7..f5aa22259 100644 --- a/src/symboltablebuilder/Scope.cpp +++ b/src/symboltablebuilder/Scope.cpp @@ -345,11 +345,11 @@ bool Scope::hasRefFields() { * * @return Number of loops */ -size_t Scope::getLoopNestingDepth() const { // NOLINT(misc-no-recursion) +unsigned int Scope::getLoopNestingDepth() const { // NOLINT(misc-no-recursion) assert(parent != nullptr); if (parent->parent == nullptr) return 0; - size_t loopCount = parent->getLoopNestingDepth(); + unsigned int loopCount = parent->getLoopNestingDepth(); if (type == ScopeType::WHILE_BODY || type == ScopeType::FOR_BODY || type == ScopeType::FOREACH_BODY) loopCount++; return loopCount; diff --git a/src/symboltablebuilder/Scope.h b/src/symboltablebuilder/Scope.h index 48588372f..6a4a089aa 100644 --- a/src/symboltablebuilder/Scope.h +++ b/src/symboltablebuilder/Scope.h @@ -81,7 +81,7 @@ class Scope { [[nodiscard]] size_t getFieldCount() const; [[nodiscard]] std::vector getVirtualMethods(); [[nodiscard]] bool hasRefFields(); - [[nodiscard]] size_t getLoopNestingDepth() const; + [[nodiscard]] unsigned int getLoopNestingDepth() const; [[nodiscard]] bool isInCaseBranch() const; [[nodiscard]] bool isInAsyncScope() const; [[nodiscard]] bool doesAllowUnsafeOperations() const; diff --git a/src/symboltablebuilder/SymbolType.cpp b/src/symboltablebuilder/SymbolType.cpp index 830590f12..846dfd825 100644 --- a/src/symboltablebuilder/SymbolType.cpp +++ b/src/symboltablebuilder/SymbolType.cpp @@ -85,7 +85,7 @@ SymbolType SymbolType::toConstReference(const ASTNode *node) const { * @param size Size of the array * @return Array type of the current type */ -SymbolType SymbolType::toArray(const ASTNode *node, size_t size, bool skipDynCheck /*=false*/) const { +SymbolType SymbolType::toArray(const ASTNode *node, unsigned int size, bool skipDynCheck /*=false*/) const { // Do not allow arrays of dyn if (!skipDynCheck && typeChain.back().superType == TY_DYN) throw SemanticError(node, DYN_ARRAYS_NOT_ALLOWED, "Just use the dyn type without '[]' instead"); diff --git a/src/symboltablebuilder/SymbolType.h b/src/symboltablebuilder/SymbolType.h index 8a410d763..005fbfa8c 100644 --- a/src/symboltablebuilder/SymbolType.h +++ b/src/symboltablebuilder/SymbolType.h @@ -58,9 +58,9 @@ class SymbolType { public: // Unions union TypeChainElementData { - size_t arraySize = 0; // TY_ARRAY - Scope *bodyScope; // TY_STRUCT, TY_INTERFACE, TY_ENUM - bool hasCaptures; // TY_FUNCTION, TY_PROCEDURE (lambdas) + unsigned int arraySize; // TY_ARRAY + Scope *bodyScope = nullptr; // TY_STRUCT, TY_INTERFACE, TY_ENUM + bool hasCaptures; // TY_FUNCTION, TY_PROCEDURE (lambdas) NLOHMANN_DEFINE_TYPE_INTRUSIVE(TypeChainElementData, arraySize) }; @@ -112,7 +112,7 @@ class SymbolType { [[nodiscard]] SymbolType toPointer(const ASTNode *node) const; [[nodiscard]] SymbolType toReference(const ASTNode *node) const; [[nodiscard]] SymbolType toConstReference(const ASTNode *node) const; - [[nodiscard]] SymbolType toArray(const ASTNode *node, size_t size = 0, bool skipDynCheck = false) const; + [[nodiscard]] SymbolType toArray(const ASTNode *node, unsigned int size = 0, bool skipDynCheck = false) const; [[nodiscard]] SymbolType getContainedTy() const; [[nodiscard]] SymbolType replaceBaseType(const SymbolType &newBaseType) const; [[nodiscard]] llvm::Type *toLLVMType(llvm::LLVMContext &context, Scope *accessScope) const; @@ -165,7 +165,7 @@ class SymbolType { [[nodiscard]] const std::vector &getTemplateTypes() const; [[nodiscard]] bool isCoveredByGenericTypeList(std::vector &genericTypeList) const; [[nodiscard]] std::string getName(bool withSize = false, bool ignorePublic = false) const; - [[nodiscard]] ALWAYS_INLINE size_t getArraySize() const { + [[nodiscard]] ALWAYS_INLINE unsigned int getArraySize() const { assert(getSuperType() == TY_ARRAY); return typeChain.back().data.arraySize; } diff --git a/src/typechecker/OpRuleManager.cpp b/src/typechecker/OpRuleManager.cpp index 518f21780..c6747183a 100644 --- a/src/typechecker/OpRuleManager.cpp +++ b/src/typechecker/OpRuleManager.cpp @@ -12,8 +12,8 @@ namespace spice::compiler { OpRuleManager::OpRuleManager(TypeChecker *typeChecker) : typeChecker(typeChecker), resourceManager(typeChecker->resourceManager) {} -SymbolType OpRuleManager::getAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx, - bool isDecl /*=false*/, const char *errorMessagePrefix /*=""*/) { +SymbolType OpRuleManager::getAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, bool isDecl, + const char *errMsgPrefix) { // Check if we try to assign a constant value if (!isDecl) ensureNoConstAssign(node, lhs); @@ -63,12 +63,13 @@ SymbolType OpRuleManager::getAssignResultType(const ASTNode *node, SymbolType lh } } // Check primitive type combinations - return validateBinaryOperation(node, ASSIGN_OP_RULES, ARRAY_LENGTH(ASSIGN_OP_RULES), "=", lhs, rhs, true, errorMessagePrefix); + return validateBinaryOperation(node, ASSIGN_OP_RULES, ARRAY_LENGTH(ASSIGN_OP_RULES), "=", lhs, rhs, true, errMsgPrefix); } -SymbolType OpRuleManager::getFieldAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx, bool imm) { +SymbolType OpRuleManager::getFieldAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, bool imm, bool isDecl) { // Check if we try to assign a constant value - ensureNoConstAssign(node, lhs); + if (!isDecl) + ensureNoConstAssign(node, lhs); // Allow pointers and arrays of the same type straight away if (lhs.isOneOf({TY_PTR, TY_ARRAY, TY_STRUCT}) && lhs == rhs) @@ -171,7 +172,7 @@ ExprResult OpRuleManager::getDivEqualResultType(ASTNode *node, SymbolType lhs, S return ExprResult(validateBinaryOperation(node, DIV_EQUAL_OP_RULES, ARRAY_LENGTH(DIV_EQUAL_OP_RULES), "/=", lhs, rhs)); } -SymbolType OpRuleManager::getRemEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getRemEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -182,7 +183,7 @@ SymbolType OpRuleManager::getRemEqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, REM_EQUAL_OP_RULES, ARRAY_LENGTH(REM_EQUAL_OP_RULES), "%=", lhs, rhs); } -SymbolType OpRuleManager::getSHLEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getSHLEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -193,7 +194,7 @@ SymbolType OpRuleManager::getSHLEqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, SHL_EQUAL_OP_RULES, ARRAY_LENGTH(SHL_EQUAL_OP_RULES), "<<=", lhs, rhs); } -SymbolType OpRuleManager::getSHREqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getSHREqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -204,7 +205,7 @@ SymbolType OpRuleManager::getSHREqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, SHR_EQUAL_OP_RULES, ARRAY_LENGTH(SHR_EQUAL_OP_RULES), ">>=", lhs, rhs); } -SymbolType OpRuleManager::getAndEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getAndEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -215,7 +216,7 @@ SymbolType OpRuleManager::getAndEqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, AND_EQUAL_OP_RULES, ARRAY_LENGTH(AND_EQUAL_OP_RULES), "&=", lhs, rhs); } -SymbolType OpRuleManager::getOrEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getOrEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -226,7 +227,7 @@ SymbolType OpRuleManager::getOrEqualResultType(const ASTNode *node, SymbolType l return validateBinaryOperation(node, OR_EQUAL_OP_RULES, ARRAY_LENGTH(OR_EQUAL_OP_RULES), "|=", lhs, rhs); } -SymbolType OpRuleManager::getXorEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getXorEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -237,7 +238,7 @@ SymbolType OpRuleManager::getXorEqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, XOR_EQUAL_OP_RULES, ARRAY_LENGTH(XOR_EQUAL_OP_RULES), "^=", lhs, rhs); } -SymbolType OpRuleManager::getLogicalOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getLogicalOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -245,7 +246,7 @@ SymbolType OpRuleManager::getLogicalOrResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, LOGICAL_OR_OP_RULES, ARRAY_LENGTH(LOGICAL_OR_OP_RULES), "||", lhs, rhs); } -SymbolType OpRuleManager::getLogicalAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getLogicalAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -253,7 +254,7 @@ SymbolType OpRuleManager::getLogicalAndResultType(const ASTNode *node, SymbolTyp return validateBinaryOperation(node, LOGICAL_AND_OP_RULES, ARRAY_LENGTH(LOGICAL_AND_OP_RULES), "&&", lhs, rhs); } -SymbolType OpRuleManager::getBitwiseOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getBitwiseOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -261,7 +262,7 @@ SymbolType OpRuleManager::getBitwiseOrResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, BITWISE_OR_OP_RULES, ARRAY_LENGTH(BITWISE_OR_OP_RULES), "|", lhs, rhs); } -SymbolType OpRuleManager::getBitwiseXorResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getBitwiseXorResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -269,7 +270,7 @@ SymbolType OpRuleManager::getBitwiseXorResultType(const ASTNode *node, SymbolTyp return validateBinaryOperation(node, BITWISE_XOR_OP_RULES, ARRAY_LENGTH(BITWISE_XOR_OP_RULES), "^", lhs, rhs); } -SymbolType OpRuleManager::getBitwiseAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getBitwiseAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -329,7 +330,7 @@ ExprResult OpRuleManager::getNotEqualResultType(ASTNode *node, SymbolType lhs, S return ExprResult(validateBinaryOperation(node, NOT_EQUAL_OP_RULES, ARRAY_LENGTH(NOT_EQUAL_OP_RULES), "!=", lhs, rhs)); } -SymbolType OpRuleManager::getLessResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getLessResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -337,7 +338,7 @@ SymbolType OpRuleManager::getLessResultType(const ASTNode *node, SymbolType lhs, return validateBinaryOperation(node, LESS_OP_RULES, ARRAY_LENGTH(LESS_OP_RULES), "<", lhs, rhs); } -SymbolType OpRuleManager::getGreaterResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getGreaterResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -345,7 +346,7 @@ SymbolType OpRuleManager::getGreaterResultType(const ASTNode *node, SymbolType l return validateBinaryOperation(node, GREATER_OP_RULES, ARRAY_LENGTH(GREATER_OP_RULES), ">", lhs, rhs); } -SymbolType OpRuleManager::getLessEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getLessEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -353,7 +354,7 @@ SymbolType OpRuleManager::getLessEqualResultType(const ASTNode *node, SymbolType return validateBinaryOperation(node, LESS_EQUAL_OP_RULES, ARRAY_LENGTH(LESS_EQUAL_OP_RULES), "<=", lhs, rhs); } -SymbolType OpRuleManager::getGreaterEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getGreaterEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -461,7 +462,7 @@ ExprResult OpRuleManager::getDivResultType(ASTNode *node, SymbolType lhs, Symbol return ExprResult(validateBinaryOperation(node, DIV_OP_RULES, ARRAY_LENGTH(DIV_OP_RULES), "/", lhs, rhs)); } -ExprResult OpRuleManager::getRemResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +ExprResult OpRuleManager::getRemResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -469,14 +470,14 @@ ExprResult OpRuleManager::getRemResultType(const ASTNode *node, SymbolType lhs, return ExprResult(validateBinaryOperation(node, REM_OP_RULES, ARRAY_LENGTH(REM_OP_RULES), "%", lhs, rhs)); } -SymbolType OpRuleManager::getPrefixMinusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixMinusResultType(const ASTNode *node, SymbolType lhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); return validateUnaryOperation(node, PREFIX_MINUS_OP_RULES, ARRAY_LENGTH(PREFIX_MINUS_OP_RULES), "-", lhs); } -SymbolType OpRuleManager::getPrefixPlusPlusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixPlusPlusResultType(const ASTNode *node, SymbolType lhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -486,7 +487,7 @@ SymbolType OpRuleManager::getPrefixPlusPlusResultType(const ASTNode *node, Symbo return validateUnaryOperation(node, PREFIX_PLUS_PLUS_OP_RULES, ARRAY_LENGTH(PREFIX_PLUS_PLUS_OP_RULES), "++", lhs); } -SymbolType OpRuleManager::getPrefixMinusMinusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixMinusMinusResultType(const ASTNode *node, SymbolType lhs) { // Check if we try to assign a constant value ensureNoConstAssign(node, lhs); @@ -496,21 +497,21 @@ SymbolType OpRuleManager::getPrefixMinusMinusResultType(const ASTNode *node, Sym return validateUnaryOperation(node, PREFIX_MINUS_MINUS_OP_RULES, ARRAY_LENGTH(PREFIX_MINUS_MINUS_OP_RULES), "--", lhs); } -SymbolType OpRuleManager::getPrefixNotResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixNotResultType(const ASTNode *node, SymbolType lhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); return validateUnaryOperation(node, PREFIX_NOT_OP_RULES, ARRAY_LENGTH(PREFIX_NOT_OP_RULES), "!", lhs); } -SymbolType OpRuleManager::getPrefixBitwiseNotResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixBitwiseNotResultType(const ASTNode *node, SymbolType lhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); return validateUnaryOperation(node, PREFIX_BITWISE_NOT_OP_RULES, ARRAY_LENGTH(PREFIX_BITWISE_NOT_OP_RULES), "~", lhs); } -SymbolType OpRuleManager::getPrefixMulResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixMulResultType(const ASTNode *node, SymbolType lhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); @@ -519,7 +520,7 @@ SymbolType OpRuleManager::getPrefixMulResultType(const ASTNode *node, SymbolType return lhs.getContainedTy(); } -SymbolType OpRuleManager::getPrefixBitwiseAndResultType(const ASTNode *node, SymbolType lhs, size_t opIdx) { +SymbolType OpRuleManager::getPrefixBitwiseAndResultType(const ASTNode *node, SymbolType lhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); @@ -558,7 +559,7 @@ ExprResult OpRuleManager::getPostfixMinusMinusResultType(ASTNode *node, SymbolTy validateUnaryOperation(node, POSTFIX_MINUS_MINUS_OP_RULES, ARRAY_LENGTH(POSTFIX_MINUS_MINUS_OP_RULES), "--", lhs)); } -SymbolType OpRuleManager::getCastResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx) { +SymbolType OpRuleManager::getCastResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs) { // Remove reference wrappers lhs = lhs.removeReferenceWrapper(); rhs = rhs.removeReferenceWrapper(); @@ -608,6 +609,7 @@ ExprResult OpRuleManager::isOperatorOverloadingFctAvailable(ASTNode *node, const // Return invalid type if the callee was not found if (!callee) return ExprResult(SymbolType(TY_INVALID)); + assert(calleeParentScope != nullptr); // Save the pointer to the operator function in the AST node std::vector &opFctPointers = typeChecker->getOpFctPointers(node); @@ -671,17 +673,14 @@ SemanticError OpRuleManager::getExceptionUnary(const ASTNode *node, const char * SemanticError OpRuleManager::getExceptionBinary(const ASTNode *node, const char *name, const SymbolType &lhs, const SymbolType &rhs, const char *messagePrefix) { // Build error message - std::string errorMsg; - if (strlen(messagePrefix) != 0) { - errorMsg += messagePrefix; - errorMsg += ". Expected " + lhs.getName(true) + " but got " + rhs.getName(true); - } else { - errorMsg += "Cannot apply '"; - errorMsg += name; - errorMsg += "' operator on types " + lhs.getName(true) + " and " + rhs.getName(true); - } + std::stringstream errorMsg; + if (strlen(messagePrefix) != 0) + errorMsg << messagePrefix << ". Expected " << lhs.getName(true) << " but got " << rhs.getName(true); + else + errorMsg << "Cannot apply '" << name << "' operator on types " << lhs.getName(true) << " and " << rhs.getName(true); + // Return the exception - return {node, OPERATOR_WRONG_DATA_TYPE, errorMsg}; + return {node, OPERATOR_WRONG_DATA_TYPE, errorMsg.str()}; } void OpRuleManager::ensureUnsafeAllowed(const ASTNode *node, const char *name, const SymbolType &lhs, @@ -698,8 +697,10 @@ void OpRuleManager::ensureUnsafeAllowed(const ASTNode *node, const char *name, c void OpRuleManager::ensureNoConstAssign(const ASTNode *node, const SymbolType &lhs) { // Check if we try to assign a constant value - if (lhs.isConst()) - throw SemanticError(node, REASSIGN_CONST_VARIABLE, "Trying to assign value to a constant"); + if (lhs.removeReferenceWrapper().isConst()) { + const std::string errorMessage = "Trying to assign value to an immutable variable of type " + lhs.getName(true); + throw SemanticError(node, REASSIGN_CONST_VARIABLE, errorMessage); + } } } // namespace spice::compiler \ No newline at end of file diff --git a/src/typechecker/OpRuleManager.h b/src/typechecker/OpRuleManager.h index 997e591d3..7f3230dab 100644 --- a/src/typechecker/OpRuleManager.h +++ b/src/typechecker/OpRuleManager.h @@ -622,47 +622,47 @@ class OpRuleManager { explicit OpRuleManager(TypeChecker *typeChecker); // Public methods - SymbolType getAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx, bool isDecl = false, - const char *errorMessagePrefix = ""); - SymbolType getFieldAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx, bool imm); + static SymbolType getAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, bool isDecl = false, + const char *errMsgPrefix = ""); + static SymbolType getFieldAssignResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, bool imm, bool isDecl = false); ExprResult getPlusEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getMinusEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getMulEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getDivEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getRemEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getSHLEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getSHREqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getAndEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getOrEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - SymbolType getXorEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getLogicalOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getLogicalAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getBitwiseOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getBitwiseXorResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getBitwiseAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); + static SymbolType getRemEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getSHLEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getSHREqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getAndEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getOrEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getXorEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getLogicalOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getLogicalAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getBitwiseOrResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getBitwiseXorResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getBitwiseAndResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); ExprResult getEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getNotEqualResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getLessResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getGreaterResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getLessEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getGreaterEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); + static SymbolType getLessResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getGreaterResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getLessEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getGreaterEqualResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); ExprResult getShiftLeftResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getShiftRightResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getPlusResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getMinusResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getMulResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); ExprResult getDivResultType(ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static ExprResult getRemResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); - static SymbolType getPrefixMinusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - SymbolType getPrefixPlusPlusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - SymbolType getPrefixMinusMinusResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - static SymbolType getPrefixNotResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - static SymbolType getPrefixBitwiseNotResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - static SymbolType getPrefixMulResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); - static SymbolType getPrefixBitwiseAndResultType(const ASTNode *node, SymbolType lhs, size_t opIdx); + static ExprResult getRemResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); + static SymbolType getPrefixMinusResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixPlusPlusResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixMinusMinusResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixNotResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixBitwiseNotResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixMulResultType(const ASTNode *node, SymbolType lhs); + static SymbolType getPrefixBitwiseAndResultType(const ASTNode *node, SymbolType lhs); ExprResult getPostfixPlusPlusResultType(ASTNode *node, SymbolType lhs, size_t opIdx); ExprResult getPostfixMinusMinusResultType(ASTNode *node, SymbolType lhs, size_t opIdx); - SymbolType getCastResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs, size_t opIdx); + SymbolType getCastResultType(const ASTNode *node, SymbolType lhs, SymbolType rhs); private: // Members diff --git a/src/typechecker/TypeChecker.cpp b/src/typechecker/TypeChecker.cpp index a21ed0a54..41aa2d6d2 100644 --- a/src/typechecker/TypeChecker.cpp +++ b/src/typechecker/TypeChecker.cpp @@ -194,7 +194,7 @@ std::any TypeChecker::visitForeachLoop(ForeachLoopNode *node) { itemType = iteratorItemType; } else { // Check item type - opRuleManager.getAssignResultType(node->itemVarDecl(), itemType, iteratorItemType, manIdx, true, ERROR_FOREACH_ITEM); + OpRuleManager::getAssignResultType(node->itemVarDecl(), itemType, iteratorItemType, true, ERROR_FOREACH_ITEM); } // Update type of item @@ -518,7 +518,7 @@ std::any TypeChecker::visitDeclStmt(DeclStmtNode *node) { // Check if type has to be inferred or both types are fixed if (!localVarType.is(TY_UNRESOLVED) && !rhsTy.is(TY_UNRESOLVED)) { - localVarType = opRuleManager.getAssignResultType(node, localVarType, rhsTy, 0, true); + localVarType = OpRuleManager::getAssignResultType(node, localVarType, rhsTy, true); // Call copy ctor if required if (localVarType.is(TY_STRUCT) && !node->isParam && !rhs.isTemporary()) { @@ -605,7 +605,7 @@ std::any TypeChecker::visitReturnStmt(ReturnStmtNode *node) { HANDLE_UNRESOLVED_TYPE_ST(rhs.type) // Check if types match - opRuleManager.getAssignResultType(node->assignExpr(), returnType, rhs.type, 0, false, ERROR_MSG_RETURN); + OpRuleManager::getAssignResultType(node->assignExpr(), returnType, rhs.type, true, ERROR_MSG_RETURN); // Manager dtor call if (rhs.entry != nullptr) { @@ -628,8 +628,8 @@ std::any TypeChecker::visitBreakStmt(BreakStmtNode *node) { SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "Break count must be >= 1, you provided " + std::to_string(node->breakTimes)) // Check if we can break this often - const size_t maxBreaks = currentScope->getLoopNestingDepth(); - if (node->breakTimes > maxBreaks) + const unsigned int maxBreaks = currentScope->getLoopNestingDepth(); + if (static_cast(node->breakTimes) > maxBreaks) SOFT_ERROR_ER(node, INVALID_BREAK_NUMBER, "We can only break " + std::to_string(maxBreaks) + " time(s) here") return nullptr; @@ -642,8 +642,8 @@ std::any TypeChecker::visitContinueStmt(ContinueStmtNode *node) { "Continue count must be >= 1, you provided " + std::to_string(node->continueTimes)) // Check if we can continue this often - const size_t maxContinues = currentScope->getLoopNestingDepth(); - if (node->continueTimes > maxContinues) + const unsigned int maxContinues = currentScope->getLoopNestingDepth(); + if (static_cast(node->continueTimes) > maxContinues) SOFT_ERROR_ER(node, INVALID_CONTINUE_NUMBER, "We can only continue " + std::to_string(maxContinues) + " time(s) here") return nullptr; @@ -812,7 +812,7 @@ std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { // Take a look at the operator if (node->op == AssignExprNode::OP_ASSIGN) { - rhsType = opRuleManager.getAssignResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getAssignResultType(node, lhsType, rhsType); // If there is an anonymous entry attached (e.g. for struct instantiation), delete it if (rhsEntry != nullptr && rhsEntry->anonymous) { @@ -828,17 +828,17 @@ std::any TypeChecker::visitAssignExpr(AssignExprNode *node) { } else if (node->op == AssignExprNode::OP_DIV_EQUAL) { rhsType = opRuleManager.getDivEqualResultType(node, lhsType, rhsType, 0).type; } else if (node->op == AssignExprNode::OP_REM_EQUAL) { - rhsType = opRuleManager.getRemEqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getRemEqualResultType(node, lhsType, rhsType); } else if (node->op == AssignExprNode::OP_SHL_EQUAL) { - rhsType = opRuleManager.getSHLEqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getSHLEqualResultType(node, lhsType, rhsType); } else if (node->op == AssignExprNode::OP_SHR_EQUAL) { - rhsType = opRuleManager.getSHREqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getSHREqualResultType(node, lhsType, rhsType); } else if (node->op == AssignExprNode::OP_AND_EQUAL) { - rhsType = opRuleManager.getAndEqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getAndEqualResultType(node, lhsType, rhsType); } else if (node->op == AssignExprNode::OP_OR_EQUAL) { - rhsType = opRuleManager.getOrEqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getOrEqualResultType(node, lhsType, rhsType); } else if (node->op == AssignExprNode::OP_XOR_EQUAL) { - rhsType = opRuleManager.getXorEqualResultType(node, lhsType, rhsType, 0); + rhsType = OpRuleManager::getXorEqualResultType(node, lhsType, rhsType); } if (lhsVar) { // Variable is involved on the left side @@ -910,7 +910,7 @@ std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) { for (size_t i = 1; i < node->operands().size(); i++) { SymbolType rhsTy = std::any_cast(visit(node->operands()[i])).type; HANDLE_UNRESOLVED_TYPE_ER(rhsTy) - currentType = OpRuleManager::getLogicalOrResultType(node, currentType, rhsTy, i - 1); + currentType = OpRuleManager::getLogicalOrResultType(node, currentType, rhsTy); } return ExprResult{node->setEvaluatedSymbolType(currentType, manIdx)}; @@ -928,7 +928,7 @@ std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) { for (size_t i = 1; i < node->operands().size(); i++) { SymbolType rhsTy = std::any_cast(visit(node->operands()[i])).type; HANDLE_UNRESOLVED_TYPE_ER(rhsTy) - currentType = OpRuleManager::getLogicalAndResultType(node, currentType, rhsTy, i - 1); + currentType = OpRuleManager::getLogicalAndResultType(node, currentType, rhsTy); } return ExprResult{node->setEvaluatedSymbolType(currentType, manIdx)}; @@ -946,7 +946,7 @@ std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) { for (size_t i = 1; i < node->operands().size(); i++) { SymbolType rhsTy = std::any_cast(visit(node->operands()[i])).type; HANDLE_UNRESOLVED_TYPE_ER(rhsTy) - currentType = OpRuleManager::getBitwiseOrResultType(node, currentType, rhsTy, i - 1); + currentType = OpRuleManager::getBitwiseOrResultType(node, currentType, rhsTy); } return ExprResult{node->setEvaluatedSymbolType(currentType, manIdx)}; @@ -964,7 +964,7 @@ std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) { for (size_t i = 1; i < node->operands().size(); i++) { SymbolType rhsTy = std::any_cast(visit(node->operands()[i])).type; HANDLE_UNRESOLVED_TYPE_ER(rhsTy) - currentType = OpRuleManager::getBitwiseXorResultType(node, currentType, rhsTy, i - 1); + currentType = OpRuleManager::getBitwiseXorResultType(node, currentType, rhsTy); } return ExprResult{node->setEvaluatedSymbolType(currentType, manIdx)}; @@ -982,7 +982,7 @@ std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) { for (size_t i = 1; i < node->operands().size(); i++) { SymbolType rhsTy = std::any_cast(visit(node->operands()[i])).type; HANDLE_UNRESOLVED_TYPE_ER(rhsTy) - currentType = OpRuleManager::getBitwiseAndResultType(node, currentType, rhsTy, i - 2); + currentType = OpRuleManager::getBitwiseAndResultType(node, currentType, rhsTy); } return ExprResult{node->setEvaluatedSymbolType(currentType, manIdx)}; @@ -1030,13 +1030,13 @@ std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) { // Check operator SymbolType resultType; if (node->op == RelationalExprNode::OP_LESS) // Operator was less - resultType = OpRuleManager::getLessResultType(node, lhsTy, rhsTy, 0); + resultType = OpRuleManager::getLessResultType(node, lhsTy, rhsTy); else if (node->op == RelationalExprNode::OP_GREATER) // Operator was greater - resultType = OpRuleManager::getGreaterResultType(node, lhsTy, rhsTy, 0); + resultType = OpRuleManager::getGreaterResultType(node, lhsTy, rhsTy); else if (node->op == RelationalExprNode::OP_LESS_EQUAL) // Operator was less equal - resultType = OpRuleManager::getLessEqualResultType(node, lhsTy, rhsTy, 0); + resultType = OpRuleManager::getLessEqualResultType(node, lhsTy, rhsTy); else if (node->op == RelationalExprNode::OP_GREATER_EQUAL) // Operator was greater equal - resultType = OpRuleManager::getGreaterEqualResultType(node, lhsTy, rhsTy, 0); + resultType = OpRuleManager::getGreaterEqualResultType(node, lhsTy, rhsTy); else throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE @@ -1123,7 +1123,7 @@ std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) { else if (op == MultiplicativeExprNode::OP_DIV) currentResult = opRuleManager.getDivResultType(node, currentResult.type, operandType, i); else if (op == MultiplicativeExprNode::OP_REM) - currentResult = OpRuleManager::getRemResultType(node, currentResult.type, operandType, i); + currentResult = OpRuleManager::getRemResultType(node, currentResult.type, operandType); else throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE @@ -1155,7 +1155,7 @@ std::any TypeChecker::visitCastExpr(CastExprNode *node) { } // Get result type - SymbolType resultType = opRuleManager.getCastResultType(node, dstType, srcType, 0); + SymbolType resultType = opRuleManager.getCastResultType(node, dstType, srcType); return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)}; } @@ -1175,10 +1175,10 @@ std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { // Determine action, based on the given operator switch (node->op) { case PrefixUnaryExprNode::OP_MINUS: - operandType = OpRuleManager::getPrefixMinusResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixMinusResultType(node, operandType); break; case PrefixUnaryExprNode::OP_PLUS_PLUS: - operandType = opRuleManager.getPrefixPlusPlusResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixPlusPlusResultType(node, operandType); if (operandEntry) { // In case the lhs is captured, notify the capture about the write access @@ -1191,7 +1191,7 @@ std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { break; case PrefixUnaryExprNode::OP_MINUS_MINUS: - operandType = opRuleManager.getPrefixMinusMinusResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixMinusMinusResultType(node, operandType); if (operandEntry) { // In case the lhs is captured, notify the capture about the write access @@ -1204,16 +1204,16 @@ std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) { break; case PrefixUnaryExprNode::OP_NOT: - operandType = OpRuleManager::getPrefixNotResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixNotResultType(node, operandType); break; case PrefixUnaryExprNode::OP_BITWISE_NOT: - operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operandType); break; case PrefixUnaryExprNode::OP_DEREFERENCE: - operandType = OpRuleManager::getPrefixMulResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixMulResultType(node, operandType); break; case PrefixUnaryExprNode::OP_ADDRESS_OF: - operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operandType, 0); + operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operandType); break; default: throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE @@ -1257,10 +1257,10 @@ std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) { // Check if we have a hardcoded array index if (lhsType.is(TY_ARRAY) && lhsType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) { - std::int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; - size_t constSize = lhsType.getArraySize(); + const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue; + const unsigned int constSize = lhsType.getArraySize(); // Check if we are accessing out-of-bounds memory - if (constIndex >= constSize) { + if (constIndex >= static_cast(constSize)) { const std::string idxStr = std::to_string(constIndex); const std::string sizeStr = std::to_string(constSize); SOFT_ERROR_ER(node, ARRAY_INDEX_OUT_OF_BOUNDS, @@ -1966,7 +1966,7 @@ std::any TypeChecker::visitStructInstantiation(StructInstantiationNode *node) { const bool rhsIsImmediate = assignExpr->hasCompileTimeValue(); // Check if actual type matches expected type - opRuleManager.getFieldAssignResultType(assignExpr, expectedType, fieldResult.type, 0, rhsIsImmediate); + OpRuleManager::getFieldAssignResultType(assignExpr, expectedType, fieldResult.type, rhsIsImmediate, true); // If there is an anonymous entry attached (e.g. for struct instantiation), delete it if (fieldResult.entry != nullptr && fieldResult.entry->anonymous) { @@ -2276,7 +2276,7 @@ std::any TypeChecker::visitBaseDataType(BaseDataTypeNode *node) { std::any TypeChecker::visitCustomDataType(CustomDataTypeNode *node) { // It is a struct type -> get the access scope - Scope *localAccessScope = accessScope ?: currentScope; + Scope *localAccessScope = accessScope ? accessScope : currentScope; const bool isImported = node->typeNameFragments.size() > 1; const std::string firstFragment = node->typeNameFragments.front(); diff --git a/src/typechecker/TypeMatcher.cpp b/src/typechecker/TypeMatcher.cpp index 29b61e13a..f692f78e8 100644 --- a/src/typechecker/TypeMatcher.cpp +++ b/src/typechecker/TypeMatcher.cpp @@ -6,9 +6,6 @@ namespace spice::compiler { -#pragma clang diagnostic push -#pragma ide diagnostic ignored "misc-no-recursion" - bool TypeMatcher::matchRequestedToCandidateTypes(const std::vector &candidateTypes, const std::vector &requestedTypes, TypeMapping &typeMapping, ResolverFct &resolverFct, bool strictSpecifiers) { @@ -138,6 +135,4 @@ void TypeMatcher::substantiateTypeWithTypeMapping(SymbolType &symbolType, const } } -#pragma clang diagnostic pop - } // namespace spice::compiler \ No newline at end of file diff --git a/test/test-files/typechecker/variables/error-reassign-const-ref-var/exception.out b/test/test-files/typechecker/variables/error-reassign-const-ref-var/exception.out new file mode 100644 index 000000000..6d71267e0 --- /dev/null +++ b/test/test-files/typechecker/variables/error-reassign-const-ref-var/exception.out @@ -0,0 +1,5 @@ +[Error|Semantic] ./test-files/typechecker/variables/error-reassign-const-ref-var/source.spice:2:5: +Cannot re-assign constant variable: Trying to assign value to an immutable variable of type const bool& + +2 b = true; + ^^^^^^^^ \ No newline at end of file diff --git a/test/test-files/typechecker/variables/error-reassign-const-ref-var/source.spice b/test/test-files/typechecker/variables/error-reassign-const-ref-var/source.spice new file mode 100644 index 000000000..6e02e271e --- /dev/null +++ b/test/test-files/typechecker/variables/error-reassign-const-ref-var/source.spice @@ -0,0 +1,8 @@ +p test(const bool& b) { + b = true; +} + +f main() { + bool test = false; + test(test); +} \ No newline at end of file diff --git a/test/test-files/typechecker/variables/error-reassign-const-var/exception.out b/test/test-files/typechecker/variables/error-reassign-const-var/exception.out index 698f26791..aada96d27 100644 --- a/test/test-files/typechecker/variables/error-reassign-const-var/exception.out +++ b/test/test-files/typechecker/variables/error-reassign-const-var/exception.out @@ -1,5 +1,5 @@ [Error|Semantic] ./test-files/typechecker/variables/error-reassign-const-var/source.spice:3:5: -Cannot re-assign constant variable: Trying to assign value to a constant +Cannot re-assign constant variable: Trying to assign value to an immutable variable of type const int 3 i = 1234; ^^^^^^^^ \ No newline at end of file