GCC Code Coverage Report


Directory: ../
File: src/typechecker/TypeCheckerExpressions.cpp
Date: 2025-06-14 23:29:02
Exec Total Coverage
Lines: 397 407 97.5%
Functions: 16 16 100.0%
Branches: 676 1215 55.6%

Line Branch Exec Source
1 // Copyright (c) 2021-2025 ChilliBits. All rights reserved.
2
3 #include "TypeChecker.h"
4
5 #include <SourceFile.h>
6 #include <global/GlobalResourceManager.h>
7 #include <symboltablebuilder/SymbolTableBuilder.h>
8 #include <typechecker/MacroDefs.h>
9
10 namespace spice::compiler {
11
12 65357 std::any TypeChecker::visitAssignExpr(AssignExprNode *node) {
13 // Check if ternary
14
2/2
✓ Branch 0 (2→3) taken 59719 times.
✓ Branch 1 (2→10) taken 5638 times.
65357 if (node->ternaryExpr) {
15
3/4
✓ Branch 0 (3→4) taken 59704 times.
✓ Branch 1 (3→97) taken 15 times.
✓ Branch 2 (4→5) taken 59704 times.
✗ Branch 3 (4→95) not taken.
59719 auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr));
16
1/2
✓ Branch 0 (6→7) taken 59704 times.
✗ Branch 1 (6→98) not taken.
59704 node->setEvaluatedSymbolType(result.type, manIdx);
17
1/2
✓ Branch 0 (7→8) taken 59704 times.
✗ Branch 1 (7→98) not taken.
59704 return result;
18 }
19
20 // Check if assignment
21
1/2
✓ Branch 0 (10→11) taken 5638 times.
✗ Branch 1 (10→86) not taken.
5638 if (node->op != AssignExprNode::AssignOp::OP_NONE) {
22 // Visit the right side first
23
2/4
✓ Branch 0 (11→12) taken 5638 times.
✗ Branch 1 (11→101) not taken.
✓ Branch 2 (12→13) taken 5638 times.
✗ Branch 3 (12→99) not taken.
5638 auto rhs = std::any_cast<ExprResult>(visit(node->rhs));
24 5638 auto [rhsType, rhsEntry] = rhs;
25
5/8
✓ Branch 0 (14→15) taken 5638 times.
✗ Branch 1 (14→120) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→20) taken 5637 times.
✓ Branch 4 (16→17) taken 1 times.
✗ Branch 5 (16→102) not taken.
✓ Branch 6 (17→18) taken 1 times.
✗ Branch 7 (17→102) not taken.
5638 HANDLE_UNRESOLVED_TYPE_ER(rhsType)
26 // Then visit the left side
27
2/4
✓ Branch 0 (20→21) taken 5637 times.
✗ Branch 1 (20→105) not taken.
✓ Branch 2 (21→22) taken 5637 times.
✗ Branch 3 (21→103) not taken.
5637 auto lhs = std::any_cast<ExprResult>(visit(node->lhs));
28 5637 auto [lhsType, lhsVar] = lhs;
29
5/8
✓ Branch 0 (23→24) taken 5637 times.
✗ Branch 1 (23→120) not taken.
✓ Branch 2 (24→25) taken 1 times.
✓ Branch 3 (24→29) taken 5636 times.
✓ Branch 4 (25→26) taken 1 times.
✗ Branch 5 (25→106) not taken.
✓ Branch 6 (26→27) taken 1 times.
✗ Branch 7 (26→106) not taken.
5637 HANDLE_UNRESOLVED_TYPE_ER(lhsType)
30
31 // Take a look at the operator
32
2/2
✓ Branch 0 (29→30) taken 5025 times.
✓ Branch 1 (29→42) taken 611 times.
5636 if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) {
33
8/10
✓ Branch 0 (30→31) taken 5024 times.
✓ Branch 1 (30→37) taken 1 times.
✓ Branch 2 (31→32) taken 5024 times.
✗ Branch 3 (31→120) not taken.
✓ Branch 4 (32→33) taken 4011 times.
✓ Branch 5 (32→37) taken 1013 times.
✓ Branch 6 (34→35) taken 4011 times.
✗ Branch 7 (34→120) not taken.
✓ Branch 8 (35→36) taken 1295 times.
✓ Branch 9 (35→37) taken 2716 times.
5025 const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized();
34
2/2
✓ Branch 0 (38→39) taken 5024 times.
✓ Branch 1 (38→107) taken 1 times.
5025 rhsType = opRuleManager.getAssignResultType(node, lhs, rhs, isDecl).first;
35
36 // If there is an anonymous entry attached (e.g. for struct instantiation), delete it
37
4/4
✓ Branch 0 (39→40) taken 2345 times.
✓ Branch 1 (39→72) taken 2679 times.
✓ Branch 2 (40→41) taken 146 times.
✓ Branch 3 (40→72) taken 2199 times.
5024 if (rhsEntry != nullptr && rhsEntry->anonymous)
38
1/2
✓ Branch 0 (41→72) taken 146 times.
✗ Branch 1 (41→120) not taken.
146 currentScope->symbolTable.deleteAnonymous(rhsEntry->name);
39
2/2
✓ Branch 0 (42→43) taken 248 times.
✓ Branch 1 (42→45) taken 363 times.
611 } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) {
40
1/2
✓ Branch 0 (43→44) taken 248 times.
✗ Branch 1 (43→108) not taken.
248 rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type;
41
2/2
✓ Branch 0 (45→46) taken 33 times.
✓ Branch 1 (45→48) taken 330 times.
363 } else if (node->op == AssignExprNode::AssignOp::OP_MINUS_EQUAL) {
42
1/2
✓ Branch 0 (46→47) taken 33 times.
✗ Branch 1 (46→109) not taken.
33 rhsType = opRuleManager.getMinusEqualResultType(node, lhs, rhs, 0).type;
43
2/2
✓ Branch 0 (48→49) taken 19 times.
✓ Branch 1 (48→51) taken 311 times.
330 } else if (node->op == AssignExprNode::AssignOp::OP_MUL_EQUAL) {
44
1/2
✓ Branch 0 (49→50) taken 19 times.
✗ Branch 1 (49→110) not taken.
19 rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type;
45
2/2
✓ Branch 0 (51→52) taken 45 times.
✓ Branch 1 (51→54) taken 266 times.
311 } else if (node->op == AssignExprNode::AssignOp::OP_DIV_EQUAL) {
46
1/2
✓ Branch 0 (52→53) taken 45 times.
✗ Branch 1 (52→111) not taken.
45 rhsType = opRuleManager.getDivEqualResultType(node, lhs, rhs, 0).type;
47
2/2
✓ Branch 0 (54→55) taken 6 times.
✓ Branch 1 (54→57) taken 260 times.
266 } else if (node->op == AssignExprNode::AssignOp::OP_REM_EQUAL) {
48
1/2
✓ Branch 0 (55→56) taken 6 times.
✗ Branch 1 (55→112) not taken.
6 rhsType = opRuleManager.getRemEqualResultType(node, lhs, rhs);
49
2/2
✓ Branch 0 (57→58) taken 2 times.
✓ Branch 1 (57→60) taken 258 times.
260 } else if (node->op == AssignExprNode::AssignOp::OP_SHL_EQUAL) {
50
1/2
✓ Branch 0 (58→59) taken 2 times.
✗ Branch 1 (58→113) not taken.
2 rhsType = opRuleManager.getSHLEqualResultType(node, lhs, rhs);
51
2/2
✓ Branch 0 (60→61) taken 3 times.
✓ Branch 1 (60→63) taken 255 times.
258 } else if (node->op == AssignExprNode::AssignOp::OP_SHR_EQUAL) {
52
1/2
✓ Branch 0 (61→62) taken 3 times.
✗ Branch 1 (61→114) not taken.
3 rhsType = opRuleManager.getSHREqualResultType(node, lhs, rhs);
53
2/2
✓ Branch 0 (63→64) taken 1 times.
✓ Branch 1 (63→66) taken 254 times.
255 } else if (node->op == AssignExprNode::AssignOp::OP_AND_EQUAL) {
54
1/2
✓ Branch 0 (64→65) taken 1 times.
✗ Branch 1 (64→115) not taken.
1 rhsType = opRuleManager.getAndEqualResultType(node, lhs, rhs);
55
2/2
✓ Branch 0 (66→67) taken 1 times.
✓ Branch 1 (66→69) taken 253 times.
254 } else if (node->op == AssignExprNode::AssignOp::OP_OR_EQUAL) {
56
1/2
✓ Branch 0 (67→68) taken 1 times.
✗ Branch 1 (67→116) not taken.
1 rhsType = opRuleManager.getOrEqualResultType(node, lhs, rhs);
57
1/2
✓ Branch 0 (69→70) taken 253 times.
✗ Branch 1 (69→72) not taken.
253 } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) {
58
1/2
✓ Branch 0 (70→71) taken 253 times.
✗ Branch 1 (70→117) not taken.
253 rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs);
59 }
60
61
1/2
✓ Branch 0 (72→73) taken 5635 times.
✗ Branch 1 (72→81) not taken.
5635 if (lhsVar) { // Variable is involved on the left side
62 // Perform type inference
63
3/4
✓ Branch 0 (73→74) taken 5635 times.
✗ Branch 1 (73→120) not taken.
✓ Branch 2 (74→75) taken 1 times.
✓ Branch 3 (74→76) taken 5634 times.
5635 if (lhsType.is(TY_DYN))
64
1/2
✓ Branch 0 (75→76) taken 1 times.
✗ Branch 1 (75→120) not taken.
1 lhsVar->updateType(rhsType, false);
65
66 // In case the lhs variable is captured, notify the capture about the write access
67
3/4
✓ Branch 0 (76→77) taken 5635 times.
✗ Branch 1 (76→120) not taken.
✓ Branch 2 (77→78) taken 3 times.
✓ Branch 3 (77→79) taken 5632 times.
5635 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(lhsVar->name); lhsCapture)
68
1/2
✓ Branch 0 (78→79) taken 3 times.
✗ Branch 1 (78→120) not taken.
3 lhsCapture->setAccessType(READ_WRITE);
69
70 // Update the state of the variable
71
1/2
✓ Branch 0 (79→80) taken 5635 times.
✗ Branch 1 (79→118) not taken.
5635 lhsVar->updateState(INITIALIZED, node);
72 }
73
74
2/4
✓ Branch 0 (81→82) taken 5635 times.
✗ Branch 1 (81→119) not taken.
✓ Branch 2 (82→83) taken 5635 times.
✗ Branch 3 (82→119) not taken.
5635 return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)};
75 }
76
77 throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE
78 }
79
80 60347 std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) {
81 // Check if there is a ternary operator applied
82
2/2
✓ Branch 0 (2→3) taken 59977 times.
✓ Branch 1 (2→5) taken 370 times.
60347 if (!node->falseExpr)
83
2/2
✓ Branch 0 (3→4) taken 59962 times.
✓ Branch 1 (3→150) taken 15 times.
59977 return visit(node->condition);
84
85 // Visit condition
86
2/4
✓ Branch 0 (5→6) taken 370 times.
✗ Branch 1 (5→115) not taken.
✓ Branch 2 (6→7) taken 370 times.
✗ Branch 3 (6→113) not taken.
370 const auto condition = std::any_cast<ExprResult>(visit(node->condition));
87
2/8
✓ Branch 0 (8→9) taken 370 times.
✗ Branch 1 (8→150) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 370 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→116) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→116) not taken.
370 HANDLE_UNRESOLVED_TYPE_ER(condition.type)
88
6/10
✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→16) taken 369 times.
✓ Branch 2 (16→17) taken 369 times.
✗ Branch 3 (16→117) not taken.
✓ Branch 4 (17→18) taken 369 times.
✗ Branch 5 (17→117) not taken.
✓ Branch 6 (18→19) taken 369 times.
✓ Branch 7 (18→20) taken 1 times.
✗ Branch 8 (117→118) not taken.
✗ Branch 9 (117→119) not taken.
370 const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr));
89 370 const auto [trueType, trueEntry] = trueExpr;
90
2/8
✓ Branch 0 (20→21) taken 370 times.
✗ Branch 1 (20→150) not taken.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→26) taken 370 times.
✗ Branch 4 (22→23) not taken.
✗ Branch 5 (22→121) not taken.
✗ Branch 6 (23→24) not taken.
✗ Branch 7 (23→121) not taken.
370 HANDLE_UNRESOLVED_TYPE_ER(trueType)
91
2/4
✓ Branch 0 (26→27) taken 370 times.
✗ Branch 1 (26→124) not taken.
✓ Branch 2 (27→28) taken 370 times.
✗ Branch 3 (27→122) not taken.
370 const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr));
92 370 const auto [falseType, falseEntry] = falseExpr;
93
2/8
✓ Branch 0 (29→30) taken 370 times.
✗ Branch 1 (29→150) not taken.
✗ Branch 2 (30→31) not taken.
✓ Branch 3 (30→35) taken 370 times.
✗ Branch 4 (31→32) not taken.
✗ Branch 5 (31→125) not taken.
✗ Branch 6 (32→33) not taken.
✗ Branch 7 (32→125) not taken.
370 HANDLE_UNRESOLVED_TYPE_ER(falseType)
94
95 // Check if the condition evaluates to bool
96
3/4
✓ Branch 0 (35→36) taken 370 times.
✗ Branch 1 (35→150) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→47) taken 369 times.
370 if (!condition.type.is(TY_BOOL))
97
4/8
✓ Branch 0 (39→40) taken 1 times.
✗ Branch 1 (39→128) not taken.
✓ Branch 2 (40→41) taken 1 times.
✗ Branch 3 (40→126) not taken.
✓ Branch 4 (43→44) taken 1 times.
✗ Branch 5 (43→132) not taken.
✓ Branch 6 (44→45) taken 1 times.
✗ Branch 7 (44→132) not taken.
3 SOFT_ERROR_ER(node->condition, OPERATOR_WRONG_DATA_TYPE, "Condition operand in ternary must be a bool")
98
99 // Check if trueType and falseType are matching
100
1/2
✓ Branch 0 (47→48) taken 369 times.
✗ Branch 1 (47→150) not taken.
369 const QualType trueTypeModified = trueType.removeReferenceWrapper();
101
1/2
✓ Branch 0 (48→49) taken 369 times.
✗ Branch 1 (48→150) not taken.
369 const QualType falseTypeModified = falseType.removeReferenceWrapper();
102
3/4
✓ Branch 0 (49→50) taken 369 times.
✗ Branch 1 (49→150) not taken.
✓ Branch 2 (50→51) taken 1 times.
✓ Branch 3 (50→66) taken 368 times.
369 if (!trueTypeModified.matches(falseTypeModified, false, true, false))
103
8/16
✓ Branch 0 (51→52) taken 1 times.
✗ Branch 1 (51→146) not taken.
✓ Branch 2 (52→53) taken 1 times.
✗ Branch 3 (52→141) not taken.
✓ Branch 4 (53→54) taken 1 times.
✗ Branch 5 (53→139) not taken.
✓ Branch 6 (54→55) taken 1 times.
✗ Branch 7 (54→137) not taken.
✓ Branch 8 (55→56) taken 1 times.
✗ Branch 9 (55→135) not taken.
✓ Branch 10 (56→57) taken 1 times.
✗ Branch 11 (56→133) not taken.
✓ Branch 12 (62→63) taken 1 times.
✗ Branch 13 (62→148) not taken.
✓ Branch 14 (63→64) taken 1 times.
✗ Branch 15 (63→148) not taken.
1 SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE,
104 "True and false operands in ternary must be of same data type. Got " + trueType.getName(true) + " and " +
105 falseType.getName(true))
106
107 // If there is an anonymous symbol attached to left or right, remove it,
108 // since the result takes over the ownership of any destructible object.
109 368 bool removedAnonymousSymbols = false;
110
2/2
✓ Branch 0 (66→67) taken 115 times.
✓ Branch 1 (66→78) taken 253 times.
368 if (trueEntry) {
111
2/2
✓ Branch 0 (67→68) taken 68 times.
✓ Branch 1 (67→70) taken 47 times.
115 if (trueEntry->anonymous) {
112
1/2
✓ Branch 0 (68→69) taken 68 times.
✗ Branch 1 (68→150) not taken.
68 currentScope->symbolTable.deleteAnonymous(trueEntry->name);
113 68 removedAnonymousSymbols = true;
114
8/10
✓ Branch 0 (70→71) taken 47 times.
✗ Branch 1 (70→150) not taken.
✓ Branch 2 (71→72) taken 39 times.
✓ Branch 3 (71→75) taken 8 times.
✓ Branch 4 (72→73) taken 39 times.
✗ Branch 5 (72→150) not taken.
✓ Branch 6 (73→74) taken 8 times.
✓ Branch 7 (73→75) taken 31 times.
✓ Branch 8 (76→77) taken 8 times.
✓ Branch 9 (76→78) taken 39 times.
47 } else if (!trueType.isRef() && !trueType.isTriviallyCopyable(node)) {
115 8 node->trueSideCallsCopyCtor = true;
116 }
117 }
118
2/2
✓ Branch 0 (78→79) taken 293 times.
✓ Branch 1 (78→90) taken 75 times.
368 if (falseEntry) {
119
2/2
✓ Branch 0 (79→80) taken 67 times.
✓ Branch 1 (79→82) taken 226 times.
293 if (falseEntry->anonymous) {
120
1/2
✓ Branch 0 (80→81) taken 67 times.
✗ Branch 1 (80→150) not taken.
67 currentScope->symbolTable.deleteAnonymous(falseEntry->name);
121 67 removedAnonymousSymbols = true;
122
8/10
✓ Branch 0 (82→83) taken 226 times.
✗ Branch 1 (82→150) not taken.
✓ Branch 2 (83→84) taken 217 times.
✓ Branch 3 (83→87) taken 9 times.
✓ Branch 4 (84→85) taken 217 times.
✗ Branch 5 (84→150) not taken.
✓ Branch 6 (85→86) taken 8 times.
✓ Branch 7 (85→87) taken 209 times.
✓ Branch 8 (88→89) taken 8 times.
✓ Branch 9 (88→90) taken 218 times.
226 } else if (!falseType.isRef() && !falseType.isTriviallyCopyable(node)) {
123 8 node->falseSideCallsCopyCtor = true;
124 }
125 }
126
127 // Create a new anonymous symbol for the result if required
128 368 const QualType &resultType = trueType;
129 368 SymbolTableEntry *anonymousSymbol = nullptr;
130
4/4
✓ Branch 0 (90→91) taken 360 times.
✓ Branch 1 (90→92) taken 8 times.
✓ Branch 2 (91→92) taken 2 times.
✓ Branch 3 (91→93) taken 358 times.
368 const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor;
131
9/10
✓ Branch 0 (94→95) taken 298 times.
✓ Branch 1 (94→98) taken 70 times.
✓ Branch 2 (95→96) taken 292 times.
✓ Branch 3 (95→98) taken 6 times.
✓ Branch 4 (96→97) taken 292 times.
✗ Branch 5 (96→150) not taken.
✓ Branch 6 (97→98) taken 8 times.
✓ Branch 7 (97→99) taken 284 times.
✓ Branch 8 (100→101) taken 84 times.
✓ Branch 9 (100→103) taken 284 times.
368 if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef())
132
1/2
✓ Branch 0 (101→102) taken 84 times.
✗ Branch 1 (101→150) not taken.
84 anonymousSymbol = currentScope->symbolTable.insertAnonymous(resultType, node);
133
134 // Look up the copy ctor if at least one side needs it
135
4/4
✓ Branch 0 (103→104) taken 360 times.
✓ Branch 1 (103→105) taken 8 times.
✓ Branch 2 (104→105) taken 2 times.
✓ Branch 3 (104→107) taken 358 times.
368 if (node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor)
136
1/2
✓ Branch 0 (105→106) taken 10 times.
✗ Branch 1 (105→150) not taken.
10 node->calledCopyCtor = matchCopyCtor(trueTypeModified, node);
137
138
2/4
✓ Branch 0 (107→108) taken 368 times.
✗ Branch 1 (107→149) not taken.
✓ Branch 2 (108→109) taken 368 times.
✗ Branch 3 (108→149) not taken.
368 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol};
139 }
140
141 61086 std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) {
142 // Check if a logical or operator is applied
143
2/2
✓ Branch 0 (3→4) taken 60231 times.
✓ Branch 1 (3→7) taken 855 times.
61086 if (node->operands.size() == 1)
144
2/2
✓ Branch 0 (5→6) taken 60217 times.
✓ Branch 1 (5→46) taken 14 times.
60231 return visit(node->operands.front());
145
146 // Visit leftmost operand
147
2/4
✓ Branch 0 (8→9) taken 855 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 855 times.
✗ Branch 3 (9→37) not taken.
855 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
148
2/8
✓ Branch 0 (11→12) taken 855 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 855 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
855 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
149
150 // Loop through all remaining operands
151
2/2
✓ Branch 0 (31→18) taken 1098 times.
✓ Branch 1 (31→32) taken 854 times.
1952 for (size_t i = 1; i < node->operands.size(); i++) {
152
2/4
✓ Branch 0 (19→20) taken 1098 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 1098 times.
✗ Branch 3 (20→41) not taken.
1098 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
153
2/8
✓ Branch 0 (22→23) taken 1098 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 1098 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
1098 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
154
2/2
✓ Branch 0 (28→29) taken 1097 times.
✓ Branch 1 (28→45) taken 1 times.
1098 currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)};
155 }
156
157
1/2
✓ Branch 0 (32→33) taken 854 times.
✗ Branch 1 (32→46) not taken.
854 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
158
1/2
✓ Branch 0 (33→34) taken 854 times.
✗ Branch 1 (33→46) not taken.
854 return currentOperand;
159 }
160
161 62184 std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) {
162 // Check if a logical and operator is applied
163
2/2
✓ Branch 0 (3→4) taken 62038 times.
✓ Branch 1 (3→7) taken 146 times.
62184 if (node->operands.size() == 1)
164
2/2
✓ Branch 0 (5→6) taken 62024 times.
✓ Branch 1 (5→46) taken 14 times.
62038 return visit(node->operands.front());
165
166 // Visit leftmost operand
167
2/4
✓ Branch 0 (8→9) taken 146 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 146 times.
✗ Branch 3 (9→37) not taken.
146 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
168
2/8
✓ Branch 0 (11→12) taken 146 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 146 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
146 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
169
170 // Loop through all remaining operands
171
2/2
✓ Branch 0 (31→18) taken 181 times.
✓ Branch 1 (31→32) taken 146 times.
327 for (size_t i = 1; i < node->operands.size(); i++) {
172
2/4
✓ Branch 0 (19→20) taken 181 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 181 times.
✗ Branch 3 (20→41) not taken.
181 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
173
2/8
✓ Branch 0 (22→23) taken 181 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 181 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
181 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
174
1/2
✓ Branch 0 (28→29) taken 181 times.
✗ Branch 1 (28→45) not taken.
181 currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)};
175 }
176
177
1/2
✓ Branch 0 (32→33) taken 146 times.
✗ Branch 1 (32→46) not taken.
146 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
178
1/2
✓ Branch 0 (33→34) taken 146 times.
✗ Branch 1 (33→46) not taken.
146 return currentOperand;
179 }
180
181 62365 std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) {
182 // Check if a bitwise or operator is applied
183
2/2
✓ Branch 0 (3→4) taken 62298 times.
✓ Branch 1 (3→7) taken 67 times.
62365 if (node->operands.size() == 1)
184
2/2
✓ Branch 0 (5→6) taken 62285 times.
✓ Branch 1 (5→46) taken 13 times.
62298 return visit(node->operands.front());
185
186 // Visit leftmost operand
187
2/4
✓ Branch 0 (8→9) taken 67 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 67 times.
✗ Branch 3 (9→37) not taken.
67 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
188
2/8
✓ Branch 0 (11→12) taken 67 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 67 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
67 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
189
190 // Loop through all remaining operands
191
2/2
✓ Branch 0 (31→18) taken 70 times.
✓ Branch 1 (31→32) taken 66 times.
136 for (size_t i = 1; i < node->operands.size(); i++) {
192
2/4
✓ Branch 0 (19→20) taken 70 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 70 times.
✗ Branch 3 (20→41) not taken.
70 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
193
2/8
✓ Branch 0 (22→23) taken 70 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 70 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
70 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
194
2/2
✓ Branch 0 (28→29) taken 69 times.
✓ Branch 1 (28→45) taken 1 times.
70 currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)};
195 }
196
197
1/2
✓ Branch 0 (32→33) taken 66 times.
✗ Branch 1 (32→46) not taken.
66 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
198
1/2
✓ Branch 0 (33→34) taken 66 times.
✗ Branch 1 (33→46) not taken.
66 return currentOperand;
199 }
200
201 62435 std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) {
202 // Check if a bitwise xor operator is applied
203
2/2
✓ Branch 0 (3→4) taken 62431 times.
✓ Branch 1 (3→7) taken 4 times.
62435 if (node->operands.size() == 1)
204
2/2
✓ Branch 0 (5→6) taken 62418 times.
✓ Branch 1 (5→46) taken 13 times.
62431 return visit(node->operands.front());
205
206 // Visit leftmost operand
207
2/4
✓ Branch 0 (8→9) taken 4 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 4 times.
✗ Branch 3 (9→37) not taken.
4 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
208
2/8
✓ Branch 0 (11→12) taken 4 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
4 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
209
210 // Loop through all remaining operands
211
2/2
✓ Branch 0 (31→18) taken 7 times.
✓ Branch 1 (31→32) taken 4 times.
11 for (size_t i = 1; i < node->operands.size(); i++) {
212
2/4
✓ Branch 0 (19→20) taken 7 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 7 times.
✗ Branch 3 (20→41) not taken.
7 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
213
2/8
✓ Branch 0 (22→23) taken 7 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 7 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
7 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
214
1/2
✓ Branch 0 (28→29) taken 7 times.
✗ Branch 1 (28→45) not taken.
7 currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)};
215 }
216
217
1/2
✓ Branch 0 (32→33) taken 4 times.
✗ Branch 1 (32→46) not taken.
4 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
218
1/2
✓ Branch 0 (33→34) taken 4 times.
✗ Branch 1 (33→46) not taken.
4 return currentOperand;
219 }
220
221 62442 std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) {
222 // Check if a bitwise and operator is applied
223
2/2
✓ Branch 0 (3→4) taken 62410 times.
✓ Branch 1 (3→7) taken 32 times.
62442 if (node->operands.size() == 1)
224
2/2
✓ Branch 0 (5→6) taken 62397 times.
✓ Branch 1 (5→46) taken 13 times.
62410 return visit(node->operands.front());
225
226 // Visit leftmost operand
227
2/4
✓ Branch 0 (8→9) taken 32 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 32 times.
✗ Branch 3 (9→37) not taken.
32 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
228
2/8
✓ Branch 0 (11→12) taken 32 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 32 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→40) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→40) not taken.
32 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
229
230 // Loop through all remaining operands
231
2/2
✓ Branch 0 (31→18) taken 35 times.
✓ Branch 1 (31→32) taken 32 times.
67 for (size_t i = 1; i < node->operands.size(); i++) {
232
2/4
✓ Branch 0 (19→20) taken 35 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 35 times.
✗ Branch 3 (20→41) not taken.
35 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
233
2/8
✓ Branch 0 (22→23) taken 35 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 35 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→44) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→44) not taken.
35 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
234
1/2
✓ Branch 0 (28→29) taken 35 times.
✗ Branch 1 (28→45) not taken.
35 currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)};
235 }
236
237
1/2
✓ Branch 0 (32→33) taken 32 times.
✗ Branch 1 (32→46) not taken.
32 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
238
1/2
✓ Branch 0 (33→34) taken 32 times.
✗ Branch 1 (33→46) not taken.
32 return currentOperand;
239 }
240
241 62477 std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) {
242 // Check if at least one equality operator is applied
243
2/2
✓ Branch 0 (3→4) taken 57722 times.
✓ Branch 1 (3→7) taken 4755 times.
62477 if (node->operands.size() == 1)
244
2/2
✓ Branch 0 (5→6) taken 57710 times.
✓ Branch 1 (5→73) taken 12 times.
57722 return visit(node->operands.front());
245
246 // Visit right side first, then left side
247
2/4
✓ Branch 0 (8→9) taken 4755 times.
✗ Branch 1 (8→58) not taken.
✓ Branch 2 (9→10) taken 4755 times.
✗ Branch 3 (9→56) not taken.
4755 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
248
2/8
✓ Branch 0 (11→12) taken 4755 times.
✗ Branch 1 (11→73) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4755 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→59) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→59) not taken.
4755 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
249
2/4
✓ Branch 0 (18→19) taken 4755 times.
✗ Branch 1 (18→62) not taken.
✓ Branch 2 (19→20) taken 4755 times.
✗ Branch 3 (19→60) not taken.
4755 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
250
2/8
✓ Branch 0 (21→22) taken 4755 times.
✗ Branch 1 (21→73) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 4755 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→63) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→63) not taken.
4755 HANDLE_UNRESOLVED_TYPE_ER(lhs.type)
251
252 // Check if we need the string runtime to perform a string comparison
253
10/14
✓ Branch 0 (27→28) taken 4755 times.
✗ Branch 1 (27→73) not taken.
✓ Branch 2 (28→29) taken 115 times.
✓ Branch 3 (28→36) taken 4640 times.
✓ Branch 4 (29→30) taken 115 times.
✗ Branch 5 (29→73) not taken.
✓ Branch 6 (30→31) taken 114 times.
✓ Branch 7 (30→36) taken 1 times.
✓ Branch 8 (31→32) taken 114 times.
✗ Branch 9 (31→73) not taken.
✓ Branch 10 (34→35) taken 114 times.
✗ Branch 11 (34→36) not taken.
✓ Branch 12 (37→38) taken 114 times.
✓ Branch 13 (37→39) taken 4641 times.
4869 if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT())
254
1/2
✓ Branch 0 (38→39) taken 114 times.
✗ Branch 1 (38→73) not taken.
114 sourceFile->requestRuntimeModule(STRING_RT);
255
256 // Check operator
257 4755 ExprResult result;
258
2/2
✓ Branch 0 (39→40) taken 3377 times.
✓ Branch 1 (39→41) taken 1378 times.
4755 if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal
259
2/2
✓ Branch 0 (40→51) taken 3376 times.
✓ Branch 1 (40→73) taken 1 times.
3377 result = opRuleManager.getEqualResultType(node, lhs, rhs, 0);
260
1/2
✓ Branch 0 (41→42) taken 1378 times.
✗ Branch 1 (41→43) not taken.
1378 else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal
261
1/2
✓ Branch 0 (42→51) taken 1378 times.
✗ Branch 1 (42→73) not taken.
1378 result = opRuleManager.getNotEqualResultType(node, lhs, rhs, 0);
262 else
263 throw CompilerError(UNHANDLED_BRANCH, "EqualityExpr fall-through"); // GCOV_EXCL_LINE
264
265
1/2
✓ Branch 0 (51→52) taken 4754 times.
✗ Branch 1 (51→73) not taken.
4754 node->setEvaluatedSymbolType(result.type, manIdx);
266
1/2
✓ Branch 0 (52→53) taken 4754 times.
✗ Branch 1 (52→73) not taken.
4754 return result;
267 }
268
269 67232 std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) {
270 // Check if a relational operator is applied
271
2/2
✓ Branch 0 (3→4) taken 63805 times.
✓ Branch 1 (3→7) taken 3427 times.
67232 if (node->operands.size() == 1)
272
2/2
✓ Branch 0 (5→6) taken 63794 times.
✓ Branch 1 (5→75) taken 11 times.
63805 return visit(node->operands.front());
273
274 // Visit right side first, then left side
275
2/4
✓ Branch 0 (8→9) taken 3427 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 3427 times.
✗ Branch 3 (9→53) not taken.
3427 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
276
5/8
✓ Branch 0 (11→12) taken 3427 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→17) taken 3426 times.
✓ Branch 4 (13→14) taken 1 times.
✗ Branch 5 (13→56) not taken.
✓ Branch 6 (14→15) taken 1 times.
✗ Branch 7 (14→56) not taken.
3427 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
277
2/4
✓ Branch 0 (18→19) taken 3426 times.
✗ Branch 1 (18→59) not taken.
✓ Branch 2 (19→20) taken 3426 times.
✗ Branch 3 (19→57) not taken.
3426 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
278
2/8
✓ Branch 0 (21→22) taken 3426 times.
✗ Branch 1 (21→75) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 3426 times.
✗ Branch 4 (23→24) not taken.
✗ Branch 5 (23→60) not taken.
✗ Branch 6 (24→25) not taken.
✗ Branch 7 (24→60) not taken.
3426 HANDLE_UNRESOLVED_TYPE_ER(lhs.type)
279
280 // Check operator
281 3426 QualType resultType;
282
2/2
✓ Branch 0 (27→28) taken 1707 times.
✓ Branch 1 (27→30) taken 1719 times.
3426 if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less
283
1/2
✓ Branch 0 (28→29) taken 1707 times.
✗ Branch 1 (28→61) not taken.
1707 resultType = OpRuleManager::getLessResultType(node, lhs, rhs);
284
2/2
✓ Branch 0 (30→31) taken 477 times.
✓ Branch 1 (30→33) taken 1242 times.
1719 else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER) // Operator was greater
285
2/2
✓ Branch 0 (31→32) taken 476 times.
✓ Branch 1 (31→62) taken 1 times.
477 resultType = OpRuleManager::getGreaterResultType(node, lhs, rhs);
286
2/2
✓ Branch 0 (33→34) taken 361 times.
✓ Branch 1 (33→36) taken 881 times.
1242 else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal
287
1/2
✓ Branch 0 (34→35) taken 361 times.
✗ Branch 1 (34→63) not taken.
361 resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs);
288
1/2
✓ Branch 0 (36→37) taken 881 times.
✗ Branch 1 (36→39) not taken.
881 else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal
289
1/2
✓ Branch 0 (37→38) taken 881 times.
✗ Branch 1 (37→64) not taken.
881 resultType = OpRuleManager::getGreaterEqualResultType(node, lhs, rhs);
290 else
291 throw CompilerError(UNHANDLED_BRANCH, "RelationalExpr fall-through"); // GCOV_EXCL_LINE
292
293
2/4
✓ Branch 0 (47→48) taken 3425 times.
✗ Branch 1 (47→74) not taken.
✓ Branch 2 (48→49) taken 3425 times.
✗ Branch 3 (48→74) not taken.
3425 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)};
294 }
295
296 70658 std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) {
297 // Check if at least one shift operator is applied
298
2/2
✓ Branch 0 (3→4) taken 70596 times.
✓ Branch 1 (3→7) taken 62 times.
70658 if (node->operands.size() == 1)
299
2/2
✓ Branch 0 (5→6) taken 70585 times.
✓ Branch 1 (5→69) taken 11 times.
70596 return visit(node->operands.front());
300
301 // Visit leftmost operand
302
2/4
✓ Branch 0 (8→9) taken 62 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 62 times.
✗ Branch 3 (9→51) not taken.
62 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
303
2/8
✓ Branch 0 (11→12) taken 62 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 62 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
62 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
304
305 // Loop through remaining operands
306
2/2
✓ Branch 0 (45→18) taken 102 times.
✓ Branch 1 (45→46) taken 62 times.
164 for (size_t i = 0; i < node->opQueue.size(); i++) {
307
2/4
✓ Branch 0 (19→20) taken 102 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 102 times.
✗ Branch 3 (20→55) not taken.
102 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
308
2/8
✓ Branch 0 (22→23) taken 102 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 102 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
102 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
309
310 // Check operator
311 102 const ShiftExprNode::ShiftOp &op = node->opQueue.front().first;
312
2/2
✓ Branch 0 (29→30) taken 95 times.
✓ Branch 1 (29→31) taken 7 times.
102 if (op == ShiftExprNode::ShiftOp::OP_SHIFT_LEFT)
313
1/2
✓ Branch 0 (30→41) taken 95 times.
✗ Branch 1 (30→68) not taken.
95 currentResult = opRuleManager.getShiftLeftResultType(node, currentResult, operandResult, i);
314
1/2
✓ Branch 0 (31→32) taken 7 times.
✗ Branch 1 (31→33) not taken.
7 else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT)
315
1/2
✓ Branch 0 (32→41) taken 7 times.
✗ Branch 1 (32→68) not taken.
7 currentResult = opRuleManager.getShiftRightResultType(node, currentResult, operandResult, i);
316 else
317 throw CompilerError(UNHANDLED_BRANCH, "ShiftExpr fall-through"); // GCOV_EXCL_LINE
318
319 // Push the new item and pop the old one on the other side of the queue
320
1/2
✓ Branch 0 (41→42) taken 102 times.
✗ Branch 1 (41→68) not taken.
102 node->opQueue.emplace(op, currentResult.type);
321 102 node->opQueue.pop();
322 }
323
324
1/2
✓ Branch 0 (46→47) taken 62 times.
✗ Branch 1 (46→69) not taken.
62 node->setEvaluatedSymbolType(currentResult.type, manIdx);
325
1/2
✓ Branch 0 (47→48) taken 62 times.
✗ Branch 1 (47→69) not taken.
62 return currentResult;
326 }
327
328 70760 std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) {
329 // Check if at least one additive operator is applied
330
2/2
✓ Branch 0 (3→4) taken 66919 times.
✓ Branch 1 (3→7) taken 3841 times.
70760 if (node->operands.size() == 1)
331
2/2
✓ Branch 0 (5→6) taken 66909 times.
✓ Branch 1 (5→69) taken 10 times.
66919 return visit(node->operands.front());
332
333 // Visit leftmost operand
334
2/4
✓ Branch 0 (8→9) taken 3841 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 3841 times.
✗ Branch 3 (9→51) not taken.
3841 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
335
2/8
✓ Branch 0 (11→12) taken 3841 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 3841 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→54) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→54) not taken.
3841 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
336
337 // Loop through remaining operands
338
2/2
✓ Branch 0 (45→18) taken 4388 times.
✓ Branch 1 (45→46) taken 3840 times.
8228 for (size_t i = 0; i < node->opQueue.size(); i++) {
339
2/4
✓ Branch 0 (19→20) taken 4388 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 4388 times.
✗ Branch 3 (20→55) not taken.
4388 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
340
2/8
✓ Branch 0 (22→23) taken 4388 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 4388 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→58) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→58) not taken.
4388 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
341
342 // Check operator
343 4388 const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first;
344
2/2
✓ Branch 0 (29→30) taken 2638 times.
✓ Branch 1 (29→31) taken 1750 times.
4388 if (op == AdditiveExprNode::AdditiveOp::OP_PLUS)
345
2/2
✓ Branch 0 (30→41) taken 2637 times.
✓ Branch 1 (30→68) taken 1 times.
2638 currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i);
346
1/2
✓ Branch 0 (31→32) taken 1750 times.
✗ Branch 1 (31→33) not taken.
1750 else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS)
347
1/2
✓ Branch 0 (32→41) taken 1750 times.
✗ Branch 1 (32→68) not taken.
1750 currentResult = opRuleManager.getMinusResultType(node, currentResult, operandResult, i);
348 else
349 throw CompilerError(UNHANDLED_BRANCH, "AdditiveExpr fall-through"); // GCOV_EXCL_LINE
350
351 // Push the new item and pop the old one on the other side of the queue
352
1/2
✓ Branch 0 (41→42) taken 4387 times.
✗ Branch 1 (41→68) not taken.
4387 node->opQueue.emplace(op, currentResult.type);
353 4387 node->opQueue.pop();
354 }
355
356
1/2
✓ Branch 0 (46→47) taken 3840 times.
✗ Branch 1 (46→69) not taken.
3840 node->setEvaluatedSymbolType(currentResult.type, manIdx);
357
1/2
✓ Branch 0 (47→48) taken 3840 times.
✗ Branch 1 (47→69) not taken.
3840 return currentResult;
358 }
359
360 75148 std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) {
361 // Check if at least one multiplicative operator is applied
362
2/2
✓ Branch 0 (3→4) taken 74323 times.
✓ Branch 1 (3→7) taken 825 times.
75148 if (node->operands.size() == 1)
363
2/2
✓ Branch 0 (5→6) taken 74314 times.
✓ Branch 1 (5→71) taken 9 times.
74323 return visit(node->operands.front());
364
365 // Visit leftmost operand
366
2/4
✓ Branch 0 (8→9) taken 825 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 825 times.
✗ Branch 3 (9→53) not taken.
825 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
367
2/8
✓ Branch 0 (11→12) taken 825 times.
✗ Branch 1 (11→71) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 825 times.
✗ Branch 4 (13→14) not taken.
✗ Branch 5 (13→56) not taken.
✗ Branch 6 (14→15) not taken.
✗ Branch 7 (14→56) not taken.
825 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
368 // Loop through remaining operands
369
2/2
✓ Branch 0 (47→18) taken 849 times.
✓ Branch 1 (47→48) taken 824 times.
1673 for (size_t i = 0; i < node->opQueue.size(); i++) {
370
2/4
✓ Branch 0 (19→20) taken 849 times.
✗ Branch 1 (19→59) not taken.
✓ Branch 2 (20→21) taken 849 times.
✗ Branch 3 (20→57) not taken.
849 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
371
2/8
✓ Branch 0 (22→23) taken 849 times.
✗ Branch 1 (22→70) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 849 times.
✗ Branch 4 (24→25) not taken.
✗ Branch 5 (24→60) not taken.
✗ Branch 6 (25→26) not taken.
✗ Branch 7 (25→60) not taken.
849 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
372
373 // Check operator
374 849 const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first;
375
2/2
✓ Branch 0 (29→30) taken 704 times.
✓ Branch 1 (29→31) taken 145 times.
849 if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL)
376
2/2
✓ Branch 0 (30→43) taken 703 times.
✓ Branch 1 (30→70) taken 1 times.
704 currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i);
377
2/2
✓ Branch 0 (31→32) taken 135 times.
✓ Branch 1 (31→33) taken 10 times.
145 else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV)
378
1/2
✓ Branch 0 (32→43) taken 135 times.
✗ Branch 1 (32→70) not taken.
135 currentResult = opRuleManager.getDivResultType(node, currentResult, operandResult, i);
379
1/2
✓ Branch 0 (33→34) taken 10 times.
✗ Branch 1 (33→35) not taken.
10 else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_REM)
380
1/2
✓ Branch 0 (34→43) taken 10 times.
✗ Branch 1 (34→70) not taken.
10 currentResult = OpRuleManager::getRemResultType(node, currentResult, operandResult);
381 else
382 throw CompilerError(UNHANDLED_BRANCH, "Multiplicative fall-through"); // GCOV_EXCL_LINE
383
384 // Push the new item and pop the old one on the other side of the queue
385
1/2
✓ Branch 0 (43→44) taken 848 times.
✗ Branch 1 (43→70) not taken.
848 node->opQueue.emplace(op, currentResult.type);
386 848 node->opQueue.pop();
387 }
388
389
1/2
✓ Branch 0 (48→49) taken 824 times.
✗ Branch 1 (48→71) not taken.
824 node->setEvaluatedSymbolType(currentResult.type, manIdx);
390
1/2
✓ Branch 0 (49→50) taken 824 times.
✗ Branch 1 (49→71) not taken.
824 return currentResult;
391 }
392
393 75997 std::any TypeChecker::visitCastExpr(CastExprNode *node) {
394 // Check if cast is applied
395
2/2
✓ Branch 0 (2→3) taken 74172 times.
✓ Branch 1 (2→5) taken 1825 times.
75997 if (!node->isCast)
396
2/2
✓ Branch 0 (3→4) taken 74163 times.
✓ Branch 1 (3→65) taken 9 times.
74172 return visit(node->prefixUnaryExpr);
397
398 // Visit destination type
399
2/4
✓ Branch 0 (5→6) taken 1825 times.
✗ Branch 1 (5→49) not taken.
✓ Branch 2 (6→7) taken 1825 times.
✗ Branch 3 (6→47) not taken.
1825 const auto dstType = std::any_cast<QualType>(visit(node->dataType));
400
2/8
✓ Branch 0 (8→9) taken 1825 times.
✗ Branch 1 (8→65) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 1825 times.
✗ Branch 4 (10→11) not taken.
✗ Branch 5 (10→50) not taken.
✗ Branch 6 (11→12) not taken.
✗ Branch 7 (11→50) not taken.
1825 HANDLE_UNRESOLVED_TYPE_ER(dstType)
401 // Visit source type
402
2/4
✓ Branch 0 (14→15) taken 1825 times.
✗ Branch 1 (14→53) not taken.
✓ Branch 2 (15→16) taken 1825 times.
✗ Branch 3 (15→51) not taken.
1825 const auto src = std::any_cast<ExprResult>(visit(node->assignExpr));
403
2/8
✓ Branch 0 (17→18) taken 1825 times.
✗ Branch 1 (17→65) not taken.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→23) taken 1825 times.
✗ Branch 4 (19→20) not taken.
✗ Branch 5 (19→54) not taken.
✗ Branch 6 (20→21) not taken.
✗ Branch 7 (20→54) not taken.
1825 HANDLE_UNRESOLVED_TYPE_ER(src.type)
404
405 // Check for identity cast
406
3/4
✓ Branch 0 (23→24) taken 1825 times.
✗ Branch 1 (23→65) not taken.
✓ Branch 2 (24→25) taken 227 times.
✓ Branch 3 (24→34) taken 1598 times.
1825 if (src.type == dstType) {
407
2/4
✓ Branch 0 (27→28) taken 227 times.
✗ Branch 1 (27→57) not taken.
✓ Branch 2 (28→29) taken 227 times.
✗ Branch 3 (28→55) not taken.
227 const CompilerWarning warning(node->codeLoc, IDENTITY_CAST, "You cast from a type to itself. Thus, this can be simplified.");
408
1/2
✓ Branch 0 (31→32) taken 227 times.
✗ Branch 1 (31→61) not taken.
227 sourceFile->compilerOutput.warnings.push_back(warning);
409 227 }
410
411 // Get result type
412
1/2
✓ Branch 0 (34→35) taken 1825 times.
✗ Branch 1 (34→65) not taken.
1825 const QualType resultType = opRuleManager.getCastResultType(node, dstType, src);
413
414
1/2
✓ Branch 0 (35→36) taken 1825 times.
✗ Branch 1 (35→65) not taken.
1825 const bool typesMatch = dstType.matches(src.type, false, true, true);
415
1/2
✓ Branch 0 (36→37) taken 1825 times.
✗ Branch 1 (36→65) not taken.
1825 const bool sameContainerType = src.type.isSameContainerTypeAs(dstType);
416
4/4
✓ Branch 0 (37→38) taken 1598 times.
✓ Branch 1 (37→39) taken 227 times.
✓ Branch 2 (38→39) taken 117 times.
✓ Branch 3 (38→40) taken 1481 times.
1825 SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr;
417
2/4
✓ Branch 0 (41→42) taken 1825 times.
✗ Branch 1 (41→64) not taken.
✓ Branch 2 (42→43) taken 1825 times.
✗ Branch 3 (42→64) not taken.
1825 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry};
418 }
419
420 80803 std::any TypeChecker::visitPrefixUnaryExpr(PrefixUnaryExprNode *node) {
421 // If no operator is applied, simply visit the postfix unary expression
422
2/2
✓ Branch 0 (2→3) taken 79809 times.
✓ Branch 1 (2→5) taken 994 times.
80803 if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE)
423
2/2
✓ Branch 0 (3→4) taken 79801 times.
✓ Branch 1 (3→78) taken 8 times.
79809 return visit(node->postfixUnaryExpr);
424
425 // Visit the right side
426 994 PrefixUnaryExprNode *rhsNode = node->prefixUnaryExpr;
427
2/4
✓ Branch 0 (5→6) taken 994 times.
✗ Branch 1 (5→57) not taken.
✓ Branch 2 (6→7) taken 994 times.
✗ Branch 3 (6→55) not taken.
994 auto operand = std::any_cast<ExprResult>(visit(rhsNode));
428 994 auto [operandType, operandEntry] = operand;
429
5/8
✓ Branch 0 (8→9) taken 994 times.
✗ Branch 1 (8→78) not taken.
✓ Branch 2 (9→10) taken 1 times.
✓ Branch 3 (9→14) taken 993 times.
✓ Branch 4 (10→11) taken 1 times.
✗ Branch 5 (10→58) not taken.
✓ Branch 6 (11→12) taken 1 times.
✗ Branch 7 (11→58) not taken.
994 HANDLE_UNRESOLVED_TYPE_ER(operandType)
430 // Determine action, based on the given operator
431
7/8
✓ Branch 0 (14→15) taken 16 times.
✓ Branch 1 (14→17) taken 19 times.
✓ Branch 2 (14→25) taken 8 times.
✓ Branch 3 (14→33) taken 688 times.
✓ Branch 4 (14→35) taken 1 times.
✓ Branch 5 (14→37) taken 181 times.
✓ Branch 6 (14→39) taken 80 times.
✗ Branch 7 (14→41) not taken.
993 switch (node->op) {
432 16 case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS:
433
1/2
✓ Branch 0 (15→16) taken 16 times.
✗ Branch 1 (15→59) not taken.
16 operandType = OpRuleManager::getPrefixMinusResultType(node, operand);
434 16 break;
435 19 case PrefixUnaryExprNode::PrefixUnaryOp::OP_PLUS_PLUS:
436
1/2
✓ Branch 0 (17→18) taken 19 times.
✗ Branch 1 (17→60) not taken.
19 operandType = opRuleManager.getPrefixPlusPlusResultType(node, operand);
437
438
2/2
✓ Branch 0 (18→19) taken 16 times.
✓ Branch 1 (18→24) taken 3 times.
19 if (operandEntry) {
439 // In case the lhs is captured, notify the capture about the write access
440
2/4
✓ Branch 0 (19→20) taken 16 times.
✗ Branch 1 (19→78) not taken.
✗ Branch 2 (20→21) not taken.
✓ Branch 3 (20→22) taken 16 times.
16 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
441 lhsCapture->setAccessType(READ_WRITE);
442
443 // Update the state of the variable
444
1/2
✓ Branch 0 (22→23) taken 16 times.
✗ Branch 1 (22→61) not taken.
16 operandEntry->updateState(INITIALIZED, node);
445 }
446
447 19 break;
448 8 case PrefixUnaryExprNode::PrefixUnaryOp::OP_MINUS_MINUS:
449
2/2
✓ Branch 0 (25→26) taken 7 times.
✓ Branch 1 (25→62) taken 1 times.
8 operandType = opRuleManager.getPrefixMinusMinusResultType(node, operand);
450
451
2/2
✓ Branch 0 (26→27) taken 4 times.
✓ Branch 1 (26→32) taken 3 times.
7 if (operandEntry) {
452 // In case the lhs is captured, notify the capture about the write access
453
2/4
✓ Branch 0 (27→28) taken 4 times.
✗ Branch 1 (27→78) not taken.
✗ Branch 2 (28→29) not taken.
✓ Branch 3 (28→30) taken 4 times.
4 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
454 lhsCapture->setAccessType(READ_WRITE);
455
456 // Update the state of the variable
457
1/2
✓ Branch 0 (30→31) taken 4 times.
✗ Branch 1 (30→63) not taken.
4 operandEntry->updateState(INITIALIZED, node);
458 }
459
460 7 break;
461 688 case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT:
462
1/2
✓ Branch 0 (33→34) taken 688 times.
✗ Branch 1 (33→64) not taken.
688 operandType = OpRuleManager::getPrefixNotResultType(node, operand);
463 688 break;
464 1 case PrefixUnaryExprNode::PrefixUnaryOp::OP_BITWISE_NOT:
465
1/2
✓ Branch 0 (35→36) taken 1 times.
✗ Branch 1 (35→65) not taken.
1 operandType = OpRuleManager::getPrefixBitwiseNotResultType(node, operand);
466 1 break;
467 181 case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE:
468
1/2
✓ Branch 0 (37→38) taken 181 times.
✗ Branch 1 (37→66) not taken.
181 operandType = OpRuleManager::getPrefixMulResultType(node, operand);
469 181 break;
470 80 case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF:
471
1/2
✓ Branch 0 (39→40) taken 80 times.
✗ Branch 1 (39→67) not taken.
80 operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand);
472 80 break;
473 default: // GCOV_EXCL_LINE
474 throw CompilerError(UNHANDLED_BRANCH, "PrefixUnaryExpr fall-through"); // GCOV_EXCL_LINE
475 }
476
477
2/4
✓ Branch 0 (49→50) taken 992 times.
✗ Branch 1 (49→77) not taken.
✓ Branch 2 (50→51) taken 992 times.
✗ Branch 3 (50→77) not taken.
992 return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry};
478 }
479
480 99666 std::any TypeChecker::visitPostfixUnaryExpr(PostfixUnaryExprNode *node) {
481 // If no operator is applied, simply visit the atomic expression
482
2/2
✓ Branch 0 (2→3) taken 79809 times.
✓ Branch 1 (2→5) taken 19857 times.
99666 if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE)
483
2/2
✓ Branch 0 (3→4) taken 79802 times.
✓ Branch 1 (3→316) taken 7 times.
79809 return visit(node->atomicExpr);
484
485 // Visit left side
486 19857 PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr;
487
2/4
✓ Branch 0 (5→6) taken 19857 times.
✗ Branch 1 (5→211) not taken.
✓ Branch 2 (6→7) taken 19857 times.
✗ Branch 3 (6→209) not taken.
19857 auto operand = std::any_cast<ExprResult>(visit(lhsNode));
488 19857 auto [operandType, operandEntry] = operand;
489
5/8
✓ Branch 0 (8→9) taken 19857 times.
✗ Branch 1 (8→316) not taken.
✓ Branch 2 (9→10) taken 6 times.
✓ Branch 3 (9→14) taken 19851 times.
✓ Branch 4 (10→11) taken 6 times.
✗ Branch 5 (10→212) not taken.
✓ Branch 6 (11→12) taken 6 times.
✗ Branch 7 (11→212) not taken.
19857 HANDLE_UNRESOLVED_TYPE_ER(operandType)
490
491
4/5
✓ Branch 0 (14→15) taken 3111 times.
✓ Branch 1 (14→101) taken 14703 times.
✓ Branch 2 (14→159) taken 1653 times.
✓ Branch 3 (14→167) taken 384 times.
✗ Branch 4 (14→175) not taken.
19851 switch (node->op) {
492 3111 case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: {
493 // Visit index assignment
494 3111 AssignExprNode *indexAssignExpr = node->subscriptIndexExpr;
495
2/4
✓ Branch 0 (15→16) taken 3111 times.
✗ Branch 1 (15→215) not taken.
✓ Branch 2 (16→17) taken 3111 times.
✗ Branch 3 (16→213) not taken.
3111 const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr));
496
2/8
✓ Branch 0 (18→19) taken 3111 times.
✗ Branch 1 (18→258) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 3111 times.
✗ Branch 4 (20→21) not taken.
✗ Branch 5 (20→216) not taken.
✗ Branch 6 (21→22) not taken.
✗ Branch 7 (21→216) not taken.
3111 HANDLE_UNRESOLVED_TYPE_ER(index.type)
497
498 // Check is there is an overloaded operator function available, if yes accept it
499
1/2
✓ Branch 0 (24→25) taken 3111 times.
✗ Branch 1 (24→217) not taken.
3111 const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0);
500
3/4
✓ Branch 0 (25→26) taken 3111 times.
✗ Branch 1 (25→258) not taken.
✓ Branch 2 (26→27) taken 111 times.
✓ Branch 3 (26→28) taken 3000 times.
3111 if (!type.is(TY_INVALID)) {
501 111 operandType = type;
502 3109 break;
503 }
504
505
1/2
✓ Branch 0 (28→29) taken 3000 times.
✗ Branch 1 (28→218) not taken.
3000 operandType = operandType.removeReferenceWrapper();
506
507 // Check if the index is of the right type
508
3/4
✓ Branch 0 (29→30) taken 3000 times.
✗ Branch 1 (29→219) not taken.
✓ Branch 2 (30→31) taken 1 times.
✓ Branch 3 (30→41) taken 2999 times.
3000 if (!index.type.isOneOf({TY_INT, TY_LONG}))
509
4/8
✓ Branch 0 (33→34) taken 1 times.
✗ Branch 1 (33→222) not taken.
✓ Branch 2 (34→35) taken 1 times.
✗ Branch 3 (34→220) not taken.
✓ Branch 4 (37→38) taken 1 times.
✗ Branch 5 (37→226) not taken.
✓ Branch 6 (38→39) taken 1 times.
✗ Branch 7 (38→226) not taken.
3 SOFT_ERROR_ER(node, ARRAY_INDEX_NOT_INT_OR_LONG, "Array index must be of type int or long")
510
511 // Check if we can apply the subscript operator on the lhs type
512
2/4
✓ Branch 0 (41→42) taken 2999 times.
✗ Branch 1 (41→227) not taken.
✗ Branch 2 (42→43) not taken.
✓ Branch 3 (42→52) taken 2999 times.
2999 if (!operandType.isOneOf({TY_ARRAY, TY_PTR, TY_STRING}))
513 SOFT_ERROR_ER(node, OPERATOR_WRONG_DATA_TYPE,
514 "Can only apply subscript operator on array type, got " + operandType.getName(true))
515
516 // Check if we have an unsafe operation
517
6/10
✓ Branch 0 (52→53) taken 2999 times.
✗ Branch 1 (52→258) not taken.
✓ Branch 2 (53→54) taken 2155 times.
✓ Branch 3 (53→57) taken 844 times.
✓ Branch 4 (54→55) taken 2155 times.
✗ Branch 5 (54→258) not taken.
✗ Branch 6 (55→56) not taken.
✓ Branch 7 (55→57) taken 2155 times.
✗ Branch 8 (58→59) not taken.
✓ Branch 9 (58→69) taken 2999 times.
2999 if (operandType.isPtr() && !currentScope->doesAllowUnsafeOperations())
518 SOFT_ERROR_ER(
519 node, UNSAFE_OPERATION_IN_SAFE_CONTEXT,
520 "The subscript operator on pointers is an unsafe operation. Use unsafe blocks if you know what you are doing.")
521
522 // In case of compile time index value and known array size, perform a compile time out-of-bounds check
523
11/14
✓ Branch 0 (69→70) taken 2999 times.
✗ Branch 1 (69→258) not taken.
✓ Branch 2 (70→71) taken 140 times.
✓ Branch 3 (70→76) taken 2859 times.
✓ Branch 4 (71→72) taken 140 times.
✗ Branch 5 (71→258) not taken.
✓ Branch 6 (72→73) taken 99 times.
✓ Branch 7 (72→76) taken 41 times.
✓ Branch 8 (73→74) taken 99 times.
✗ Branch 9 (73→258) not taken.
✓ Branch 10 (74→75) taken 34 times.
✓ Branch 11 (74→76) taken 65 times.
✓ Branch 12 (77→78) taken 34 times.
✓ Branch 13 (77→96) taken 2965 times.
2999 if (operandType.isArray() && operandType.getArraySize() != ARRAY_SIZE_UNKNOWN && indexAssignExpr->hasCompileTimeValue()) {
524
1/2
✓ Branch 0 (78→79) taken 34 times.
✗ Branch 1 (78→258) not taken.
34 const int32_t constIndex = indexAssignExpr->getCompileTimeValue().intValue;
525
1/2
✓ Branch 0 (79→80) taken 34 times.
✗ Branch 1 (79→258) not taken.
34 const unsigned int constSize = operandType.getArraySize();
526 // Check if we are accessing out-of-bounds memory
527
2/2
✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→96) taken 33 times.
34 if (constIndex >= static_cast<int32_t>(constSize)) {
528 1 const std::string idxStr = std::to_string(constIndex);
529 1 const std::string sizeStr = std::to_string(constSize);
530
6/12
✓ Branch 0 (83→84) taken 1 times.
✗ Branch 1 (83→248) not taken.
✓ Branch 2 (84→85) taken 1 times.
✗ Branch 3 (84→246) not taken.
✓ Branch 4 (85→86) taken 1 times.
✗ Branch 5 (85→244) not taken.
✓ Branch 6 (86→87) taken 1 times.
✗ Branch 7 (86→242) not taken.
✓ Branch 8 (90→91) taken 1 times.
✗ Branch 9 (90→251) not taken.
✓ Branch 10 (91→92) taken 1 times.
✗ Branch 11 (91→251) not taken.
1 SOFT_ERROR_ER(node, ARRAY_INDEX_OUT_OF_BOUNDS,
531 "You are trying to access element with index " + idxStr + " of an array with size " + sizeStr)
532 1 }
533 }
534
535 // Get item type
536
1/2
✓ Branch 0 (96→97) taken 2998 times.
✗ Branch 1 (96→257) not taken.
2998 operandType = operandType.getContained();
537
538 // Remove heap qualifier
539 2998 operandType.getQualifiers().isHeap = false;
540
541 2998 break;
542 }
543 14703 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: {
544 14703 const std::string &fieldName = node->identifier;
545
546 // Check if lhs is enum or strobj
547
1/2
✓ Branch 0 (101→102) taken 14703 times.
✗ Branch 1 (101→286) not taken.
14703 const QualType lhsBaseTy = operandType.autoDeReference();
548
3/4
✓ Branch 0 (102→103) taken 14703 times.
✗ Branch 1 (102→286) not taken.
✓ Branch 2 (103→104) taken 1 times.
✓ Branch 3 (103→113) taken 14702 times.
14703 if (!lhsBaseTy.is(TY_STRUCT))
549
5/10
✓ Branch 0 (104→105) taken 1 times.
✗ Branch 1 (104→263) not taken.
✓ Branch 2 (105→106) taken 1 times.
✗ Branch 3 (105→261) not taken.
✓ Branch 4 (106→107) taken 1 times.
✗ Branch 5 (106→259) not taken.
✓ Branch 6 (109→110) taken 1 times.
✗ Branch 7 (109→265) not taken.
✓ Branch 8 (110→111) taken 1 times.
✗ Branch 9 (110→265) not taken.
1 SOFT_ERROR_ER(node, INVALID_MEMBER_ACCESS, "Cannot apply member access operator on " + operandType.getName(false))
550
551 // Retrieve registry entry
552
1/2
✓ Branch 0 (113→114) taken 14702 times.
✗ Branch 1 (113→286) not taken.
14702 const std::string &structName = lhsBaseTy.getSubType();
553
1/2
✓ Branch 0 (114→115) taken 14702 times.
✗ Branch 1 (114→286) not taken.
14702 Scope *structScope = lhsBaseTy.getBodyScope();
554
555 // If we only have the generic struct scope, lookup the concrete manifestation scope
556
2/2
✓ Branch 0 (115→116) taken 78 times.
✓ Branch 1 (115→120) taken 14624 times.
14702 if (structScope->isGenericScope) {
557
1/2
✓ Branch 0 (116→117) taken 78 times.
✗ Branch 1 (116→286) not taken.
78 const Struct *spiceStruct = lhsBaseTy.getStruct(node);
558
1/2
✗ Branch 0 (117→118) not taken.
✓ Branch 1 (117→119) taken 78 times.
78 assert(spiceStruct != nullptr);
559 78 structScope = spiceStruct->scope;
560 }
561
1/2
✗ Branch 0 (120→121) not taken.
✓ Branch 1 (120→122) taken 14702 times.
14702 assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope
562
563 // Get accessed field
564 14702 std::vector<size_t> indexPath;
565
1/2
✓ Branch 0 (122→123) taken 14702 times.
✗ Branch 1 (122→284) not taken.
14702 SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath);
566
2/2
✓ Branch 0 (123→124) taken 2 times.
✓ Branch 1 (123→135) taken 14700 times.
14702 if (!memberEntry)
567
6/12
✓ Branch 0 (124→125) taken 2 times.
✗ Branch 1 (124→272) not taken.
✓ Branch 2 (125→126) taken 2 times.
✗ Branch 3 (125→270) not taken.
✓ Branch 4 (126→127) taken 2 times.
✗ Branch 5 (126→268) not taken.
✓ Branch 6 (127→128) taken 2 times.
✗ Branch 7 (127→266) not taken.
✓ Branch 8 (131→132) taken 2 times.
✗ Branch 9 (131→275) not taken.
✓ Branch 10 (132→133) taken 2 times.
✗ Branch 11 (132→275) not taken.
2 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Field '" + node->identifier + "' not found in struct " + structName)
568
1/2
✓ Branch 0 (135→136) taken 14700 times.
✗ Branch 1 (135→284) not taken.
14700 const QualType memberType = memberEntry->getQualType();
569
570 // Check for insufficient visibility
571
8/14
✓ Branch 0 (136→137) taken 14700 times.
✗ Branch 1 (136→276) not taken.
✓ Branch 2 (137→138) taken 74 times.
✓ Branch 3 (137→143) taken 14626 times.
✓ Branch 4 (138→139) taken 74 times.
✗ Branch 5 (138→276) not taken.
✓ Branch 6 (139→140) taken 74 times.
✗ Branch 7 (139→276) not taken.
✓ Branch 8 (140→141) taken 74 times.
✗ Branch 9 (140→276) not taken.
✗ Branch 10 (141→142) not taken.
✓ Branch 11 (141→143) taken 74 times.
✗ Branch 12 (144→145) not taken.
✓ Branch 13 (144→154) taken 14700 times.
14700 if (structScope->isImportedBy(rootScope) && !memberEntry->getQualType().getBase().isPublic())
572 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access field '" + fieldName + "' due to its private visibility")
573
574 // Set field to used
575 14700 memberEntry->used = true;
576
577 // Overwrite type and entry of left side with member type and entry
578 14700 operandType = memberType;
579 14700 operandEntry = memberEntry;
580 14700 break;
581
2/2
✓ Branch 0 (156→157) taken 2 times.
✓ Branch 1 (156→158) taken 14700 times.
14702 }
582 1653 case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: {
583
2/2
✓ Branch 0 (159→160) taken 1652 times.
✓ Branch 1 (159→287) taken 1 times.
1653 operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type;
584
585
2/2
✓ Branch 0 (160→161) taken 1648 times.
✓ Branch 1 (160→166) taken 4 times.
1652 if (operandEntry) {
586 // In case the lhs is captured, notify the capture about the write access
587
3/4
✓ Branch 0 (161→162) taken 1648 times.
✗ Branch 1 (161→316) not taken.
✓ Branch 2 (162→163) taken 4 times.
✓ Branch 3 (162→164) taken 1644 times.
1648 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
588
1/2
✓ Branch 0 (163→164) taken 4 times.
✗ Branch 1 (163→316) not taken.
4 lhsCapture->setAccessType(READ_WRITE);
589
590 // Update the state of the variable
591
1/2
✓ Branch 0 (164→165) taken 1648 times.
✗ Branch 1 (164→288) not taken.
1648 operandEntry->updateState(INITIALIZED, node);
592 }
593
594 1652 break;
595 }
596 384 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: {
597
1/2
✓ Branch 0 (167→168) taken 384 times.
✗ Branch 1 (167→289) not taken.
384 operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type;
598
599
2/2
✓ Branch 0 (168→169) taken 380 times.
✓ Branch 1 (168→174) taken 4 times.
384 if (operandEntry) {
600 // In case the lhs is captured, notify the capture about the write access
601
2/4
✓ Branch 0 (169→170) taken 380 times.
✗ Branch 1 (169→316) not taken.
✗ Branch 2 (170→171) not taken.
✓ Branch 3 (170→172) taken 380 times.
380 if (Capture *lhsCapture = currentScope->symbolTable.lookupCapture(operandEntry->name); lhsCapture)
602 lhsCapture->setAccessType(READ_WRITE);
603
604 // Update the state of the variable
605
1/2
✓ Branch 0 (172→173) taken 380 times.
✗ Branch 1 (172→290) not taken.
380 operandEntry->updateState(INITIALIZED, node);
606 }
607
608 384 break;
609 }
610 default: // GCOV_EXCL_LINE
611 throw CompilerError(UNHANDLED_BRANCH, "PostfixUnaryExpr fall-through"); // GCOV_EXCL_LINE
612 }
613
614
2/4
✓ Branch 0 (183→184) taken 19845 times.
✗ Branch 1 (183→316) not taken.
✗ Branch 2 (184→185) not taken.
✓ Branch 3 (184→203) taken 19845 times.
19845 if (operandType.is(TY_INVALID)) {
615 const std::string &varName = operandEntry ? operandEntry->name : "";
616 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "Variable '" + varName + "' was referenced before declared")
617 }
618
619
2/4
✓ Branch 0 (203→204) taken 19845 times.
✗ Branch 1 (203→315) not taken.
✓ Branch 2 (204→205) taken 19845 times.
✗ Branch 3 (204→315) not taken.
19845 return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry};
620 }
621
622 79809 std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) {
623 // Check if constant
624
2/2
✓ Branch 0 (2→3) taken 15568 times.
✓ Branch 1 (2→5) taken 64241 times.
79809 if (node->constant)
625
1/2
✓ Branch 0 (3→4) taken 15568 times.
✗ Branch 1 (3→219) not taken.
15568 return visit(node->constant);
626
627 // Check if value
628
2/2
✓ Branch 0 (5→6) taken 15407 times.
✓ Branch 1 (5→8) taken 48834 times.
64241 if (node->value)
629
2/2
✓ Branch 0 (6→7) taken 15403 times.
✓ Branch 1 (6→219) taken 4 times.
15407 return visit(node->value);
630
631 // Check for builtin calls
632
2/2
✓ Branch 0 (8→9) taken 1595 times.
✓ Branch 1 (8→11) taken 47239 times.
48834 if (node->builtinCall)
633
1/2
✓ Branch 0 (9→10) taken 1595 times.
✗ Branch 1 (9→219) not taken.
1595 return visit(node->builtinCall);
634
635 // Check for assign expression within parentheses
636
2/2
✓ Branch 0 (11→12) taken 525 times.
✓ Branch 1 (11→14) taken 46714 times.
47239 if (node->assignExpr)
637
2/2
✓ Branch 0 (12→13) taken 522 times.
✓ Branch 1 (12→219) taken 3 times.
525 return visit(node->assignExpr);
638
639 // Identifier (local or global variable access)
640
1/2
✗ Branch 0 (15→16) not taken.
✓ Branch 1 (15→17) taken 46714 times.
46714 assert(!node->fqIdentifier.empty());
641
642
1/2
✓ Branch 0 (17→18) taken 46714 times.
✗ Branch 1 (17→219) not taken.
46714 auto &[entry, accessScope, capture] = node->data.at(manIdx);
643 46714 accessScope = currentScope;
644
645 // Check if a local or global variable can be found by searching for the name
646
2/2
✓ Branch 0 (19→20) taken 46471 times.
✓ Branch 1 (19→25) taken 243 times.
46714 if (node->identifierFragments.size() == 1)
647 92942 entry = accessScope->lookup(node->identifierFragments.back());
648
649 // If no local or global was found, search in the name registry
650
2/2
✓ Branch 0 (25→26) taken 319 times.
✓ Branch 1 (25→38) taken 46395 times.
46714 if (!entry) {
651
1/2
✓ Branch 0 (26→27) taken 319 times.
✗ Branch 1 (26→219) not taken.
319 const NameRegistryEntry *registryEntry = sourceFile->getNameRegistryEntry(node->fqIdentifier);
652
2/2
✓ Branch 0 (27→28) taken 1 times.
✓ Branch 1 (27→37) taken 318 times.
319 if (!registryEntry)
653
5/10
✓ Branch 0 (28→29) taken 1 times.
✗ Branch 1 (28→167) not taken.
✓ Branch 2 (29→30) taken 1 times.
✗ Branch 3 (29→165) not taken.
✓ Branch 4 (30→31) taken 1 times.
✗ Branch 5 (30→163) not taken.
✓ Branch 6 (33→34) taken 1 times.
✗ Branch 7 (33→169) not taken.
✓ Branch 8 (34→35) taken 1 times.
✗ Branch 9 (34→169) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE, "The variable '" + node->fqIdentifier + "' could not be found")
654 318 entry = registryEntry->targetEntry;
655 318 accessScope = registryEntry->targetScope;
656 }
657
1/2
✗ Branch 0 (38→39) not taken.
✓ Branch 1 (38→40) taken 46713 times.
46713 assert(entry != nullptr);
658 46713 entry->used = true;
659
1/2
✓ Branch 0 (40→41) taken 46713 times.
✗ Branch 1 (40→219) not taken.
46713 capture = accessScope->symbolTable.lookupCapture(entry->name);
660
661
1/2
✓ Branch 0 (41→42) taken 46713 times.
✗ Branch 1 (41→219) not taken.
46713 const QualType varType = entry->getQualType();
662
5/8
✓ Branch 0 (42→43) taken 46713 times.
✗ Branch 1 (42→219) not taken.
✓ Branch 2 (43→44) taken 9 times.
✓ Branch 3 (43→48) taken 46704 times.
✓ Branch 4 (44→45) taken 9 times.
✗ Branch 5 (44→170) not taken.
✓ Branch 6 (45→46) taken 9 times.
✗ Branch 7 (45→170) not taken.
46713 HANDLE_UNRESOLVED_TYPE_ER(varType)
663
3/4
✓ Branch 0 (48→49) taken 46704 times.
✗ Branch 1 (48→219) not taken.
✓ Branch 2 (49→50) taken 2 times.
✓ Branch 3 (49→59) taken 46702 times.
46704 if (varType.is(TY_INVALID))
664
5/10
✓ Branch 0 (50→51) taken 2 times.
✗ Branch 1 (50→175) not taken.
✓ Branch 2 (51→52) taken 2 times.
✗ Branch 3 (51→173) not taken.
✓ Branch 4 (52→53) taken 2 times.
✗ Branch 5 (52→171) not taken.
✓ Branch 6 (55→56) taken 2 times.
✗ Branch 7 (55→177) not taken.
✓ Branch 8 (56→57) taken 2 times.
✗ Branch 9 (56→177) not taken.
2 SOFT_ERROR_ER(node, USED_BEFORE_DECLARED, "Symbol '" + entry->name + "' was used before declared.")
665
666
7/8
✓ Branch 0 (59→60) taken 46702 times.
✗ Branch 1 (59→178) not taken.
✓ Branch 2 (60→61) taken 25 times.
✓ Branch 3 (60→63) taken 46677 times.
✓ Branch 4 (61→62) taken 9 times.
✓ Branch 5 (61→63) taken 16 times.
✓ Branch 6 (64→65) taken 9 times.
✓ Branch 7 (64→93) taken 46693 times.
46702 if (varType.isOneOf({TY_FUNCTION, TY_PROCEDURE}) && entry->global) {
667 // Check if overloaded function was referenced
668
1/2
✓ Branch 0 (65→66) taken 9 times.
✗ Branch 1 (65→219) not taken.
9 const std::vector<Function *> *manifestations = entry->declNode->getFctManifestations(entry->name);
669
2/2
✓ Branch 0 (67→68) taken 1 times.
✓ Branch 1 (67→78) taken 8 times.
9 if (manifestations->size() > 1)
670
4/8
✓ Branch 0 (70→71) taken 1 times.
✗ Branch 1 (70→181) not taken.
✓ Branch 2 (71→72) taken 1 times.
✗ Branch 3 (71→179) not taken.
✓ Branch 4 (74→75) taken 1 times.
✗ Branch 5 (74→185) not taken.
✓ Branch 6 (75→76) taken 1 times.
✗ Branch 7 (75→185) not taken.
3 SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Overloaded functions / functions with optional params cannot be referenced")
671
2/2
✓ Branch 0 (80→81) taken 1 times.
✓ Branch 1 (80→91) taken 7 times.
8 if (!manifestations->front()->templateTypes.empty())
672
4/8
✓ Branch 0 (83→84) taken 1 times.
✗ Branch 1 (83→188) not taken.
✓ Branch 2 (84→85) taken 1 times.
✗ Branch 3 (84→186) not taken.
✓ Branch 4 (87→88) taken 1 times.
✗ Branch 5 (87→192) not taken.
✓ Branch 6 (88→89) taken 1 times.
✗ Branch 7 (88→192) not taken.
3 SOFT_ERROR_ER(node, REFERENCED_OVERLOADED_FCT, "Generic functions cannot be referenced")
673 // Set referenced function to used
674 7 Function *referencedFunction = manifestations->front();
675 7 referencedFunction->used = true;
676 7 referencedFunction->entry->used = true;
677 }
678
679 // The base type should be an extended primitive
680
1/2
✓ Branch 0 (93→94) taken 46700 times.
✗ Branch 1 (93→219) not taken.
46700 const QualType baseType = varType.getBase();
681
6/10
✓ Branch 0 (94→95) taken 46700 times.
✗ Branch 1 (94→219) not taken.
✓ Branch 2 (95→96) taken 2 times.
✓ Branch 3 (95→99) taken 46698 times.
✓ Branch 4 (96→97) taken 2 times.
✗ Branch 5 (96→219) not taken.
✗ Branch 6 (97→98) not taken.
✓ Branch 7 (97→99) taken 2 times.
✗ Branch 8 (100→101) not taken.
✓ Branch 9 (100→112) taken 46700 times.
46700 if (!baseType.isExtendedPrimitive() && !baseType.is(TY_DYN))
682 SOFT_ERROR_ER(node, INVALID_SYMBOL_ACCESS, "A symbol of type " + varType.getName(false) + " cannot be accessed here")
683
684 // Check if we have seen a 'this.' prefix, because the generator needs that
685
6/8
✓ Branch 0 (112→113) taken 1 times.
✓ Branch 1 (112→117) taken 46699 times.
✓ Branch 2 (114→115) taken 1 times.
✗ Branch 3 (114→219) not taken.
✓ Branch 4 (115→116) taken 1 times.
✗ Branch 5 (115→117) not taken.
✓ Branch 6 (118→119) taken 1 times.
✓ Branch 7 (118→128) taken 46699 times.
46700 if (entry->scope->type == ScopeType::STRUCT && node->identifierFragments.front() != THIS_VARIABLE_NAME)
686
5/10
✓ Branch 0 (119→120) taken 1 times.
✗ Branch 1 (119→207) not taken.
✓ Branch 2 (120→121) taken 1 times.
✗ Branch 3 (120→205) not taken.
✓ Branch 4 (121→122) taken 1 times.
✗ Branch 5 (121→203) not taken.
✓ Branch 6 (124→125) taken 1 times.
✗ Branch 7 (124→209) not taken.
✓ Branch 8 (125→126) taken 1 times.
✗ Branch 9 (125→209) not taken.
1 SOFT_ERROR_ER(node, REFERENCED_UNDEFINED_VARIABLE,
687 "The symbol '" + node->fqIdentifier + "' could not be found. Missing 'this.' prefix?")
688
689 // Ensure that the entry is public, if the symbol is imported.
690 // An exception are enum items. There it is sufficient, that the enum itself is public.
691
7/8
✓ Branch 0 (128→129) taken 46699 times.
✗ Branch 1 (128→219) not taken.
✓ Branch 2 (129→130) taken 199 times.
✓ Branch 3 (129→132) taken 46500 times.
✓ Branch 4 (130→131) taken 78 times.
✓ Branch 5 (130→132) taken 121 times.
✓ Branch 6 (133→134) taken 78 times.
✓ Branch 7 (133→147) taken 46621 times.
46699 if (accessScope->isImportedBy(rootScope) && accessScope->type != ScopeType::ENUM)
692
5/8
✓ Branch 0 (134→135) taken 78 times.
✗ Branch 1 (134→210) not taken.
✓ Branch 2 (135→136) taken 78 times.
✗ Branch 3 (135→210) not taken.
✓ Branch 4 (136→137) taken 78 times.
✗ Branch 5 (136→210) not taken.
✓ Branch 6 (137→138) taken 1 times.
✓ Branch 7 (137→147) taken 77 times.
78 if (!entry->getQualType().getBase().isPublic())
693
5/10
✓ Branch 0 (138→139) taken 1 times.
✗ Branch 1 (138→215) not taken.
✓ Branch 2 (139→140) taken 1 times.
✗ Branch 3 (139→213) not taken.
✓ Branch 4 (140→141) taken 1 times.
✗ Branch 5 (140→211) not taken.
✓ Branch 6 (143→144) taken 1 times.
✗ Branch 7 (143→217) not taken.
✓ Branch 8 (144→145) taken 1 times.
✗ Branch 9 (144→217) not taken.
1 SOFT_ERROR_ER(node, INSUFFICIENT_VISIBILITY, "Cannot access '" + entry->name + "' due to its private visibility")
694
695 // For enum item access, use access scope of the enum
696
2/2
✓ Branch 0 (147→148) taken 238 times.
✓ Branch 1 (147→149) taken 46460 times.
46698 if (entry->scope->type == ScopeType::ENUM)
697 238 accessScope = entry->scope;
698
699 // For struct access, use access scope of the struct
700
3/4
✓ Branch 0 (149→150) taken 46698 times.
✗ Branch 1 (149→219) not taken.
✓ Branch 2 (150→151) taken 16627 times.
✓ Branch 3 (150→157) taken 30071 times.
46698 if (baseType.is(TY_STRUCT)) {
701
1/2
✓ Branch 0 (151→152) taken 16627 times.
✗ Branch 1 (151→219) not taken.
16627 const std::string &structName = baseType.getSubType();
702
1/2
✓ Branch 0 (152→153) taken 16627 times.
✗ Branch 1 (152→219) not taken.
16627 const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName);
703
1/2
✗ Branch 0 (153→154) not taken.
✓ Branch 1 (153→155) taken 16627 times.
16627 assert(nameRegistryEntry != nullptr);
704 16627 accessScope = nameRegistryEntry->targetScope;
705
1/2
✗ Branch 0 (155→156) not taken.
✓ Branch 1 (155→157) taken 16627 times.
16627 assert(accessScope != nullptr);
706 }
707
708
2/4
✓ Branch 0 (157→158) taken 46698 times.
✗ Branch 1 (157→218) not taken.
✓ Branch 2 (158→159) taken 46698 times.
✗ Branch 3 (158→218) not taken.
46698 return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), entry};
709 }
710
711 } // namespace spice::compiler
712