Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/fpy/semantics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1741,10 +1741,11 @@ def pick_intermediate_type(
if op in BOOLEAN_OPERATORS:
return BOOL

# for == and !=, non-numeric same-type comparisons are valid
# for == and !=, non-numeric same-type comparisons are valid, as long
# as the operands have a value at all
if op in (BinaryStackOp.EQUAL, BinaryStackOp.NOT_EQUAL):
if len(arg_types) == 2 and arg_types[0] == arg_types[1]:
if not arg_types[0].is_numerical:
if not arg_types[0].is_numerical and arg_types[0] != NOTHING:
# non-numeric equality (struct, array, enum, time)
return arg_types[0]

Expand Down
24 changes: 24 additions & 0 deletions test/fpy/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,30 @@ def noop():
"""
assert_compile_failure(fprime_test_api, seq)

def test_compare_void_function_results_equal(self, fprime_test_api):
"""A void call has no value, so it cannot be an operand of ==."""
seq = """
def f():
pass

b: bool = f() == f()
"""
assert_compile_failure(fprime_test_api, seq, match="undefined for Nothing")

def test_compare_void_function_results_not_equal(self, fprime_test_api):
"""A void call has no value, so it cannot be an operand of !=."""
seq = """
def f():
pass

def g():
pass

if f() != g():
exit(1)
"""
assert_compile_failure(fprime_test_api, seq, match="undefined for Nothing")

def test_call_embedded_in_bare_expression(self, fprime_test_api):
"""A bare expression statement whose top-level node isn't itself
side-effecting (an == comparison) still embeds a call that is; the
Expand Down
Loading