Skip to content

Commit dee5200

Browse files
authored
Merge pull request #2078 from Shaikh-Ubaid/throw_err_for_unsupp_operand
Throw error for unsupported unary operand
2 parents ba76069 + 5dfcf28 commit dee5200

File tree

5 files changed

+62
-40
lines changed

5 files changed

+62
-40
lines changed

src/lpython/semantics/python_ast_to_asr.cpp

Lines changed: 29 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3404,7 +3404,6 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34043404
ASR::expr_t *value = nullptr;
34053405

34063406
if (x.m_op == AST::unaryopType::Invert) {
3407-
34083407
if (ASRUtils::is_integer(*operand_type)) {
34093408
if (ASRUtils::expr_value(operand) != nullptr) {
34103409
int64_t op_value = ASR::down_cast<ASR::IntegerConstant_t>(
@@ -3414,8 +3413,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34143413
}
34153414
tmp = ASR::make_IntegerBitNot_t(al, x.base.base.loc, operand, dest_type, value);
34163415
return;
3417-
}
3418-
else if (ASRUtils::is_unsigned_integer(*operand_type)) {
3416+
} else if (ASRUtils::is_unsigned_integer(*operand_type)) {
34193417
if (ASRUtils::expr_value(operand) != nullptr) {
34203418
int64_t op_value = ASR::down_cast<ASR::UnsignedIntegerConstant_t>(
34213419
ASRUtils::expr_value(operand))->m_n;
@@ -3425,12 +3423,10 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34253423
}
34263424
tmp = ASR::make_UnsignedIntegerBitNot_t(al, x.base.base.loc, operand, dest_type, value);
34273425
return;
3428-
}
3429-
else if (ASRUtils::is_real(*operand_type)) {
3426+
} else if (ASRUtils::is_real(*operand_type)) {
34303427
throw SemanticError("Unary operator '~' not supported for floats",
34313428
x.base.base.loc);
3432-
}
3433-
else if (ASRUtils::is_logical(*operand_type)) {
3429+
} else if (ASRUtils::is_logical(*operand_type)) {
34343430
if (ASRUtils::expr_value(operand) != nullptr) {
34353431
bool op_value = ASR::down_cast<ASR::LogicalConstant_t>(
34363432
ASRUtils::expr_value(operand))->m_value;
@@ -3444,15 +3440,14 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34443440
int_type, value));
34453441
tmp = ASR::make_IntegerBitNot_t(al, x.base.base.loc, int_arg, int_type, value);
34463442
return;
3447-
}
3448-
else if (ASRUtils::is_complex(*operand_type)) {
3443+
} else if (ASRUtils::is_complex(*operand_type)) {
34493444
throw SemanticError("Unary operator '~' not supported for complex type",
34503445
x.base.base.loc);
3446+
} else {
3447+
throw SemanticError("Unary operator '~' not supported for type " + ASRUtils::type_to_str_python(operand_type),
3448+
x.base.base.loc);
34513449
}
3452-
3453-
}
3454-
else if (x.m_op == AST::unaryopType::Not) {
3455-
3450+
} else if (x.m_op == AST::unaryopType::Not) {
34563451
ASR::expr_t *logical_arg = operand;
34573452
if (ASRUtils::is_integer(*operand_type)) {
34583453
if (ASRUtils::expr_value(operand) != nullptr) {
@@ -3466,8 +3461,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34663461
logical_arg = ASR::down_cast<ASR::expr_t>(ASR::make_Cast_t(
34673462
al, x.base.base.loc, operand, ASR::cast_kindType::IntegerToLogical,
34683463
logical_type, value));
3469-
}
3470-
else if (ASRUtils::is_real(*operand_type)) {
3464+
} else if (ASRUtils::is_real(*operand_type)) {
34713465
if (ASRUtils::expr_value(operand) != nullptr) {
34723466
double op_value = ASR::down_cast<ASR::RealConstant_t>(
34733467
ASRUtils::expr_value(operand))->m_r;
@@ -3479,16 +3473,14 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
34793473
logical_arg = ASR::down_cast<ASR::expr_t>(ASR::make_Cast_t(
34803474
al, x.base.base.loc, operand, ASR::cast_kindType::RealToLogical,
34813475
logical_type, value));
3482-
}
3483-
else if (ASRUtils::is_logical(*operand_type)) {
3476+
} else if (ASRUtils::is_logical(*operand_type)) {
34843477
if (ASRUtils::expr_value(operand) != nullptr) {
34853478
bool op_value = ASR::down_cast<ASR::LogicalConstant_t>(
34863479
ASRUtils::expr_value(operand))->m_value;
34873480
value = ASR::down_cast<ASR::expr_t>(ASR::make_LogicalConstant_t(
34883481
al, x.base.base.loc, !op_value, logical_type));
34893482
}
3490-
}
3491-
else if (ASRUtils::is_complex(*operand_type)) {
3483+
} else if (ASRUtils::is_complex(*operand_type)) {
34923484
if (ASRUtils::expr_value(operand) != nullptr) {
34933485
if( ASR::is_a<ASR::FunctionCall_t>(*operand) ) {
34943486
ASR::FunctionCall_t* operand_func_call = ASR::down_cast<ASR::FunctionCall_t>(operand);
@@ -3505,29 +3497,27 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35053497
logical_arg = ASR::down_cast<ASR::expr_t>(ASR::make_Cast_t(
35063498
al, x.base.base.loc, operand, ASR::cast_kindType::ComplexToLogical,
35073499
logical_type, value));
3500+
} else {
3501+
throw SemanticError("Unary operator '!' not supported for type " + ASRUtils::type_to_str_python(operand_type),
3502+
x.base.base.loc);
35083503
}
35093504

35103505
tmp = ASR::make_LogicalNot_t(al, x.base.base.loc, logical_arg, logical_type, value);
35113506
return;
3512-
3513-
}
3514-
else if (x.m_op == AST::unaryopType::UAdd) {
3515-
3507+
} else if (x.m_op == AST::unaryopType::UAdd) {
35163508
if (ASRUtils::is_integer(*operand_type)) {
35173509
if (ASRUtils::expr_value(operand) != nullptr) {
35183510
int64_t op_value = ASR::down_cast<ASR::IntegerConstant_t>(
35193511
ASRUtils::expr_value(operand))->m_n;
35203512
tmp = ASR::make_IntegerConstant_t(al, x.base.base.loc, op_value, operand_type);
35213513
}
3522-
}
3523-
else if (ASRUtils::is_real(*operand_type)) {
3514+
} else if (ASRUtils::is_real(*operand_type)) {
35243515
if (ASRUtils::expr_value(operand) != nullptr) {
35253516
double op_value = ASR::down_cast<ASR::RealConstant_t>(
35263517
ASRUtils::expr_value(operand))->m_r;
35273518
tmp = ASR::make_RealConstant_t(al, x.base.base.loc, op_value, operand_type);
35283519
}
3529-
}
3530-
else if (ASRUtils::is_logical(*operand_type)) {
3520+
} else if (ASRUtils::is_logical(*operand_type)) {
35313521
if (ASRUtils::expr_value(operand) != nullptr) {
35323522
bool op_value = ASR::down_cast<ASR::LogicalConstant_t>(
35333523
ASRUtils::expr_value(operand))->m_value;
@@ -3536,8 +3526,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35363526
}
35373527
tmp = ASR::make_Cast_t(al, x.base.base.loc, operand, ASR::cast_kindType::LogicalToInteger,
35383528
int_type, value);
3539-
}
3540-
else if (ASRUtils::is_complex(*operand_type)) {
3529+
} else if (ASRUtils::is_complex(*operand_type)) {
35413530
if (ASRUtils::expr_value(operand) != nullptr) {
35423531
if( ASR::is_a<ASR::FunctionCall_t>(*operand) ) {
35433532
ASR::FunctionCall_t* operand_func_call = ASR::down_cast<ASR::FunctionCall_t>(operand);
@@ -3549,12 +3538,12 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35493538
tmp = ASR::make_ComplexConstant_t(al, x.base.base.loc,
35503539
std::real(op_value), std::imag(op_value), operand_type);
35513540
}
3541+
} else {
3542+
throw SemanticError("Unary operator '+' not supported for type " + ASRUtils::type_to_str_python(operand_type),
3543+
x.base.base.loc);
35523544
}
35533545
return;
3554-
3555-
}
3556-
else if (x.m_op == AST::unaryopType::USub) {
3557-
3546+
} else if (x.m_op == AST::unaryopType::USub) {
35583547
if (ASRUtils::is_integer(*operand_type)) {
35593548
if (ASRUtils::expr_value(operand) != nullptr) {
35603549
int64_t op_value = ASR::down_cast<ASR::IntegerConstant_t>(
@@ -3565,8 +3554,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35653554
tmp = ASR::make_IntegerUnaryMinus_t(al, x.base.base.loc, operand,
35663555
operand_type, value);
35673556
return;
3568-
}
3569-
else if (ASRUtils::is_real(*operand_type)) {
3557+
} else if (ASRUtils::is_real(*operand_type)) {
35703558
if (ASRUtils::expr_value(operand) != nullptr) {
35713559
double op_value = ASR::down_cast<ASR::RealConstant_t>(
35723560
ASRUtils::expr_value(operand))->m_r;
@@ -3576,8 +3564,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35763564
tmp = ASR::make_RealUnaryMinus_t(al, x.base.base.loc, operand,
35773565
operand_type, value);
35783566
return;
3579-
}
3580-
else if (ASRUtils::is_logical(*operand_type)) {
3567+
} else if (ASRUtils::is_logical(*operand_type)) {
35813568
if (ASRUtils::expr_value(operand) != nullptr) {
35823569
bool op_value = ASR::down_cast<ASR::LogicalConstant_t>(
35833570
ASRUtils::expr_value(operand))->m_value;
@@ -3591,8 +3578,7 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
35913578
tmp = ASR::make_IntegerUnaryMinus_t(al, x.base.base.loc, int_arg,
35923579
int_type, value);
35933580
return;
3594-
}
3595-
else if (ASRUtils::is_complex(*operand_type)) {
3581+
} else if (ASRUtils::is_complex(*operand_type)) {
35963582
if (ASRUtils::expr_value(operand) != nullptr) {
35973583
ASR::ComplexConstant_t *c = ASR::down_cast<ASR::ComplexConstant_t>(
35983584
ASRUtils::expr_value(operand));
@@ -3606,6 +3592,9 @@ class CommonVisitor : public AST::BaseVisitor<Struct> {
36063592
tmp = ASR::make_ComplexUnaryMinus_t(al, x.base.base.loc, operand,
36073593
operand_type, value);
36083594
return;
3595+
} else {
3596+
throw SemanticError("Unary operator '-' not supported for type " + ASRUtils::type_to_str_python(operand_type),
3597+
x.base.base.loc);
36093598
}
36103599
}
36113600
}
@@ -4765,7 +4754,7 @@ class BodyVisitor : public CommonVisitor<BodyVisitor> {
47654754
if (t == nullptr) {
47664755
// Throw Not implemented error.
47674756
throw SemanticError("Internal FunctionDef: Not implemented", x.base.base.loc);
4768-
}
4757+
}
47694758

47704759
if (ASR::is_a<ASR::Function_t>(*t)) {
47714760
ASR::Function_t *f = ASR::down_cast<ASR::Function_t>(t);

tests/errors/test_operator_01.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from lpython import i32, dataclass
2+
3+
@dataclass
4+
class A:
5+
n: i32
6+
7+
def main0():
8+
a: A = A(10)
9+
print(-a)
10+
11+
main0()
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"basename": "asr-test_operator_01-0f232bf",
3+
"cmd": "lpython --show-asr --no-color {infile} -o {outfile}",
4+
"infile": "tests/errors/test_operator_01.py",
5+
"infile_hash": "fe3fc1c23c2f63265b758b4d5d757943c1462811c5bc5e7a14abb64d",
6+
"outfile": null,
7+
"outfile_hash": null,
8+
"stdout": null,
9+
"stdout_hash": null,
10+
"stderr": "asr-test_operator_01-0f232bf.stderr",
11+
"stderr_hash": "d291f8cc0413a1d9a1f4450493d17790ceec00cad791cdc4d1283161",
12+
"returncode": 2
13+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
semantic error: Unary operator '-' not supported for type A
2+
--> tests/errors/test_operator_01.py:9:11
3+
|
4+
9 | print(-a)
5+
| ^^

tests/tests.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,10 @@ asr = true
845845
filename = "errors/test_pow4.py"
846846
asr = true
847847

848+
[[test]]
849+
filename = "errors/test_operator_01.py"
850+
asr = true
851+
848852
[[test]]
849853
filename = "errors/test_ord.py"
850854
asr = true

0 commit comments

Comments
 (0)