From 4e2e78cfbb60765393f4a02f0369ee53793088d6 Mon Sep 17 00:00:00 2001 From: Akuli Date: Tue, 26 Dec 2023 18:53:01 +0200 Subject: [PATCH] Handle CF_BOOL_NEGATE in simplify_cfg (#489) --- src/simplify_cfg.c | 13 +++++++++++++ tests/other_errors/assert_fail.jou | 3 +-- tests/other_errors/assert_fail_multiline.jou | 3 +-- tests/should_succeed/and_or_not.jou | 10 ++++------ tests/should_succeed/unreachable_warning.jou | 5 +++++ 5 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/simplify_cfg.c b/src/simplify_cfg.c index ad22b55e..6d89e572 100644 --- a/src/simplify_cfg.c +++ b/src/simplify_cfg.c @@ -109,6 +109,19 @@ static void update_statuses_with_instruction(const CfGraph *cfg, enum VarStatus statuses[find_var_index(cfg, ins->operands[0])] = VS_UNPREDICTABLE; statuses[destidx] = VS_DEFINED; break; + case CF_BOOL_NEGATE: + switch(statuses[find_var_index(cfg, ins->operands[0])]) { + case VS_TRUE: + statuses[destidx] = VS_FALSE; + break; + case VS_FALSE: + statuses[destidx] = VS_TRUE; + break; + default: + statuses[destidx] = VS_DEFINED; + break; + } + break; case CF_CONSTANT: if (ins->data.constant.kind == CONSTANT_BOOL) statuses[destidx] = ins->data.constant.data.boolean ? VS_TRUE : VS_FALSE; diff --git a/tests/other_errors/assert_fail.jou b/tests/other_errors/assert_fail.jou index 4000c18e..fba096e3 100644 --- a/tests/other_errors/assert_fail.jou +++ b/tests/other_errors/assert_fail.jou @@ -4,5 +4,4 @@ def main() -> int: assert lol and wat assert lol and not wat # Output: Assertion 'lol and not wat' failed in file "tests/other_errors/assert_fail.jou", line 5. - # TODO: Compiler should be clever enough to not warn about missing return statement, but it isn't. - return 0 + # No need for a "return 0" because compiler knows we will never get here. diff --git a/tests/other_errors/assert_fail_multiline.jou b/tests/other_errors/assert_fail_multiline.jou index 89baddc8..56612d48 100644 --- a/tests/other_errors/assert_fail_multiline.jou +++ b/tests/other_errors/assert_fail_multiline.jou @@ -6,5 +6,4 @@ def main() -> int: and not wat ) - # TODO: Compiler should be clever enough to not warn about missing return statement, but it isn't. - return 0 + # No need for a "return 0" because compiler knows we will never get here. diff --git a/tests/should_succeed/and_or_not.jou b/tests/should_succeed/and_or_not.jou index f9672ec9..b3157b5e 100644 --- a/tests/should_succeed/and_or_not.jou +++ b/tests/should_succeed/and_or_not.jou @@ -59,12 +59,10 @@ def main() -> int: printf("%d", False or False or False) printf("\n") - # TODO: presumably these should emit warnings too - # Output: Precedence and 0001 printf("Precedence and ") - printf("%d", not True and not True) - printf("%d", not True and not False) + printf("%d", not True and not True) # Warning: this code will never run + printf("%d", not True and not False) # Warning: this code will never run printf("%d", not False and not True) printf("%d", not False and not False) printf("\n") @@ -73,8 +71,8 @@ def main() -> int: printf("Precedence or ") printf("%d", not True or not True) printf("%d", not True or not False) - printf("%d", not False or not True) - printf("%d", not False or not False) + printf("%d", not False or not True) # Warning: this code will never run + printf("%d", not False or not False) # Warning: this code will never run printf("\n") # Output: Side effects and aAbBcd diff --git a/tests/should_succeed/unreachable_warning.jou b/tests/should_succeed/unreachable_warning.jou index 116ac47d..f180a364 100644 --- a/tests/should_succeed/unreachable_warning.jou +++ b/tests/should_succeed/unreachable_warning.jou @@ -39,7 +39,12 @@ def lots_of_unreachable_code() -> None: puts("blah") i = i+1 +def with_not() -> None: + if not True: + puts("Hello") # Warning: this code will never run + def main() -> int: after_return() + with_not() # Can't run infinite loops (test script redirects output to file) return 0