Skip to content

Commit 853a1e9

Browse files
committed
Add support for nested ifs/else-ifs
This change brings support for nested `if` or `else if`. It make possible to process the following code: ```cpp main: (args) = { p : *int; a := 1; b := 2; c := 3; d := 4; if args.cout == 3 { p = a&; } else if p = b& { if args.cout == 2 { p = c&; } else { if b > 0 { p = a&; } else { p = d&; } } } else { p = c&; } std::cout << p* << std::endl; } ``` And gets generated: ```cpp auto main(int const argc_, char const* const* const argv_) -> int{ auto args = cpp2::make_args(argc_, argv_); cpp2::deferred_init<int*> p; auto a {1}; auto b {2}; auto c {3}; auto d {4}; if (args.cout==3) { p.construct(&a); } else if (p.construct(&b)) { if (args.cout==2) { p.construct(&c); }else { if (cpp2::cmp_greater(std::move(b),0)) { p.construct(&a); } else { p.construct(&d); } } }else { p.construct(&c); } std::cout << *cpp2::assert_not_null(std::move(p.value())) << std::endl; } ``` Assignements are properly marked as `DEFINITE INITIALIZATION` ``` 0 | function main 1 | scope 2 | var p *** UNINITIALIZED 2 | /var 2 | var a 2 | /var 2 | var b 2 | /var 2 | var c 2 | /var 2 | var d 2 | /var 2 | selection 3 | if branch 4 | *** (10,9) DEFINITE INITIALIZATION OF p 4 | *** use of a 4 | /if branch 3 | *** (11,15) DEFINITE INITIALIZATION OF p 3 | *** use of b 3 | if else branch 4 | selection 5 | if branch 6 | *** (13,13) DEFINITE INITIALIZATION OF p 6 | *** (13,17) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of c 6 | /if branch 5 | else branch 6 | selection 7 | *** (15,16) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of b 7 | if branch 8 | *** (16,17) DEFINITE INITIALIZATION OF p 8 | *** (16,21) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of a 8 | /if branch 7 | else branch 8 | *** (19,17) DEFINITE INITIALIZATION OF p 8 | *** (19,21) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of d 8 | /else branch 7 | /selection 6 | /else branch 5 | /selection 4 | /if else branch 3 | else branch 4 | *** (23,9) DEFINITE INITIALIZATION OF p 4 | *** (23,13) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of c 4 | /else branch 3 | /selection 2 | *** (26,18) DEFINITE LAST POTENTIALLY MOVING USE OF *** use of p 2 | /scope 1 | /function ```
1 parent fd862cd commit 853a1e9

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed

source/sema.h

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,7 @@ class sema
683683
branch(int s, bool r) : start{s}, result{r} { }
684684
};
685685
std::vector<branch> branches;
686+
bool in_branch = false;
686687

687688
stack_entry(int p) : pos{p} { }
688689

@@ -695,7 +696,6 @@ class sema
695696
}
696697
};
697698
std::vector<stack_entry> selection_stack;
698-
bool in_branch = false;
699699

700700
for (
701701
;
@@ -755,10 +755,10 @@ class sema
755755

756756
// Else if we're inside a selection statement but still in the condition
757757
// portion (there are no branches entered yet)
758-
else if (std::ssize(selection_stack.back().branches) == 0) {
758+
else if (!selection_stack.back().in_branch) {
759759
// If this is a top-level selection statement, handle it the same as
760760
// if we weren't an a selection statement
761-
if (std::ssize(selection_stack) == 1) {
761+
if (std::ssize(selection_stack) >= 1) {
762762
if (sym.assignment_to) {
763763
definite_initializations.push_back( sym.identifier );
764764
}
@@ -768,7 +768,6 @@ class sema
768768
"local variable " + name
769769
+ " is used in a condition before it was initialized");
770770
}
771-
return sym.assignment_to;
772771
}
773772
// Else we can skip the rest of this selection statement, and record
774773
// this as the result of the next outer selection statement's current branch
@@ -797,7 +796,7 @@ class sema
797796
+ " is used in a branch before it was initialized");
798797
}
799798

800-
if (!in_branch) {
799+
if (!selection_stack.back().in_branch) {
801800
return sym.assignment_to;
802801
}
803802

@@ -912,11 +911,11 @@ class sema
912911
)
913912
{
914913
selection_stack.back().branches.emplace_back( pos, false );
915-
in_branch = true;
914+
selection_stack.back().in_branch = true;
916915
}
917916

918917
if ( !sym.start ) {
919-
in_branch = false;
918+
selection_stack.back().in_branch = false;
920919
}
921920
}
922921
}

0 commit comments

Comments
 (0)