Skip to content

Commit 0ace37b

Browse files
committed
INV: add more support for typecast value
1 parent b1ab225 commit 0ace37b

File tree

3 files changed

+55
-19
lines changed

3 files changed

+55
-19
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-20250203"
1+
chbversion: str = "0.3.0-20250204"

chb/arm/opcodes/ARMLoadRegister.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,18 @@ def ast_prov(
205205

206206
# high-level assignment
207207

208+
def has_cast() -> bool:
209+
return (
210+
astree.has_register_variable_intro(iaddr)
211+
and astree.get_register_variable_intro(iaddr).has_cast())
212+
208213
lhs = xd.vrt
209214

210215
if xd.is_ok:
211216
rhs = xd.xrmem
217+
rhsval = None if has_cast() else xd.xrmem
212218
xaddr = xd.xaddr
213-
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree, rhs=rhs)
219+
hl_lhs = XU.xvariable_to_ast_lval(lhs, xdata, iaddr, astree, rhs=rhsval)
214220
hl_rhs = XU.xxpr_to_ast_def_expr(
215221
rhs, xdata, iaddr, astree, memaddr=xaddr)
216222

@@ -230,11 +236,6 @@ def ast_prov(
230236
defuses = xdata.defuses
231237
defuseshigh = xdata.defuseshigh
232238

233-
def has_cast() -> bool:
234-
return (
235-
astree.has_register_variable_intro(iaddr)
236-
and astree.get_register_variable_intro(iaddr).has_cast())
237-
238239
if has_cast():
239240
lhstype = hl_lhs.ctype(astree.ctyper)
240241
if lhstype is not None:

chb/invariants/XXprUtil.py

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,34 @@ def memory_variable_to_lval_expression(
374374
size: int = 4,
375375
anonymous: bool = False) -> AST.ASTExpr:
376376

377+
if base.is_basevar:
378+
base = cast("VMemoryBaseBaseVar", base)
379+
if base.basevar.is_typecast_value:
380+
tcval = cast("VTypeCastValue", base.basevar.denotation.auxvar)
381+
asttgttype = tcval.tgttype.convert(astree.typconverter)
382+
vinfo = astree.mk_vinfo(tcval.name, vtype=asttgttype)
383+
astbase = astree.mk_vinfo_lval_expression(vinfo)
384+
if offset.is_field_offset:
385+
offset = cast("VMemoryOffsetFieldOffset", offset)
386+
astoffset: AST.ASTOffset = field_offset_to_ast_offset(
387+
offset, xdata, iaddr, astree)
388+
elif offset.is_array_index_offset:
389+
offset = cast("VMemoryOffsetArrayIndexOffset", offset)
390+
astoffset = array_offset_to_ast_offset(offset, xdata, iaddr, astree)
391+
elif offset.is_constant_value_offset:
392+
astoffset = astree.mk_scalar_index_offset(offset.offsetvalue())
393+
else:
394+
astoffset = nooffset
395+
return astree.mk_memref_expr(
396+
astbase, offset=astoffset, anonymous=anonymous)
397+
398+
else:
399+
chklogger.logger.error(
400+
"AST conversion of non-typecast basevar %s at address %s "
401+
+ "not yet supported",
402+
str(base), iaddr)
403+
return astree.mk_temp_lval_expression()
404+
377405
name = str(base)
378406

379407
if not astree.globalsymboltable.has_symbol(name):
@@ -690,6 +718,9 @@ def vinitmemory_value_to_ast_lval_expression(
690718

691719
if astbasetype.is_pointer:
692720
tgttype = cast(AST.ASTTypPtr, astbasetype).tgttyp
721+
if tgttype.is_scalar:
722+
return astree.mk_memref_expr(astbase, anonymous=anonymous)
723+
693724
if tgttype.is_compound:
694725

695726
compkey = cast(AST.ASTTypComp, tgttype).compkey
@@ -1050,12 +1081,13 @@ def default() -> AST.ASTExpr:
10501081
return default()
10511082
subfoffset = astree.mk_field_offset(subfield.fieldname, fcompkey)
10521083
else:
1053-
chklogger.logger.error(
1054-
"Non-struct type %s for field %s in second-level rest "
1055-
+ "offset not yet "
1056-
+ "handled for %s with offset %s at %s: %d",
1057-
str(field.fieldtype), field.fieldname,
1058-
str(axpr1), str(axpr2), iaddr, restoffset)
1084+
if not anonymous:
1085+
chklogger.logger.error(
1086+
"Non-struct type %s for field %s in second-level rest "
1087+
+ "offset not yet "
1088+
+ "handled for %s with offset %s at %s: %d",
1089+
str(field.fieldtype), field.fieldname,
1090+
str(axpr1), str(axpr2), iaddr, restoffset)
10591091
return default()
10601092
else:
10611093
subfoffset = nooffset
@@ -1125,8 +1157,9 @@ def default() -> AST.ASTExpr:
11251157

11261158
if xpr1.is_compound and xpr2.is_constant:
11271159
xc = cast(X.XprCompound, xpr1)
1128-
astxpr1 = xcompound_to_ast_def_expr(xc, xdata, iaddr, astree)
1129-
astxpr2 = xxpr_to_ast_expr(xpr2, xdata, iaddr, astree)
1160+
astxpr1 = xcompound_to_ast_def_expr(
1161+
xc, xdata, iaddr, astree, anonymous=anonymous)
1162+
astxpr2 = xxpr_to_ast_expr(xpr2, xdata, iaddr, astree, anonymous=anonymous)
11301163
if operator in ["plus", "minus"]:
11311164
return astree.mk_binary_expression(operator, astxpr1, astxpr2)
11321165
else:
@@ -1656,6 +1689,7 @@ def xvariable_to_ast_lval(
16561689
rhs, xdata, iaddr, astree)
16571690
else:
16581691
astrhs = None
1692+
16591693
return astree.mk_ssa_register_variable_lval(
16601694
str(xv), iaddr, vtype=ctype, ssavalue=astrhs)
16611695

@@ -1795,10 +1829,11 @@ def vargument_deref_value_to_ast_lval(
17951829
return astree.mk_memref_lval(vexpr, anonymous=anonymous)
17961830

17971831
if not offset.is_constant_value_offset:
1798-
chklogger.logger.error(
1799-
"Non-constant offset: %s with variable %s not yet supported at "
1800-
+ "address %s",
1801-
str(offset), str(basevar), iaddr)
1832+
if not anonymous:
1833+
chklogger.logger.error(
1834+
"Non-constant offset: %s with variable %s not yet supported at "
1835+
+ "address %s",
1836+
str(offset), str(basevar), iaddr)
18021837
return astree.mk_temp_lval()
18031838

18041839
coff = offset.offsetvalue()

0 commit comments

Comments
 (0)