Skip to content

Commit b31ce1b

Browse files
committed
ASTI: fix address-of array-element-zero
1 parent cf75904 commit b31ce1b

File tree

3 files changed

+62
-3
lines changed

3 files changed

+62
-3
lines changed

chb/app/CHVersion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
chbversion: str = "0.3.0-20241014"
1+
chbversion: str = "0.3.0-20241028"

chb/ast/ASTNode.py

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1112,7 +1112,7 @@ def ctype(self, ctyper: "ASTCTyper") -> Optional["ASTTyp"]:
11121112

11131113
def __str__(self) -> str:
11141114
vol = " volatile" if self.volatile else ""
1115-
return "asm{}({}, {})".format(vol, self.template, self.clobbers)
1115+
return "asm{}({}, {})".format(vol, self.template, self.clobbers)
11161116

11171117

11181118
class ASTLval(ASTNode):
@@ -1396,6 +1396,10 @@ def is_no_offset(self) -> bool:
13961396
def offset(self) -> "ASTOffset":
13971397
raise Exception("offset property not supported for " + str(self))
13981398

1399+
@property
1400+
def tail_offset(self) -> "ASTOffset":
1401+
raise Exception("tail offset property not supported for " + str(self))
1402+
13991403
@abstractmethod
14001404
def transform(self, transformer: "ASTTransformer") -> "ASTOffset":
14011405
...
@@ -1419,6 +1423,10 @@ def __init__(self) -> None:
14191423
def is_no_offset(self) -> bool:
14201424
return True
14211425

1426+
@property
1427+
def tail_offset(self) -> "ASTOffset":
1428+
return self
1429+
14221430
def accept(self, visitor: "ASTVisitor") -> None:
14231431
visitor.visit_no_offset(self)
14241432

@@ -1472,6 +1480,13 @@ def compkey(self) -> int:
14721480
def offset(self) -> "ASTOffset":
14731481
return self._byteoffset
14741482

1483+
@property
1484+
def tail_offset(self) -> "ASTOffset":
1485+
if self.offset.is_no_offset:
1486+
return self
1487+
else:
1488+
return self._byteoffset.tail_offset
1489+
14751490
def accept(self, visitor: "ASTVisitor") -> None:
14761491
visitor.visit_field_offset(self)
14771492

@@ -1516,6 +1531,13 @@ def index_expr(self) -> "ASTExpr":
15161531
def offset(self) -> "ASTOffset":
15171532
return self._offset
15181533

1534+
@property
1535+
def tail_offset(self) -> "ASTOffset":
1536+
if self.offset.is_no_offset:
1537+
return self
1538+
else:
1539+
return self.offset.tail_offset
1540+
15191541
def accept(self, visitor: "ASTVisitor") -> None:
15201542
visitor.visit_index_offset(self)
15211543

@@ -1593,6 +1615,10 @@ def is_ast_constant(self) -> bool:
15931615
def is_integer_constant(self) -> bool:
15941616
return False
15951617

1618+
@property
1619+
def is_integer_constant_zero(self) -> bool:
1620+
return False
1621+
15961622
@property
15971623
def is_global_address(self) -> bool:
15981624
return False
@@ -1686,6 +1712,10 @@ def __init__(
16861712
def is_integer_constant(self) -> bool:
16871713
return True
16881714

1715+
@property
1716+
def is_integer_constant_zero(self) -> bool:
1717+
return self.cvalue == 0
1718+
16891719
@property
16901720
def cvalue(self) -> int:
16911721
return self._cvalue

chb/astinterface/ASTInterface.py

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1377,10 +1377,39 @@ def mk_string_constant(
13771377
return self.astree.mk_string_constant(expr, cstr, saddr)
13781378

13791379
def mk_address_of(
1380-
self, lval: AST.ASTLval, anonymous: bool = False) -> AST.ASTAddressOf:
1380+
self, lval: AST.ASTLval, anonymous: bool = False) -> AST.ASTExpr:
13811381
optexprid = -1 if anonymous else None
1382+
if lval.offset.tail_offset.is_index_offset:
1383+
indexexpr = cast(
1384+
AST.ASTIndexOffset, lval.offset.tail_offset).index_expr
1385+
if indexexpr.is_integer_constant_zero:
1386+
return self.mk_index_parent_start_of(lval)
1387+
13821388
return self.astree.mk_address_of_expression(lval, optexprid=optexprid)
13831389

1390+
def mk_index_parent_start_of(self, lval: AST.ASTLval) -> AST.ASTStartOf:
1391+
1392+
def replace_tail(offset: AST.ASTOffset) -> AST.ASTOffset:
1393+
if offset.is_no_offset:
1394+
chklogger.logger.error("Inconsistent offset")
1395+
return offset
1396+
elif offset.is_field_offset:
1397+
offset = cast(AST.ASTFieldOffset, offset)
1398+
suboffset = replace_tail(offset.offset)
1399+
return self.mk_field_offset(
1400+
offset.fieldname, offset.compkey, offset = suboffset)
1401+
else:
1402+
if offset.offset.is_no_offset:
1403+
return offset.offset
1404+
else:
1405+
offset = cast(AST.ASTIndexOffset, offset)
1406+
suboffset = replace_tail(offset.offset)
1407+
return self.mk_expr_index_offset(
1408+
offset.index_expr, offset=suboffset)
1409+
1410+
lval = self.mk_lval(lval.lhost, replace_tail(lval.offset))
1411+
return self.mk_start_of(lval)
1412+
13841413
def mk_start_of(self, lval: AST.ASTLval) -> AST.ASTStartOf:
13851414
return self.astree.mk_start_of_expression(lval, optexprid=None)
13861415

0 commit comments

Comments
 (0)