Skip to content

Commit 5084897

Browse files
authored
Raise error for calls with mis-matching types (#1261)
1 parent 36a5e3b commit 5084897

8 files changed

+104
-2
lines changed

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -813,13 +813,28 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
813813

814814
void visit_expr_list_with_cast(ASR::expr_t** m_args, size_t n_args,
815815
Vec<ASR::call_arg_t>& call_args_vec,
816-
Vec<ASR::call_arg_t>& args) {
816+
Vec<ASR::call_arg_t>& args,
817+
bool check_type_equality=true) {
817818
LFORTRAN_ASSERT(call_args_vec.reserve_called);
818819
for (size_t i = 0; i < n_args; i++) {
819820
ASR::call_arg_t c_arg;
820821
c_arg.loc = args[i].loc;
821822
c_arg.m_value = args[i].m_value;
822823
cast_helper(m_args[i], c_arg.m_value, true);
824+
ASR::ttype_t* left_type = ASRUtils::expr_type(m_args[i]);
825+
ASR::ttype_t* right_type = ASRUtils::expr_type(c_arg.m_value);
826+
if( check_type_equality && !ASRUtils::check_equal_type(left_type, right_type) ) {
827+
std::string ltype = ASRUtils::type_to_str_python(left_type);
828+
std::string rtype = ASRUtils::type_to_str_python(right_type);
829+
diag.add(diag::Diagnostic(
830+
"Type mismatch in procedure call; the types must be compatible",
831+
diag::Level::Error, diag::Stage::Semantic, {
832+
diag::Label("type mismatch (passed argument type is " + rtype + " but required type is " + ltype + ")",
833+
{ c_arg.loc, left_type->base.loc})
834+
})
835+
);
836+
throw SemanticAbort();
837+
}
823838
call_args_vec.push_back(al, c_arg);
824839
}
825840
}
@@ -1047,7 +1062,8 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
10471062

10481063
Vec<ASR::call_arg_t> args_new;
10491064
args_new.reserve(al, func->n_args);
1050-
visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args);
1065+
visit_expr_list_with_cast(func->m_args, func->n_args, args_new, args,
1066+
!ASRUtils::is_intrinsic_function2(func));
10511067
dependencies.insert(std::string(ASRUtils::symbol_name(stemp)));
10521068
ASR::asr_t* func_call_asr = ASR::make_FunctionCall_t(al, loc, stemp,
10531069
s_generic, args_new.p, args_new.size(),
@@ -1085,6 +1101,20 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
10851101
StructType->m_symtab->resolve_symbol(member_name));
10861102
ASR::expr_t* arg_new_i = args_new[i];
10871103
cast_helper(member_var->m_type, arg_new_i);
1104+
ASR::ttype_t* left_type = member_var->m_type;
1105+
ASR::ttype_t* right_type = ASRUtils::expr_type(arg_new_i);
1106+
if( !ASRUtils::check_equal_type(left_type, right_type) ) {
1107+
std::string ltype = ASRUtils::type_to_str_python(left_type);
1108+
std::string rtype = ASRUtils::type_to_str_python(right_type);
1109+
diag.add(diag::Diagnostic(
1110+
"Type mismatch in procedure call; the types must be compatible",
1111+
diag::Level::Error, diag::Stage::Semantic, {
1112+
diag::Label("type mismatch (passed argument type is " + rtype + " but required type is " + ltype + ")",
1113+
{ arg_new_i->base.loc, left_type->base.loc})
1114+
})
1115+
);
1116+
throw SemanticAbort();
1117+
}
10881118
args_new.p[i] = arg_new_i;
10891119
}
10901120
ASR::ttype_t* der_type = ASRUtils::TYPE(ASR::make_Struct_t(al, loc, s, nullptr, 0));

tests/errors/bindc_01.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from ltypes import i32, CPtr, ccall
2+
3+
@ccall
4+
def cptr_arg(arg1: CPtr):
5+
pass
6+
7+
def test_call_cptr():
8+
int32obj: i32
9+
cptr_arg(int32obj)
10+
11+
test_call_cptr()

tests/errors/bindc_02.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from ltypes import i32, CPtr, ccall, dataclass
2+
3+
@dataclass
4+
class Struct:
5+
cptr_member: CPtr
6+
7+
def test_call_cptr():
8+
int32obj: i32
9+
s: Struct = Struct(int32obj)
10+
11+
test_call_cptr()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-bindc_01-f761165",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/bindc_01.py",
5+
"infile_hash": "e35ebc641a551a6575b45284fbb377c27bfe3fe97a4395175c209354",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-bindc_01-f761165.stderr",
11+
"stderr_hash": "b2d416fa6afa00923a130cb76dbd580798a9ee0841e34980c531b050",
12+
"returncode": 2
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
semantic error: Type mismatch in procedure call; the types must be compatible
2+
--> tests/errors/bindc_01.py:9:14
3+
|
4+
9 | cptr_arg(int32obj)
5+
| ^^^^^^^^ type mismatch (passed argument type is i32 but required type is CPtr)
6+
|
7+
4 | def cptr_arg(arg1: CPtr):
8+
| ^^^^ type mismatch (passed argument type is i32 but required type is CPtr)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-bindc_02-5092d8e",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/bindc_02.py",
5+
"infile_hash": "4ab9dc03aed5933cc9311b55995467d6c2deb8502fad441f6f73b4fa",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-bindc_02-5092d8e.stderr",
11+
"stderr_hash": "315076027d80c91db75f4ec44ea5cf8d5fd37a499a367f627b6f6553",
12+
"returncode": 2
13+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
semantic error: Type mismatch in procedure call; the types must be compatible
2+
--> tests/errors/bindc_02.py:9:24
3+
|
4+
9 | s: Struct = Struct(int32obj)
5+
| ^^^^^^^^ type mismatch (passed argument type is i32 but required type is CPtr)
6+
|
7+
5 | cptr_member: CPtr
8+
| ^^^^ type mismatch (passed argument type is i32 but required type is CPtr)

tests/tests.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,14 @@ asr = true
935935
filename = "errors/test_goto.py"
936936
asr = true
937937

938+
[[test]]
939+
filename = "errors/bindc_01.py"
940+
asr = true
941+
942+
[[test]]
943+
filename = "errors/bindc_02.py"
944+
asr = true
945+
938946
# tests/runtime_errors
939947
[[test]]
940948
filename = "runtime_errors/test_list_01.py"

0 commit comments

Comments
 (0)