Skip to content

Commit b0b2d33

Browse files
committed
AST: add error handling
1 parent dbda8d8 commit b0b2d33

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

chb/arm/ARMOpcode.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,21 @@ def is_ok(self) -> bool:
119119
return self.xdata.is_ok
120120

121121
def var(self, index: int, name: str) -> "XVariable":
122+
if index >= len(self.xdata.vars_r):
123+
raise UF.CHBError(
124+
self.__class__.__name__ + ":"
125+
+ name + " index out of bounds: " + str(index))
122126
v = self.xdata.vars_r[index]
123127
if v is None:
124128
raise UF.CHBError(
125129
self.__class__.__name__ + ":" + name + " has an error value")
126130
return v
127131

128132
def xpr(self, index: int, name: str) -> "XXpr":
133+
if index >= len(self.xdata.xprs_r):
134+
raise UF.CHBError(
135+
self.__class__.__name__ + ":"
136+
+ name + " index out of bounds: " + str(index))
129137
x = self.xdata.xprs_r[index]
130138
if x is None:
131139
raise UF.CHBError(

chb/ast/ASTNode.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2767,6 +2767,9 @@ def is_compinfo(self) -> bool:
27672767
def has_field_offsets(self) -> bool:
27682768
return all(finfo.has_byteoffset() for finfo in self.fieldinfos)
27692769

2770+
def has_field_offset(self, offset: int) -> bool:
2771+
return offset in self.field_offsets
2772+
27702773
@property
27712774
def field_offsets(self) -> Dict[int, str]:
27722775
result: Dict[int, str] = {}

chb/invariants/XXprUtil.py

Lines changed: 43 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
# ------------------------------------------------------------------------------
55
# The MIT License (MIT)
66
#
7-
# Copyright (c) 2021-2024 Aarno Labs LLC
7+
# Copyright (c) 2021-2025 Aarno Labs LLC
88
#
99
# Permission is hereby granted, free of charge, to any person obtaining a copy
1010
# of this software and associated documentation files (the "Software"), to deal
@@ -485,6 +485,13 @@ def global_variable_to_lval_expression(
485485
globaladdress=gaddr,
486486
anonymous=anonymous)
487487

488+
if offset.offset.is_array_index_offset and vinfo is not None:
489+
arrayoffset = cast("VMemoryOffsetArrayIndexOffset", offset.offset)
490+
astoffset = array_offset_to_ast_offset(
491+
arrayoffset, xdata, iaddr, astree, anonymous=anonymous)
492+
return astree.mk_vinfo_lval_expression(
493+
vinfo, astoffset, anonymous=anonymous)
494+
488495
chklogger.logger.error(
489496
"Conversion of global variable %s at address %s not yet supported",
490497
str(offset), iaddr)
@@ -694,6 +701,19 @@ def vinitmemory_value_to_ast_lval_expression(
694701
return astree.mk_temp_lval_expression()
695702

696703
compinfo = astree.compinfo(compkey)
704+
if not compinfo.has_field_offsets():
705+
chklogger.logger.error(
706+
"No fields are specified for compinfo %s (at address %s)",
707+
compinfo.compname, iaddr)
708+
return astree.mk_temp_lval_expression()
709+
710+
if not compinfo.has_field_offset(coff):
711+
chklogger.logger.error(
712+
"Compinfo %s does not have a field at offset %d "
713+
+ "(at address %s)",
714+
compinfo.compname, coff, iaddr)
715+
return astree.mk_temp_lval_expression()
716+
697717
(field, restoffset) = compinfo.field_at_offset(coff)
698718
if restoffset > 0:
699719
chklogger.logger.error(
@@ -1049,7 +1069,7 @@ def default() -> AST.ASTExpr:
10491069
astxpr2 = xxpr_to_ast_def_expr(
10501070
xpr2, xdata, iaddr, astree, anonymous=anonymous)
10511071
if operator in [
1052-
"plus", "minus", "mult", "div",
1072+
"plus", "minus", "mult", "div", "mod",
10531073
"band", "land", "lor", "bor", "asr", "bxor",
10541074
"lsl", "lsr", "eq", "ne", "gt", "le", "lt", "ge"]:
10551075
return astree.mk_binary_expression(operator, astxpr1, astxpr2)
@@ -1363,17 +1383,21 @@ def array_offset_to_ast_offset(
13631383
if offset.has_no_offset():
13641384
return astree.mk_expr_index_offset(indexxpr)
13651385

1366-
def to_ast_offset(suboffset: "VMemoryOffset") -> AST.ASTOffset:
1367-
if suboffset.is_constant_value_offset:
1368-
return astree.mk_scalar_index_offset(suboffset.offsetconstant)
1369-
elif suboffset.is_field_offset:
1370-
suboffset = cast ("VMemoryOffsetFieldOffset", suboffset)
1371-
return astree.mk_field_offset(suboffset.fieldname, suboffset.ckey)
1372-
else:
1373-
return nooffset
1386+
if offset.offset.is_field_offset:
1387+
fsuboffset = cast("VMemoryOffsetFieldOffset", offset.offset)
1388+
astoffset: AST.ASTOffset = field_offset_to_ast_offset(
1389+
fsuboffset, xdata, iaddr, astree)
1390+
return astree.mk_expr_index_offset(indexxpr, offset=astoffset)
13741391

1375-
return astree.mk_expr_index_offset(
1376-
indexxpr, offset=to_ast_offset(offset.offset))
1392+
if offset.offset.is_array_index_offset:
1393+
asuboffset = cast("VMemoryOffsetArrayIndexOffset", offset.offset)
1394+
astoffset = array_offset_to_ast_offset(
1395+
asuboffset, xdata, iaddr, astree)
1396+
return astree.mk_expr_index_offset(indexxpr, offset=astoffset)
1397+
1398+
chklogger.logger.error(
1399+
"Offset %s not recognized at address %s", str(offset), iaddr)
1400+
return astree.mk_expr_index_offset(indexxpr)
13771401

13781402

13791403
def field_offset_to_ast_offset(
@@ -1402,7 +1426,6 @@ def field_offset_to_ast_offset(
14021426
offset.fieldname, offset.ckey, offset=suboffset)
14031427

14041428

1405-
14061429
def array_variable_to_ast_lval(
14071430
base: "MemoryAddress",
14081431
elementtyp: AST.ASTTyp,
@@ -1524,7 +1547,7 @@ def global_variable_to_ast_lval(
15241547
return astree.mk_vinfo_lval(vinfo, astoffset, anonymous=anonymous)
15251548

15261549
if offset.offset.is_field_offset and vinfo is not None:
1527-
fieldoffset = cast ("VMemoryOffsetFieldOffset", offset.offset)
1550+
fieldoffset = cast("VMemoryOffsetFieldOffset", offset.offset)
15281551
fieldname = fieldoffset.fieldname
15291552
compkey = fieldoffset.ckey
15301553
if fieldoffset.offset.is_no_offset:
@@ -1546,6 +1569,12 @@ def global_variable_to_ast_lval(
15461569
fieldname, compkey, offset=subfieldastoffset)
15471570
return astree.mk_vinfo_lval(vinfo, astoffset, anonymous=anonymous)
15481571

1572+
if offset.offset.is_array_index_offset and vinfo is not None:
1573+
aindexoffset = cast("VMemoryOffsetArrayIndexOffset", offset.offset)
1574+
astoffset = array_offset_to_ast_offset(
1575+
aindexoffset, xdata, iaddr, astree, anonymous=anonymous)
1576+
return astree.mk_vinfo_lval(vinfo, astoffset, anonymous=anonymous)
1577+
15491578
chklogger.logger.error(
15501579
("Conversion of global ast lval for address %s at address %s "
15511580
+ "not yet supported"),

0 commit comments

Comments
 (0)