GCC Code Coverage Report


Directory: ../
File: src/typechecker/TypeCheckerExpressions.cpp
Date: 2025-08-26 18:26:32
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 67765 std::any TypeChecker::visitAssignExpr(AssignExprNode *node) {
13 // Check if ternary
14
2/2
✓ Branch 0 (2→3) taken 61942 times.
✓ Branch 1 (2→10) taken 5823 times.
67765 if (node->ternaryExpr) {
15
3/4
✓ Branch 0 (3→4) taken 61927 times.
✓ Branch 1 (3→97) taken 15 times.
✓ Branch 2 (4→5) taken 61927 times.
✗ Branch 3 (4→95) not taken.
61942 auto result = std::any_cast<ExprResult>(visit(node->ternaryExpr));
16
1/2
✓ Branch 0 (6→7) taken 61927 times.
✗ Branch 1 (6→98) not taken.
61927 node->setEvaluatedSymbolType(result.type, manIdx);
17
1/2
✓ Branch 0 (7→8) taken 61927 times.
✗ Branch 1 (7→98) not taken.
61927 return result;
18 }
19
20 // Check if assignment
21
1/2
✓ Branch 0 (10→11) taken 5823 times.
✗ Branch 1 (10→86) not taken.
5823 if (node->op != AssignExprNode::AssignOp::OP_NONE) {
22 // Visit the right side first
23
2/4
✓ Branch 0 (11→12) taken 5823 times.
✗ Branch 1 (11→101) not taken.
✓ Branch 2 (12→13) taken 5823 times.
✗ Branch 3 (12→99) not taken.
5823 auto rhs = std::any_cast<ExprResult>(visit(node->rhs));
24 5823 auto [rhsType, rhsEntry] = rhs;
25
5/8
✓ Branch 0 (14→15) taken 5823 times.
✗ Branch 1 (14→120) not taken.
✓ Branch 2 (15→16) taken 1 times.
✓ Branch 3 (15→20) taken 5822 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.
5823 HANDLE_UNRESOLVED_TYPE_ER(rhsType)
26 // Then visit the left side
27
2/4
✓ Branch 0 (20→21) taken 5822 times.
✗ Branch 1 (20→105) not taken.
✓ Branch 2 (21→22) taken 5822 times.
✗ Branch 3 (21→103) not taken.
5822 auto lhs = std::any_cast<ExprResult>(visit(node->lhs));
28 5822 auto [lhsType, lhsVar] = lhs;
29
5/8
✓ Branch 0 (23→24) taken 5822 times.
✗ Branch 1 (23→120) not taken.
✓ Branch 2 (24→25) taken 1 times.
✓ Branch 3 (24→29) taken 5821 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.
5822 HANDLE_UNRESOLVED_TYPE_ER(lhsType)
30
31 // Take a look at the operator
32
2/2
✓ Branch 0 (29→30) taken 5155 times.
✓ Branch 1 (29→42) taken 666 times.
5821 if (node->op == AssignExprNode::AssignOp::OP_ASSIGN) {
33
8/10
✓ Branch 0 (30→31) taken 5154 times.
✓ Branch 1 (30→37) taken 1 times.
✓ Branch 2 (31→32) taken 5154 times.
✗ Branch 3 (31→120) not taken.
✓ Branch 4 (32→33) taken 4080 times.
✓ Branch 5 (32→37) taken 1074 times.
✓ Branch 6 (34→35) taken 4080 times.
✗ Branch 7 (34→120) not taken.
✓ Branch 8 (35→36) taken 1291 times.
✓ Branch 9 (35→37) taken 2789 times.
5155 const bool isDecl = lhs.entry != nullptr && lhs.entry->isField() && !lhs.entry->getLifecycle().isInitialized();
34
2/2
✓ Branch 0 (38→39) taken 5154 times.
✓ Branch 1 (38→107) taken 1 times.
5155 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 2398 times.
✓ Branch 1 (39→72) taken 2756 times.
✓ Branch 2 (40→41) taken 206 times.
✓ Branch 3 (40→72) taken 2192 times.
5154 if (rhsEntry != nullptr && rhsEntry->anonymous)
38
1/2
✓ Branch 0 (41→72) taken 206 times.
✗ Branch 1 (41→120) not taken.
206 currentScope->symbolTable.deleteAnonymous(rhsEntry->name);
39
2/2
✓ Branch 0 (42→43) taken 246 times.
✓ Branch 1 (42→45) taken 420 times.
666 } else if (node->op == AssignExprNode::AssignOp::OP_PLUS_EQUAL) {
40
1/2
✓ Branch 0 (43→44) taken 246 times.
✗ Branch 1 (43→108) not taken.
246 rhsType = opRuleManager.getPlusEqualResultType(node, lhs, rhs, 0).type;
41
2/2
✓ Branch 0 (45→46) taken 33 times.
✓ Branch 1 (45→48) taken 387 times.
420 } 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 34 times.
✓ Branch 1 (48→51) taken 353 times.
387 } else if (node->op == AssignExprNode::AssignOp::OP_MUL_EQUAL) {
44
1/2
✓ Branch 0 (49→50) taken 34 times.
✗ Branch 1 (49→110) not taken.
34 rhsType = opRuleManager.getMulEqualResultType(node, lhs, rhs, 0).type;
45
2/2
✓ Branch 0 (51→52) taken 45 times.
✓ Branch 1 (51→54) taken 308 times.
353 } 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 302 times.
308 } 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 300 times.
302 } 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 297 times.
300 } 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 296 times.
297 } 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 295 times.
296 } 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 295 times.
✗ Branch 1 (69→72) not taken.
295 } else if (node->op == AssignExprNode::AssignOp::OP_XOR_EQUAL) {
58
1/2
✓ Branch 0 (70→71) taken 295 times.
✗ Branch 1 (70→117) not taken.
295 rhsType = opRuleManager.getXorEqualResultType(node, lhs, rhs);
59 }
60
61
1/2
✓ Branch 0 (72→73) taken 5820 times.
✗ Branch 1 (72→81) not taken.
5820 if (lhsVar) { // Variable is involved on the left side
62 // Perform type inference
63
3/4
✓ Branch 0 (73→74) taken 5820 times.
✗ Branch 1 (73→120) not taken.
✓ Branch 2 (74→75) taken 1 times.
✓ Branch 3 (74→76) taken 5819 times.
5820 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 5820 times.
✗ Branch 1 (76→120) not taken.
✓ Branch 2 (77→78) taken 3 times.
✓ Branch 3 (77→79) taken 5817 times.
5820 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 5820 times.
✗ Branch 1 (79→118) not taken.
5820 lhsVar->updateState(INITIALIZED, node);
72 }
73
74
2/4
✓ Branch 0 (81→82) taken 5820 times.
✗ Branch 1 (81→119) not taken.
✓ Branch 2 (82→83) taken 5820 times.
✗ Branch 3 (82→119) not taken.
5820 return ExprResult{node->setEvaluatedSymbolType(rhsType, manIdx)};
75 }
76
77 throw CompilerError(UNHANDLED_BRANCH, "AssignExpr fall-through"); // GCOV_EXCL_LINE
78 }
79
80 62570 std::any TypeChecker::visitTernaryExpr(TernaryExprNode *node) {
81 // Check if there is a ternary operator applied
82
2/2
✓ Branch 0 (2→3) taken 62113 times.
✓ Branch 1 (2→5) taken 457 times.
62570 if (!node->falseExpr)
83
2/2
✓ Branch 0 (3→4) taken 62098 times.
✓ Branch 1 (3→150) taken 15 times.
62113 return visit(node->condition);
84
85 // Visit condition
86
2/4
✓ Branch 0 (5→6) taken 457 times.
✗ Branch 1 (5→115) not taken.
✓ Branch 2 (6→7) taken 457 times.
✗ Branch 3 (6→113) not taken.
457 const auto condition = std::any_cast<ExprResult>(visit(node->condition));
87
2/8
✓ Branch 0 (8→9) taken 457 times.
✗ Branch 1 (8→150) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 457 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.
457 HANDLE_UNRESOLVED_TYPE_ER(condition.type)
88
6/10
✓ Branch 0 (14→15) taken 1 times.
✓ Branch 1 (14→16) taken 456 times.
✓ Branch 2 (16→17) taken 456 times.
✗ Branch 3 (16→117) not taken.
✓ Branch 4 (17→18) taken 456 times.
✗ Branch 5 (17→117) not taken.
✓ Branch 6 (18→19) taken 456 times.
✓ Branch 7 (18→20) taken 1 times.
✗ Branch 8 (117→118) not taken.
✗ Branch 9 (117→119) not taken.
457 const auto trueExpr = node->isShortened ? condition : std::any_cast<ExprResult>(visit(node->trueExpr));
89 457 const auto [trueType, trueEntry] = trueExpr;
90
2/8
✓ Branch 0 (20→21) taken 457 times.
✗ Branch 1 (20→150) not taken.
✗ Branch 2 (21→22) not taken.
✓ Branch 3 (21→26) taken 457 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.
457 HANDLE_UNRESOLVED_TYPE_ER(trueType)
91
2/4
✓ Branch 0 (26→27) taken 457 times.
✗ Branch 1 (26→124) not taken.
✓ Branch 2 (27→28) taken 457 times.
✗ Branch 3 (27→122) not taken.
457 const auto falseExpr = std::any_cast<ExprResult>(visit(node->falseExpr));
92 457 const auto [falseType, falseEntry] = falseExpr;
93
2/8
✓ Branch 0 (29→30) taken 457 times.
✗ Branch 1 (29→150) not taken.
✗ Branch 2 (30→31) not taken.
✓ Branch 3 (30→35) taken 457 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.
457 HANDLE_UNRESOLVED_TYPE_ER(falseType)
94
95 // Check if the condition evaluates to bool
96
3/4
✓ Branch 0 (35→36) taken 457 times.
✗ Branch 1 (35→150) not taken.
✓ Branch 2 (36→37) taken 1 times.
✓ Branch 3 (36→47) taken 456 times.
457 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 456 times.
✗ Branch 1 (47→150) not taken.
456 const QualType trueTypeModified = trueType.removeReferenceWrapper();
101
1/2
✓ Branch 0 (48→49) taken 456 times.
✗ Branch 1 (48→150) not taken.
456 const QualType falseTypeModified = falseType.removeReferenceWrapper();
102
3/4
✓ Branch 0 (49→50) taken 456 times.
✗ Branch 1 (49→150) not taken.
✓ Branch 2 (50→51) taken 1 times.
✓ Branch 3 (50→66) taken 455 times.
456 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 455 bool removedAnonymousSymbols = false;
110
2/2
✓ Branch 0 (66→67) taken 117 times.
✓ Branch 1 (66→78) taken 338 times.
455 if (trueEntry) {
111
2/2
✓ Branch 0 (67→68) taken 70 times.
✓ Branch 1 (67→70) taken 47 times.
117 if (trueEntry->anonymous) {
112
1/2
✓ Branch 0 (68→69) taken 70 times.
✗ Branch 1 (68→150) not taken.
70 currentScope->symbolTable.deleteAnonymous(trueEntry->name);
113 70 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 297 times.
✓ Branch 1 (78→90) taken 158 times.
455 if (falseEntry) {
119
2/2
✓ Branch 0 (79→80) taken 69 times.
✓ Branch 1 (79→82) taken 228 times.
297 if (falseEntry->anonymous) {
120
1/2
✓ Branch 0 (80→81) taken 69 times.
✗ Branch 1 (80→150) not taken.
69 currentScope->symbolTable.deleteAnonymous(falseEntry->name);
121 69 removedAnonymousSymbols = true;
122
8/10
✓ Branch 0 (82→83) taken 228 times.
✗ Branch 1 (82→150) not taken.
✓ Branch 2 (83→84) taken 219 times.
✓ Branch 3 (83→87) taken 9 times.
✓ Branch 4 (84→85) taken 219 times.
✗ Branch 5 (84→150) not taken.
✓ Branch 6 (85→86) taken 8 times.
✓ Branch 7 (85→87) taken 211 times.
✓ Branch 8 (88→89) taken 8 times.
✓ Branch 9 (88→90) taken 220 times.
228 } 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 455 const QualType &resultType = trueType;
129 455 SymbolTableEntry *anonymousSymbol = nullptr;
130
4/4
✓ Branch 0 (90→91) taken 447 times.
✓ Branch 1 (90→92) taken 8 times.
✓ Branch 2 (91→92) taken 2 times.
✓ Branch 3 (91→93) taken 445 times.
455 const bool calledCopyCtor = node->trueSideCallsCopyCtor || node->falseSideCallsCopyCtor;
131
9/10
✓ Branch 0 (94→95) taken 383 times.
✓ Branch 1 (94→98) taken 72 times.
✓ Branch 2 (95→96) taken 377 times.
✓ Branch 3 (95→98) taken 6 times.
✓ Branch 4 (96→97) taken 377 times.
✗ Branch 5 (96→150) not taken.
✓ Branch 6 (97→98) taken 8 times.
✓ Branch 7 (97→99) taken 369 times.
✓ Branch 8 (100→101) taken 86 times.
✓ Branch 9 (100→103) taken 369 times.
455 if (removedAnonymousSymbols || calledCopyCtor || resultType.isRef())
132
1/2
✓ Branch 0 (101→102) taken 86 times.
✗ Branch 1 (101→150) not taken.
86 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 447 times.
✓ Branch 1 (103→105) taken 8 times.
✓ Branch 2 (104→105) taken 2 times.
✓ Branch 3 (104→107) taken 445 times.
455 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 455 times.
✗ Branch 1 (107→149) not taken.
✓ Branch 2 (108→109) taken 455 times.
✗ Branch 3 (108→149) not taken.
455 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), anonymousSymbol};
139 }
140
141 63483 std::any TypeChecker::visitLogicalOrExpr(LogicalOrExprNode *node) {
142 // Check if a logical or operator is applied
143
2/2
✓ Branch 0 (3→4) taken 62638 times.
✓ Branch 1 (3→7) taken 845 times.
63483 if (node->operands.size() == 1)
144
2/2
✓ Branch 0 (5→6) taken 62624 times.
✓ Branch 1 (5→46) taken 14 times.
62638 return visit(node->operands.front());
145
146 // Visit leftmost operand
147
2/4
✓ Branch 0 (8→9) taken 845 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 845 times.
✗ Branch 3 (9→37) not taken.
845 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
148
2/8
✓ Branch 0 (11→12) taken 845 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 845 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.
845 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
149
150 // Loop through all remaining operands
151
2/2
✓ Branch 0 (31→18) taken 1085 times.
✓ Branch 1 (31→32) taken 844 times.
1929 for (size_t i = 1; i < node->operands.size(); i++) {
152
2/4
✓ Branch 0 (19→20) taken 1085 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 1085 times.
✗ Branch 3 (20→41) not taken.
1085 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
153
2/8
✓ Branch 0 (22→23) taken 1085 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 1085 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.
1085 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
154
2/2
✓ Branch 0 (28→29) taken 1084 times.
✓ Branch 1 (28→45) taken 1 times.
1085 currentOperand = {OpRuleManager::getLogicalOrResultType(node, currentOperand, rhsOperand)};
155 }
156
157
1/2
✓ Branch 0 (32→33) taken 844 times.
✗ Branch 1 (32→46) not taken.
844 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
158
1/2
✓ Branch 0 (33→34) taken 844 times.
✗ Branch 1 (33→46) not taken.
844 return currentOperand;
159 }
160
161 64568 std::any TypeChecker::visitLogicalAndExpr(LogicalAndExprNode *node) {
162 // Check if a logical and operator is applied
163
2/2
✓ Branch 0 (3→4) taken 64423 times.
✓ Branch 1 (3→7) taken 145 times.
64568 if (node->operands.size() == 1)
164
2/2
✓ Branch 0 (5→6) taken 64409 times.
✓ Branch 1 (5→46) taken 14 times.
64423 return visit(node->operands.front());
165
166 // Visit leftmost operand
167
2/4
✓ Branch 0 (8→9) taken 145 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 145 times.
✗ Branch 3 (9→37) not taken.
145 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
168
2/8
✓ Branch 0 (11→12) taken 145 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 145 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.
145 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
169
170 // Loop through all remaining operands
171
2/2
✓ Branch 0 (31→18) taken 180 times.
✓ Branch 1 (31→32) taken 145 times.
325 for (size_t i = 1; i < node->operands.size(); i++) {
172
2/4
✓ Branch 0 (19→20) taken 180 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 180 times.
✗ Branch 3 (20→41) not taken.
180 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
173
2/8
✓ Branch 0 (22→23) taken 180 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 180 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.
180 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
174
1/2
✓ Branch 0 (28→29) taken 180 times.
✗ Branch 1 (28→45) not taken.
180 currentOperand = {OpRuleManager::getLogicalAndResultType(node, currentOperand, rhsOperand)};
175 }
176
177
1/2
✓ Branch 0 (32→33) taken 145 times.
✗ Branch 1 (32→46) not taken.
145 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
178
1/2
✓ Branch 0 (33→34) taken 145 times.
✗ Branch 1 (33→46) not taken.
145 return currentOperand;
179 }
180
181 64748 std::any TypeChecker::visitBitwiseOrExpr(BitwiseOrExprNode *node) {
182 // Check if a bitwise or operator is applied
183
2/2
✓ Branch 0 (3→4) taken 64679 times.
✓ Branch 1 (3→7) taken 69 times.
64748 if (node->operands.size() == 1)
184
2/2
✓ Branch 0 (5→6) taken 64666 times.
✓ Branch 1 (5→46) taken 13 times.
64679 return visit(node->operands.front());
185
186 // Visit leftmost operand
187
2/4
✓ Branch 0 (8→9) taken 69 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 69 times.
✗ Branch 3 (9→37) not taken.
69 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
188
2/8
✓ Branch 0 (11→12) taken 69 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 69 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.
69 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
189
190 // Loop through all remaining operands
191
2/2
✓ Branch 0 (31→18) taken 72 times.
✓ Branch 1 (31→32) taken 68 times.
140 for (size_t i = 1; i < node->operands.size(); i++) {
192
2/4
✓ Branch 0 (19→20) taken 72 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 72 times.
✗ Branch 3 (20→41) not taken.
72 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
193
2/8
✓ Branch 0 (22→23) taken 72 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 72 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.
72 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
194
2/2
✓ Branch 0 (28→29) taken 71 times.
✓ Branch 1 (28→45) taken 1 times.
72 currentOperand = {OpRuleManager::getBitwiseOrResultType(node, currentOperand, rhsOperand)};
195 }
196
197
1/2
✓ Branch 0 (32→33) taken 68 times.
✗ Branch 1 (32→46) not taken.
68 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
198
1/2
✓ Branch 0 (33→34) taken 68 times.
✗ Branch 1 (33→46) not taken.
68 return currentOperand;
199 }
200
201 64820 std::any TypeChecker::visitBitwiseXorExpr(BitwiseXorExprNode *node) {
202 // Check if a bitwise xor operator is applied
203
2/2
✓ Branch 0 (3→4) taken 64811 times.
✓ Branch 1 (3→7) taken 9 times.
64820 if (node->operands.size() == 1)
204
2/2
✓ Branch 0 (5→6) taken 64798 times.
✓ Branch 1 (5→46) taken 13 times.
64811 return visit(node->operands.front());
205
206 // Visit leftmost operand
207
2/4
✓ Branch 0 (8→9) taken 9 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 9 times.
✗ Branch 3 (9→37) not taken.
9 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
208
2/8
✓ Branch 0 (11→12) taken 9 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 9 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.
9 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
209
210 // Loop through all remaining operands
211
2/2
✓ Branch 0 (31→18) taken 12 times.
✓ Branch 1 (31→32) taken 9 times.
21 for (size_t i = 1; i < node->operands.size(); i++) {
212
2/4
✓ Branch 0 (19→20) taken 12 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 12 times.
✗ Branch 3 (20→41) not taken.
12 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
213
2/8
✓ Branch 0 (22→23) taken 12 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 12 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.
12 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
214
1/2
✓ Branch 0 (28→29) taken 12 times.
✗ Branch 1 (28→45) not taken.
12 currentOperand = {OpRuleManager::getBitwiseXorResultType(node, currentOperand, rhsOperand)};
215 }
216
217
1/2
✓ Branch 0 (32→33) taken 9 times.
✗ Branch 1 (32→46) not taken.
9 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
218
1/2
✓ Branch 0 (33→34) taken 9 times.
✗ Branch 1 (33→46) not taken.
9 return currentOperand;
219 }
220
221 64832 std::any TypeChecker::visitBitwiseAndExpr(BitwiseAndExprNode *node) {
222 // Check if a bitwise and operator is applied
223
2/2
✓ Branch 0 (3→4) taken 64805 times.
✓ Branch 1 (3→7) taken 27 times.
64832 if (node->operands.size() == 1)
224
2/2
✓ Branch 0 (5→6) taken 64792 times.
✓ Branch 1 (5→46) taken 13 times.
64805 return visit(node->operands.front());
225
226 // Visit leftmost operand
227
2/4
✓ Branch 0 (8→9) taken 27 times.
✗ Branch 1 (8→39) not taken.
✓ Branch 2 (9→10) taken 27 times.
✗ Branch 3 (9→37) not taken.
27 auto currentOperand = std::any_cast<ExprResult>(visit(node->operands[0]));
228
2/8
✓ Branch 0 (11→12) taken 27 times.
✗ Branch 1 (11→46) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 27 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.
27 HANDLE_UNRESOLVED_TYPE_ER(currentOperand.type)
229
230 // Loop through all remaining operands
231
2/2
✓ Branch 0 (31→18) taken 30 times.
✓ Branch 1 (31→32) taken 27 times.
57 for (size_t i = 1; i < node->operands.size(); i++) {
232
2/4
✓ Branch 0 (19→20) taken 30 times.
✗ Branch 1 (19→43) not taken.
✓ Branch 2 (20→21) taken 30 times.
✗ Branch 3 (20→41) not taken.
30 auto rhsOperand = std::any_cast<ExprResult>(visit(node->operands[i]));
233
2/8
✓ Branch 0 (22→23) taken 30 times.
✗ Branch 1 (22→45) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 30 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.
30 HANDLE_UNRESOLVED_TYPE_ER(rhsOperand.type)
234
1/2
✓ Branch 0 (28→29) taken 30 times.
✗ Branch 1 (28→45) not taken.
30 currentOperand = {OpRuleManager::getBitwiseAndResultType(node, currentOperand, rhsOperand)};
235 }
236
237
1/2
✓ Branch 0 (32→33) taken 27 times.
✗ Branch 1 (32→46) not taken.
27 node->setEvaluatedSymbolType(currentOperand.type, manIdx);
238
1/2
✓ Branch 0 (33→34) taken 27 times.
✗ Branch 1 (33→46) not taken.
27 return currentOperand;
239 }
240
241 64862 std::any TypeChecker::visitEqualityExpr(EqualityExprNode *node) {
242 // Check if at least one equality operator is applied
243
2/2
✓ Branch 0 (3→4) taken 60081 times.
✓ Branch 1 (3→7) taken 4781 times.
64862 if (node->operands.size() == 1)
244
2/2
✓ Branch 0 (5→6) taken 60069 times.
✓ Branch 1 (5→73) taken 12 times.
60081 return visit(node->operands.front());
245
246 // Visit right side first, then left side
247
2/4
✓ Branch 0 (8→9) taken 4781 times.
✗ Branch 1 (8→58) not taken.
✓ Branch 2 (9→10) taken 4781 times.
✗ Branch 3 (9→56) not taken.
4781 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
248
2/8
✓ Branch 0 (11→12) taken 4781 times.
✗ Branch 1 (11→73) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 4781 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.
4781 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
249
2/4
✓ Branch 0 (18→19) taken 4781 times.
✗ Branch 1 (18→62) not taken.
✓ Branch 2 (19→20) taken 4781 times.
✗ Branch 3 (19→60) not taken.
4781 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
250
2/8
✓ Branch 0 (21→22) taken 4781 times.
✗ Branch 1 (21→73) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 4781 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.
4781 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 4781 times.
✗ Branch 1 (27→73) not taken.
✓ Branch 2 (28→29) taken 132 times.
✓ Branch 3 (28→36) taken 4649 times.
✓ Branch 4 (29→30) taken 132 times.
✗ Branch 5 (29→73) not taken.
✓ Branch 6 (30→31) taken 131 times.
✓ Branch 7 (30→36) taken 1 times.
✓ Branch 8 (31→32) taken 131 times.
✗ Branch 9 (31→73) not taken.
✓ Branch 10 (34→35) taken 131 times.
✗ Branch 11 (34→36) not taken.
✓ Branch 12 (37→38) taken 131 times.
✓ Branch 13 (37→39) taken 4650 times.
4912 if (lhs.type.is(TY_STRING) && rhs.type.is(TY_STRING) && !sourceFile->isStringRT())
254
1/2
✓ Branch 0 (38→39) taken 131 times.
✗ Branch 1 (38→73) not taken.
131 sourceFile->requestRuntimeModule(STRING_RT);
255
256 // Check operator
257 4781 ExprResult result;
258
2/2
✓ Branch 0 (39→40) taken 3407 times.
✓ Branch 1 (39→41) taken 1374 times.
4781 if (node->op == EqualityExprNode::EqualityOp::OP_EQUAL) // Operator was equal
259
2/2
✓ Branch 0 (40→51) taken 3406 times.
✓ Branch 1 (40→73) taken 1 times.
3407 result = opRuleManager.getEqualResultType(node, lhs, rhs, 0);
260
1/2
✓ Branch 0 (41→42) taken 1374 times.
✗ Branch 1 (41→43) not taken.
1374 else if (node->op == EqualityExprNode::EqualityOp::OP_NOT_EQUAL) // Operator was not equal
261
1/2
✓ Branch 0 (42→51) taken 1374 times.
✗ Branch 1 (42→73) not taken.
1374 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 4780 times.
✗ Branch 1 (51→73) not taken.
4780 node->setEvaluatedSymbolType(result.type, manIdx);
266
1/2
✓ Branch 0 (52→53) taken 4780 times.
✗ Branch 1 (52→73) not taken.
4780 return result;
267 }
268
269 69643 std::any TypeChecker::visitRelationalExpr(RelationalExprNode *node) {
270 // Check if a relational operator is applied
271
2/2
✓ Branch 0 (3→4) taken 66204 times.
✓ Branch 1 (3→7) taken 3439 times.
69643 if (node->operands.size() == 1)
272
2/2
✓ Branch 0 (5→6) taken 66193 times.
✓ Branch 1 (5→75) taken 11 times.
66204 return visit(node->operands.front());
273
274 // Visit right side first, then left side
275
2/4
✓ Branch 0 (8→9) taken 3439 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 3439 times.
✗ Branch 3 (9→53) not taken.
3439 const auto rhs = std::any_cast<ExprResult>(visit(node->operands[1]));
276
5/8
✓ Branch 0 (11→12) taken 3439 times.
✗ Branch 1 (11→75) not taken.
✓ Branch 2 (12→13) taken 1 times.
✓ Branch 3 (12→17) taken 3438 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.
3439 HANDLE_UNRESOLVED_TYPE_ER(rhs.type)
277
2/4
✓ Branch 0 (18→19) taken 3438 times.
✗ Branch 1 (18→59) not taken.
✓ Branch 2 (19→20) taken 3438 times.
✗ Branch 3 (19→57) not taken.
3438 const auto lhs = std::any_cast<ExprResult>(visit(node->operands[0]));
278
2/8
✓ Branch 0 (21→22) taken 3438 times.
✗ Branch 1 (21→75) not taken.
✗ Branch 2 (22→23) not taken.
✓ Branch 3 (22→27) taken 3438 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.
3438 HANDLE_UNRESOLVED_TYPE_ER(lhs.type)
279
280 // Check operator
281 3438 QualType resultType;
282
2/2
✓ Branch 0 (27→28) taken 1685 times.
✓ Branch 1 (27→30) taken 1753 times.
3438 if (node->op == RelationalExprNode::RelationalOp::OP_LESS) // Operator was less
283
1/2
✓ Branch 0 (28→29) taken 1685 times.
✗ Branch 1 (28→61) not taken.
1685 resultType = OpRuleManager::getLessResultType(node, lhs, rhs);
284
2/2
✓ Branch 0 (30→31) taken 477 times.
✓ Branch 1 (30→33) taken 1276 times.
1753 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 357 times.
✓ Branch 1 (33→36) taken 919 times.
1276 else if (node->op == RelationalExprNode::RelationalOp::OP_LESS_EQUAL) // Operator was less equal
287
1/2
✓ Branch 0 (34→35) taken 357 times.
✗ Branch 1 (34→63) not taken.
357 resultType = OpRuleManager::getLessEqualResultType(node, lhs, rhs);
288
1/2
✓ Branch 0 (36→37) taken 919 times.
✗ Branch 1 (36→39) not taken.
919 else if (node->op == RelationalExprNode::RelationalOp::OP_GREATER_EQUAL) // Operator was greater equal
289
1/2
✓ Branch 0 (37→38) taken 919 times.
✗ Branch 1 (37→64) not taken.
919 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 3437 times.
✗ Branch 1 (47→74) not taken.
✓ Branch 2 (48→49) taken 3437 times.
✗ Branch 3 (48→74) not taken.
3437 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx)};
294 }
295
296 73081 std::any TypeChecker::visitShiftExpr(ShiftExprNode *node) {
297 // Check if at least one shift operator is applied
298
2/2
✓ Branch 0 (3→4) taken 72984 times.
✓ Branch 1 (3→7) taken 97 times.
73081 if (node->operands.size() == 1)
299
2/2
✓ Branch 0 (5→6) taken 72973 times.
✓ Branch 1 (5→69) taken 11 times.
72984 return visit(node->operands.front());
300
301 // Visit leftmost operand
302
2/4
✓ Branch 0 (8→9) taken 97 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 97 times.
✗ Branch 3 (9→51) not taken.
97 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
303
2/8
✓ Branch 0 (11→12) taken 97 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 97 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.
97 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
304
305 // Loop through remaining operands
306
2/2
✓ Branch 0 (45→18) taken 137 times.
✓ Branch 1 (45→46) taken 97 times.
234 for (size_t i = 0; i < node->opQueue.size(); i++) {
307
2/4
✓ Branch 0 (19→20) taken 137 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 137 times.
✗ Branch 3 (20→55) not taken.
137 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
308
2/8
✓ Branch 0 (22→23) taken 137 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 137 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.
137 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
309
310 // Check operator
311 137 const ShiftExprNode::ShiftOp &op = node->opQueue.front().first;
312
2/2
✓ Branch 0 (29→30) taken 95 times.
✓ Branch 1 (29→31) taken 42 times.
137 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 42 times.
✗ Branch 1 (31→33) not taken.
42 else if (op == ShiftExprNode::ShiftOp::OP_SHIFT_RIGHT)
315
1/2
✓ Branch 0 (32→41) taken 42 times.
✗ Branch 1 (32→68) not taken.
42 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 137 times.
✗ Branch 1 (41→68) not taken.
137 node->opQueue.emplace(op, currentResult.type);
321 137 node->opQueue.pop();
322 }
323
324
1/2
✓ Branch 0 (46→47) taken 97 times.
✗ Branch 1 (46→69) not taken.
97 node->setEvaluatedSymbolType(currentResult.type, manIdx);
325
1/2
✓ Branch 0 (47→48) taken 97 times.
✗ Branch 1 (47→69) not taken.
97 return currentResult;
326 }
327
328 73218 std::any TypeChecker::visitAdditiveExpr(AdditiveExprNode *node) {
329 // Check if at least one additive operator is applied
330
2/2
✓ Branch 0 (3→4) taken 69299 times.
✓ Branch 1 (3→7) taken 3919 times.
73218 if (node->operands.size() == 1)
331
2/2
✓ Branch 0 (5→6) taken 69289 times.
✓ Branch 1 (5→69) taken 10 times.
69299 return visit(node->operands.front());
332
333 // Visit leftmost operand
334
2/4
✓ Branch 0 (8→9) taken 3919 times.
✗ Branch 1 (8→53) not taken.
✓ Branch 2 (9→10) taken 3919 times.
✗ Branch 3 (9→51) not taken.
3919 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
335
2/8
✓ Branch 0 (11→12) taken 3919 times.
✗ Branch 1 (11→69) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 3919 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.
3919 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
336
337 // Loop through remaining operands
338
2/2
✓ Branch 0 (45→18) taken 4470 times.
✓ Branch 1 (45→46) taken 3918 times.
8388 for (size_t i = 0; i < node->opQueue.size(); i++) {
339
2/4
✓ Branch 0 (19→20) taken 4470 times.
✗ Branch 1 (19→57) not taken.
✓ Branch 2 (20→21) taken 4470 times.
✗ Branch 3 (20→55) not taken.
4470 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
340
2/8
✓ Branch 0 (22→23) taken 4470 times.
✗ Branch 1 (22→68) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 4470 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.
4470 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
341
342 // Check operator
343 4470 const AdditiveExprNode::AdditiveOp &op = node->opQueue.front().first;
344
2/2
✓ Branch 0 (29→30) taken 2744 times.
✓ Branch 1 (29→31) taken 1726 times.
4470 if (op == AdditiveExprNode::AdditiveOp::OP_PLUS)
345
2/2
✓ Branch 0 (30→41) taken 2743 times.
✓ Branch 1 (30→68) taken 1 times.
2744 currentResult = opRuleManager.getPlusResultType(node, currentResult, operandResult, i);
346
1/2
✓ Branch 0 (31→32) taken 1726 times.
✗ Branch 1 (31→33) not taken.
1726 else if (op == AdditiveExprNode::AdditiveOp::OP_MINUS)
347
1/2
✓ Branch 0 (32→41) taken 1726 times.
✗ Branch 1 (32→68) not taken.
1726 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 4469 times.
✗ Branch 1 (41→68) not taken.
4469 node->opQueue.emplace(op, currentResult.type);
353 4469 node->opQueue.pop();
354 }
355
356
1/2
✓ Branch 0 (46→47) taken 3918 times.
✗ Branch 1 (46→69) not taken.
3918 node->setEvaluatedSymbolType(currentResult.type, manIdx);
357
1/2
✓ Branch 0 (47→48) taken 3918 times.
✗ Branch 1 (47→69) not taken.
3918 return currentResult;
358 }
359
360 77688 std::any TypeChecker::visitMultiplicativeExpr(MultiplicativeExprNode *node) {
361 // Check if at least one multiplicative operator is applied
362
2/2
✓ Branch 0 (3→4) taken 76861 times.
✓ Branch 1 (3→7) taken 827 times.
77688 if (node->operands.size() == 1)
363
2/2
✓ Branch 0 (5→6) taken 76852 times.
✓ Branch 1 (5→71) taken 9 times.
76861 return visit(node->operands.front());
364
365 // Visit leftmost operand
366
2/4
✓ Branch 0 (8→9) taken 827 times.
✗ Branch 1 (8→55) not taken.
✓ Branch 2 (9→10) taken 827 times.
✗ Branch 3 (9→53) not taken.
827 auto currentResult = std::any_cast<ExprResult>(visit(node->operands[0]));
367
2/8
✓ Branch 0 (11→12) taken 827 times.
✗ Branch 1 (11→71) not taken.
✗ Branch 2 (12→13) not taken.
✓ Branch 3 (12→17) taken 827 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.
827 HANDLE_UNRESOLVED_TYPE_ER(currentResult.type)
368 // Loop through remaining operands
369
2/2
✓ Branch 0 (47→18) taken 851 times.
✓ Branch 1 (47→48) taken 826 times.
1677 for (size_t i = 0; i < node->opQueue.size(); i++) {
370
2/4
✓ Branch 0 (19→20) taken 851 times.
✗ Branch 1 (19→59) not taken.
✓ Branch 2 (20→21) taken 851 times.
✗ Branch 3 (20→57) not taken.
851 auto operandResult = std::any_cast<ExprResult>(visit(node->operands[i + 1]));
371
2/8
✓ Branch 0 (22→23) taken 851 times.
✗ Branch 1 (22→70) not taken.
✗ Branch 2 (23→24) not taken.
✓ Branch 3 (23→28) taken 851 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.
851 HANDLE_UNRESOLVED_TYPE_ER(operandResult.type)
372
373 // Check operator
374 851 const MultiplicativeExprNode::MultiplicativeOp &op = node->opQueue.front().first;
375
2/2
✓ Branch 0 (29→30) taken 707 times.
✓ Branch 1 (29→31) taken 144 times.
851 if (op == MultiplicativeExprNode::MultiplicativeOp::OP_MUL)
376
2/2
✓ Branch 0 (30→43) taken 706 times.
✓ Branch 1 (30→70) taken 1 times.
707 currentResult = opRuleManager.getMulResultType(node, currentResult, operandResult, i);
377
2/2
✓ Branch 0 (31→32) taken 134 times.
✓ Branch 1 (31→33) taken 10 times.
144 else if (op == MultiplicativeExprNode::MultiplicativeOp::OP_DIV)
378
1/2
✓ Branch 0 (32→43) taken 134 times.
✗ Branch 1 (32→70) not taken.
134 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 850 times.
✗ Branch 1 (43→70) not taken.
850 node->opQueue.emplace(op, currentResult.type);
386 850 node->opQueue.pop();
387 }
388
389
1/2
✓ Branch 0 (48→49) taken 826 times.
✗ Branch 1 (48→71) not taken.
826 node->setEvaluatedSymbolType(currentResult.type, manIdx);
390
1/2
✓ Branch 0 (49→50) taken 826 times.
✗ Branch 1 (49→71) not taken.
826 return currentResult;
391 }
392
393 78539 std::any TypeChecker::visitCastExpr(CastExprNode *node) {
394 // Check if cast is applied
395
2/2
✓ Branch 0 (2→3) taken 76178 times.
✓ Branch 1 (2→5) taken 2361 times.
78539 if (!node->isCast)
396
2/2
✓ Branch 0 (3→4) taken 76169 times.
✓ Branch 1 (3→65) taken 9 times.
76178 return visit(node->prefixUnaryExpr);
397
398 // Visit destination type
399
2/4
✓ Branch 0 (5→6) taken 2361 times.
✗ Branch 1 (5→49) not taken.
✓ Branch 2 (6→7) taken 2361 times.
✗ Branch 3 (6→47) not taken.
2361 const auto dstType = std::any_cast<QualType>(visit(node->dataType));
400
2/8
✓ Branch 0 (8→9) taken 2361 times.
✗ Branch 1 (8→65) not taken.
✗ Branch 2 (9→10) not taken.
✓ Branch 3 (9→14) taken 2361 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.
2361 HANDLE_UNRESOLVED_TYPE_ER(dstType)
401 // Visit source type
402
2/4
✓ Branch 0 (14→15) taken 2361 times.
✗ Branch 1 (14→53) not taken.
✓ Branch 2 (15→16) taken 2361 times.
✗ Branch 3 (15→51) not taken.
2361 const auto src = std::any_cast<ExprResult>(visit(node->assignExpr));
403
2/8
✓ Branch 0 (17→18) taken 2361 times.
✗ Branch 1 (17→65) not taken.
✗ Branch 2 (18→19) not taken.
✓ Branch 3 (18→23) taken 2361 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.
2361 HANDLE_UNRESOLVED_TYPE_ER(src.type)
404
405 // Check for identity cast
406
3/4
✓ Branch 0 (23→24) taken 2361 times.
✗ Branch 1 (23→65) not taken.
✓ Branch 2 (24→25) taken 229 times.
✓ Branch 3 (24→34) taken 2132 times.
2361 if (src.type == dstType) {
407
2/4
✓ Branch 0 (27→28) taken 229 times.
✗ Branch 1 (27→57) not taken.
✓ Branch 2 (28→29) taken 229 times.
✗ Branch 3 (28→55) not taken.
229 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 229 times.
✗ Branch 1 (31→61) not taken.
229 sourceFile->compilerOutput.warnings.push_back(warning);
409 229 }
410
411 // Get result type
412
1/2
✓ Branch 0 (34→35) taken 2361 times.
✗ Branch 1 (34→65) not taken.
2361 const QualType resultType = opRuleManager.getCastResultType(node, dstType, src);
413
414
1/2
✓ Branch 0 (35→36) taken 2361 times.
✗ Branch 1 (35→65) not taken.
2361 const bool typesMatch = dstType.matches(src.type, false, true, true);
415
1/2
✓ Branch 0 (36→37) taken 2361 times.
✗ Branch 1 (36→65) not taken.
2361 const bool sameContainerType = src.type.isSameContainerTypeAs(dstType);
416
4/4
✓ Branch 0 (37→38) taken 2132 times.
✓ Branch 1 (37→39) taken 229 times.
✓ Branch 2 (38→39) taken 122 times.
✓ Branch 3 (38→40) taken 2010 times.
2361 SymbolTableEntry *entry = typesMatch || sameContainerType ? src.entry : nullptr;
417
2/4
✓ Branch 0 (41→42) taken 2361 times.
✗ Branch 1 (41→64) not taken.
✓ Branch 2 (42→43) taken 2361 times.
✗ Branch 3 (42→64) not taken.
2361 return ExprResult{node->setEvaluatedSymbolType(resultType, manIdx), entry};
418 }
419
420 82994 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 82000 times.
✓ Branch 1 (2→5) taken 994 times.
82994 if (node->op == PrefixUnaryExprNode::PrefixUnaryOp::OP_NONE)
423
2/2
✓ Branch 0 (3→4) taken 81992 times.
✓ Branch 1 (3→78) taken 8 times.
82000 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 684 times.
✓ Branch 4 (14→35) taken 1 times.
✓ Branch 5 (14→37) taken 180 times.
✓ Branch 6 (14→39) taken 85 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 684 case PrefixUnaryExprNode::PrefixUnaryOp::OP_NOT:
462
1/2
✓ Branch 0 (33→34) taken 684 times.
✗ Branch 1 (33→64) not taken.
684 operandType = OpRuleManager::getPrefixNotResultType(node, operand);
463 684 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 180 case PrefixUnaryExprNode::PrefixUnaryOp::OP_DEREFERENCE:
468
1/2
✓ Branch 0 (37→38) taken 180 times.
✗ Branch 1 (37→66) not taken.
180 operandType = OpRuleManager::getPrefixMulResultType(node, operand);
469 180 break;
470 85 case PrefixUnaryExprNode::PrefixUnaryOp::OP_ADDRESS_OF:
471
1/2
✓ Branch 0 (39→40) taken 85 times.
✗ Branch 1 (39→67) not taken.
85 operandType = OpRuleManager::getPrefixBitwiseAndResultType(node, operand);
472 85 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 101798 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 82000 times.
✓ Branch 1 (2→5) taken 19798 times.
101798 if (node->op == PostfixUnaryExprNode::PostfixUnaryOp::OP_NONE)
483
2/2
✓ Branch 0 (3→4) taken 81993 times.
✓ Branch 1 (3→316) taken 7 times.
82000 return visit(node->atomicExpr);
484
485 // Visit left side
486 19798 PostfixUnaryExprNode *lhsNode = node->postfixUnaryExpr;
487
2/4
✓ Branch 0 (5→6) taken 19798 times.
✗ Branch 1 (5→211) not taken.
✓ Branch 2 (6→7) taken 19798 times.
✗ Branch 3 (6→209) not taken.
19798 auto operand = std::any_cast<ExprResult>(visit(lhsNode));
488 19798 auto [operandType, operandEntry] = operand;
489
5/8
✓ Branch 0 (8→9) taken 19798 times.
✗ Branch 1 (8→316) not taken.
✓ Branch 2 (9→10) taken 6 times.
✓ Branch 3 (9→14) taken 19792 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.
19798 HANDLE_UNRESOLVED_TYPE_ER(operandType)
490
491
4/5
✓ Branch 0 (14→15) taken 3089 times.
✓ Branch 1 (14→101) taken 14686 times.
✓ Branch 2 (14→159) taken 1637 times.
✓ Branch 3 (14→167) taken 380 times.
✗ Branch 4 (14→175) not taken.
19792 switch (node->op) {
492 3089 case PostfixUnaryExprNode::PostfixUnaryOp::OP_SUBSCRIPT: {
493 // Visit index assignment
494 3089 AssignExprNode *indexAssignExpr = node->subscriptIndexExpr;
495
2/4
✓ Branch 0 (15→16) taken 3089 times.
✗ Branch 1 (15→215) not taken.
✓ Branch 2 (16→17) taken 3089 times.
✗ Branch 3 (16→213) not taken.
3089 const auto index = std::any_cast<ExprResult>(visit(indexAssignExpr));
496
2/8
✓ Branch 0 (18→19) taken 3089 times.
✗ Branch 1 (18→258) not taken.
✗ Branch 2 (19→20) not taken.
✓ Branch 3 (19→24) taken 3089 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.
3089 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 3089 times.
✗ Branch 1 (24→217) not taken.
3089 const auto [type, _] = opRuleManager.isOperatorOverloadingFctAvailable<2>(node, OP_FCT_SUBSCRIPT, {operand, index}, 0);
500
3/4
✓ Branch 0 (25→26) taken 3089 times.
✗ Branch 1 (25→258) not taken.
✓ Branch 2 (26→27) taken 110 times.
✓ Branch 3 (26→28) taken 2979 times.
3089 if (!type.is(TY_INVALID)) {
501 110 operandType = type;
502 3087 break;
503 }
504
505
1/2
✓ Branch 0 (28→29) taken 2979 times.
✗ Branch 1 (28→218) not taken.
2979 operandType = operandType.removeReferenceWrapper();
506
507 // Check if the index is of the right type
508
3/4
✓ Branch 0 (29→30) taken 2979 times.
✗ Branch 1 (29→219) not taken.
✓ Branch 2 (30→31) taken 1 times.
✓ Branch 3 (30→41) taken 2978 times.
2979 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 2978 times.
✗ Branch 1 (41→227) not taken.
✗ Branch 2 (42→43) not taken.
✓ Branch 3 (42→52) taken 2978 times.
2978 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 2978 times.
✗ Branch 1 (52→258) not taken.
✓ Branch 2 (53→54) taken 2135 times.
✓ Branch 3 (53→57) taken 843 times.
✓ Branch 4 (54→55) taken 2135 times.
✗ Branch 5 (54→258) not taken.
✗ Branch 6 (55→56) not taken.
✓ Branch 7 (55→57) taken 2135 times.
✗ Branch 8 (58→59) not taken.
✓ Branch 9 (58→69) taken 2978 times.
2978 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 2978 times.
✗ Branch 1 (69→258) not taken.
✓ Branch 2 (70→71) taken 140 times.
✓ Branch 3 (70→76) taken 2838 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 2944 times.
2978 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 2977 times.
✗ Branch 1 (96→257) not taken.
2977 operandType = operandType.getContained();
537
538 // Remove heap qualifier
539 2977 operandType.getQualifiers().isHeap = false;
540
541 2977 break;
542 }
543 14686 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MEMBER_ACCESS: {
544 14686 const std::string &fieldName = node->identifier;
545
546 // Check if lhs is enum or strobj
547
1/2
✓ Branch 0 (101→102) taken 14686 times.
✗ Branch 1 (101→286) not taken.
14686 const QualType lhsBaseTy = operandType.autoDeReference();
548
3/4
✓ Branch 0 (102→103) taken 14686 times.
✗ Branch 1 (102→286) not taken.
✓ Branch 2 (103→104) taken 1 times.
✓ Branch 3 (103→113) taken 14685 times.
14686 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 14685 times.
✗ Branch 1 (113→286) not taken.
14685 const std::string &structName = lhsBaseTy.getSubType();
553
1/2
✓ Branch 0 (114→115) taken 14685 times.
✗ Branch 1 (114→286) not taken.
14685 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 14607 times.
14685 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 14685 times.
14685 assert(!structScope->isGenericScope); // At this point we always expect a substantiation scope
562
563 // Get accessed field
564 14685 std::vector<size_t> indexPath;
565
1/2
✓ Branch 0 (122→123) taken 14685 times.
✗ Branch 1 (122→284) not taken.
14685 SymbolTableEntry *memberEntry = structScope->symbolTable.lookupInComposedFields(fieldName, indexPath);
566
2/2
✓ Branch 0 (123→124) taken 2 times.
✓ Branch 1 (123→135) taken 14683 times.
14685 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 14683 times.
✗ Branch 1 (135→284) not taken.
14683 const QualType memberType = memberEntry->getQualType();
569
570 // Check for insufficient visibility
571
8/14
✓ Branch 0 (136→137) taken 14683 times.
✗ Branch 1 (136→276) not taken.
✓ Branch 2 (137→138) taken 74 times.
✓ Branch 3 (137→143) taken 14609 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 14683 times.
14683 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 14683 memberEntry->used = true;
576
577 // Overwrite type and entry of left side with member type and entry
578 14683 operandType = memberType;
579 14683 operandEntry = memberEntry;
580 14683 break;
581
2/2
✓ Branch 0 (156→157) taken 2 times.
✓ Branch 1 (156→158) taken 14683 times.
14685 }
582 1637 case PostfixUnaryExprNode::PostfixUnaryOp::OP_PLUS_PLUS: {
583
2/2
✓ Branch 0 (159→160) taken 1636 times.
✓ Branch 1 (159→287) taken 1 times.
1637 operandType = opRuleManager.getPostfixPlusPlusResultType(node, operand, 0).type;
584
585
2/2
✓ Branch 0 (160→161) taken 1632 times.
✓ Branch 1 (160→166) taken 4 times.
1636 if (operandEntry) {
586 // In case the lhs is captured, notify the capture about the write access
587
3/4
✓ Branch 0 (161→162) taken 1632 times.
✗ Branch 1 (161→316) not taken.
✓ Branch 2 (162→163) taken 4 times.
✓ Branch 3 (162→164) taken 1628 times.
1632 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 1632 times.
✗ Branch 1 (164→288) not taken.
1632 operandEntry->updateState(INITIALIZED, node);
592 }
593
594 1636 break;
595 }
596 380 case PostfixUnaryExprNode::PostfixUnaryOp::OP_MINUS_MINUS: {
597
1/2
✓ Branch 0 (167→168) taken 380 times.
✗ Branch 1 (167→289) not taken.
380 operandType = opRuleManager.getPostfixMinusMinusResultType(node, operand, 0).type;
598
599
2/2
✓ Branch 0 (168→169) taken 376 times.
✓ Branch 1 (168→174) taken 4 times.
380 if (operandEntry) {
600 // In case the lhs is captured, notify the capture about the write access
601
2/4
✓ Branch 0 (169→170) taken 376 times.
✗ Branch 1 (169→316) not taken.
✗ Branch 2 (170→171) not taken.
✓ Branch 3 (170→172) taken 376 times.
376 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 376 times.
✗ Branch 1 (172→290) not taken.
376 operandEntry->updateState(INITIALIZED, node);
606 }
607
608 380 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 19786 times.
✗ Branch 1 (183→316) not taken.
✗ Branch 2 (184→185) not taken.
✓ Branch 3 (184→203) taken 19786 times.
19786 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 19786 times.
✗ Branch 1 (203→315) not taken.
✓ Branch 2 (204→205) taken 19786 times.
✗ Branch 3 (204→315) not taken.
19786 return ExprResult{node->setEvaluatedSymbolType(operandType, manIdx), operandEntry};
620 }
621
622 82000 std::any TypeChecker::visitAtomicExpr(AtomicExprNode *node) {
623 // Check if constant
624
2/2
✓ Branch 0 (2→3) taken 16258 times.
✓ Branch 1 (2→5) taken 65742 times.
82000 if (node->constant)
625
1/2
✓ Branch 0 (3→4) taken 16258 times.
✗ Branch 1 (3→219) not taken.
16258 return visit(node->constant);
626
627 // Check if value
628
2/2
✓ Branch 0 (5→6) taken 15983 times.
✓ Branch 1 (5→8) taken 49759 times.
65742 if (node->value)
629
2/2
✓ Branch 0 (6→7) taken 15979 times.
✓ Branch 1 (6→219) taken 4 times.
15983 return visit(node->value);
630
631 // Check for builtin calls
632
2/2
✓ Branch 0 (8→9) taken 1596 times.
✓ Branch 1 (8→11) taken 48163 times.
49759 if (node->builtinCall)
633
1/2
✓ Branch 0 (9→10) taken 1596 times.
✗ Branch 1 (9→219) not taken.
1596 return visit(node->builtinCall);
634
635 // Check for assign expression within parentheses
636
2/2
✓ Branch 0 (11→12) taken 532 times.
✓ Branch 1 (11→14) taken 47631 times.
48163 if (node->assignExpr)
637
2/2
✓ Branch 0 (12→13) taken 529 times.
✓ Branch 1 (12→219) taken 3 times.
532 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 47631 times.
47631 assert(!node->fqIdentifier.empty());
641
642
1/2
✓ Branch 0 (17→18) taken 47631 times.
✗ Branch 1 (17→219) not taken.
47631 auto &[entry, accessScope, capture] = node->data.at(manIdx);
643 47631 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 47388 times.
✓ Branch 1 (19→25) taken 243 times.
47631 if (node->identifierFragments.size() == 1)
647 94776 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 47312 times.
47631 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 47630 times.
47630 assert(entry != nullptr);
658 47630 entry->used = true;
659
1/2
✓ Branch 0 (40→41) taken 47630 times.
✗ Branch 1 (40→219) not taken.
47630 capture = accessScope->symbolTable.lookupCapture(entry->name);
660
661
1/2
✓ Branch 0 (41→42) taken 47630 times.
✗ Branch 1 (41→219) not taken.
47630 const QualType varType = entry->getQualType();
662
5/8
✓ Branch 0 (42→43) taken 47630 times.
✗ Branch 1 (42→219) not taken.
✓ Branch 2 (43→44) taken 9 times.
✓ Branch 3 (43→48) taken 47621 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.
47630 HANDLE_UNRESOLVED_TYPE_ER(varType)
663
3/4
✓ Branch 0 (48→49) taken 47621 times.
✗ Branch 1 (48→219) not taken.
✓ Branch 2 (49→50) taken 2 times.
✓ Branch 3 (49→59) taken 47619 times.
47621 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 47619 times.
✗ Branch 1 (59→178) not taken.
✓ Branch 2 (60→61) taken 25 times.
✓ Branch 3 (60→63) taken 47594 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 47610 times.
47619 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 47617 times.
✗ Branch 1 (93→219) not taken.
47617 const QualType baseType = varType.getBase();
681
6/10
✓ Branch 0 (94→95) taken 47617 times.
✗ Branch 1 (94→219) not taken.
✓ Branch 2 (95→96) taken 2 times.
✓ Branch 3 (95→99) taken 47615 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 47617 times.
47617 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 47616 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 47616 times.
47617 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 47616 times.
✗ Branch 1 (128→219) not taken.
✓ Branch 2 (129→130) taken 199 times.
✓ Branch 3 (129→132) taken 47417 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 47538 times.
47616 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 47377 times.
47615 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 47615 times.
✗ Branch 1 (149→219) not taken.
✓ Branch 2 (150→151) taken 16663 times.
✓ Branch 3 (150→157) taken 30952 times.
47615 if (baseType.is(TY_STRUCT)) {
701
1/2
✓ Branch 0 (151→152) taken 16663 times.
✗ Branch 1 (151→219) not taken.
16663 const std::string &structName = baseType.getSubType();
702
1/2
✓ Branch 0 (152→153) taken 16663 times.
✗ Branch 1 (152→219) not taken.
16663 const NameRegistryEntry *nameRegistryEntry = sourceFile->getNameRegistryEntry(structName);
703
1/2
✗ Branch 0 (153→154) not taken.
✓ Branch 1 (153→155) taken 16663 times.
16663 assert(nameRegistryEntry != nullptr);
704 16663 accessScope = nameRegistryEntry->targetScope;
705
1/2
✗ Branch 0 (155→156) not taken.
✓ Branch 1 (155→157) taken 16663 times.
16663 assert(accessScope != nullptr);
706 }
707
708
2/4
✓ Branch 0 (157→158) taken 47615 times.
✗ Branch 1 (157→218) not taken.
✓ Branch 2 (158→159) taken 47615 times.
✗ Branch 3 (158→218) not taken.
47615 return ExprResult{node->setEvaluatedSymbolType(varType, manIdx), entry};
709 }
710
711 } // namespace spice::compiler
712