@@ -1222,7 +1222,7 @@ def mkIfExpr(site, cond, texpr, fexpr):
12221222 (texpr , fexpr , utype ) = usual_int_conv (
12231223 texpr , ttype , fexpr , ftype )
12241224 else :
1225- if not compatible_types (ttype , ftype ):
1225+ if not compatible_types_fuzzy (ttype , ftype ):
12261226 raise EBINOP (site , ':' , texpr , fexpr )
12271227 # TODO: in C, the rules are more complex,
12281228 # but our type system is too primitive to cover that
@@ -1396,7 +1396,7 @@ def make(cls, site, lh, rh):
13961396 if ((lhtype .is_arith and rhtype .is_arith )
13971397 or (isinstance (lhtype , (TPtr , TArray ))
13981398 and isinstance (rhtype , (TPtr , TArray ))
1399- and compatible_types (lhtype .base , rhtype .base ))):
1399+ and compatible_types_fuzzy (lhtype .base , rhtype .base ))):
14001400 return cls .make_simple (site , lh , rh )
14011401 raise EILLCOMP (site , lh , lhtype , rh , rhtype )
14021402
@@ -1601,7 +1601,7 @@ def make(cls, site, lh, rh):
16011601 if ((lhtype .is_arith and rhtype .is_arith )
16021602 or (isinstance (lhtype , (TPtr , TArray ))
16031603 and isinstance (rhtype , (TPtr , TArray ))
1604- and compatible_types (lhtype , rhtype ))
1604+ and compatible_types_fuzzy (lhtype , rhtype ))
16051605 or (isinstance (lhtype , TBool ) and isinstance (rhtype , TBool ))):
16061606 return Equals (site , lh , rh )
16071607
@@ -2932,8 +2932,8 @@ def mkInterfaceMethodRef(site, iface_node, indices, method_name):
29322932 if (not isinstance (ftype , TPtr )
29332933 or not isinstance (ftype .base , TFunction )
29342934 or not ftype .base .input_types
2935- or TPtr (safe_realtype (TNamed ('conf_object_t' ))).cmp (
2936- safe_realtype (ftype .base .input_types [0 ])) != 0 ):
2935+ or TPtr (safe_realtype_unconst (TNamed ('conf_object_t' ))).cmp (
2936+ safe_realtype_unconst (ftype .base .input_types [0 ])) != 0 ):
29372937 # non-method members are not accessible
29382938 raise EMEMBER (site , struct_name , method_name )
29392939
@@ -4674,7 +4674,10 @@ class ArrayRef(LValue):
46744674 explicit_type = True
46754675 @auto_init
46764676 def __init__ (self , site , expr , idx ):
4677- self .type = realtype_shallow (expr .ctype ()).base
4677+ expr_type = realtype_shallow (expr .ctype ())
4678+ self .type = conv_const (expr_type .const
4679+ and isinstance (expr_type , TArray ),
4680+ expr_type .base )
46784681 def __str__ (self ):
46794682 return '%s[%s]' % (self .expr , self .idx )
46804683 def read (self ):
@@ -4787,30 +4790,41 @@ def mkCast(site, expr, new_type):
47874790 raise ETEMPLATEUPCAST (site , "object" , new_type )
47884791 else :
47894792 return mkTraitUpcast (site , expr , real .trait )
4793+
4794+ if (compat .dml12_misc in dml .globals .enabled_compat
4795+ and isinstance (expr , InterfaceMethodRef )):
4796+ # Workaround for SIMICS-9868
4797+ return mkLit (site , "%s->%s" % (
4798+ expr .node_expr .read (), expr .method_name ), new_type )
4799+
4800+ if isinstance (expr , NonValue ):
4801+ raise expr .exc ()
47904802 old_type = safe_realtype (expr .ctype ())
47914803 if (dml .globals .compat_dml12_int (site )
47924804 and (isinstance (old_type , (TStruct , TVector ))
47934805 or isinstance (real , (TStruct , TVector )))):
47944806 # these casts are permitted by C only if old and new are
47954807 # the same type, which is useless
47964808 return Cast (site , expr , new_type )
4797- if isinstance (real , TStruct ):
4798- if isinstance (old_type , TStruct ) and old_type .label == real .label :
4799- return expr
4800- raise ECAST (site , expr , new_type )
4801- if isinstance (real , TExternStruct ):
4802- if isinstance (old_type , TExternStruct ) and old_type .id == real .id :
4803- return expr
4809+ if isinstance (real , (TVoid , TArray , TFunction )):
48044810 raise ECAST (site , expr , new_type )
4805- if isinstance (real , (TVoid , TArray , TVector , TTraitList , TFunction )):
4811+ if old_type .cmp (real ) == 0 :
4812+ if (old_type .is_int
4813+ and not old_type .is_endian
4814+ and dml .globals .compat_dml12_int (expr .site )):
4815+ # 1.2 integer expressions often lie about their actual type,
4816+ # and require a "redundant" cast! Why yes, this IS horrid!
4817+ return Cast (site , expr , new_type )
4818+ return mkRValue (expr )
4819+ if isinstance (real , (TStruct , TExternStruct , TVector , TTraitList )):
48064820 raise ECAST (site , expr , new_type )
48074821 if isinstance (old_type , (TVoid , TStruct , TVector , TTraitList , TTrait )):
48084822 raise ECAST (site , expr , new_type )
48094823 if old_type .is_int and old_type .is_endian :
48104824 expr = as_int (expr )
48114825 old_type = safe_realtype (expr .ctype ())
48124826 if real .is_int and not real .is_endian :
4813- if isinstance ( expr , IntegerConstant ) :
4827+ if old_type . is_int and expr . constant :
48144828 value = truncate_int_bits (expr .value , real .signed , real .bits )
48154829 if dml .globals .compat_dml12_int (site ):
48164830 return IntegerConstant_dml12 (site , value , real )
@@ -4821,8 +4835,8 @@ def mkCast(site, expr, new_type):
48214835 # Shorten redundant chains of integer casts. Avoids insane C
48224836 # output for expressions like a+b+c+d.
48234837 if (isinstance (expr , Cast )
4824- and isinstance (expr . type , TInt )
4825- and expr . type .bits >= real .bits ):
4838+ and isinstance (old_type , TInt )
4839+ and old_type .bits >= real .bits ):
48264840 # (uint64)(int64)x -> (uint64)x
48274841 expr = expr .expr
48284842 old_type = safe_realtype (expr .ctype ())
@@ -4858,9 +4872,7 @@ def mkCast(site, expr, new_type):
48584872 return expr
48594873 elif real .is_int and real .is_endian :
48604874 old_type = safe_realtype (expr .ctype ())
4861- if real .cmp (old_type ) == 0 :
4862- return expr
4863- elif old_type .is_arith or isinstance (old_type , TPtr ):
4875+ if old_type .is_arith or isinstance (old_type , TPtr ):
48644876 return mkApply (
48654877 expr .site ,
48664878 mkLit (expr .site , * real .get_store_fun ()),
@@ -4917,7 +4929,6 @@ def mkCast(site, expr, new_type):
49174929class RValue (Expression ):
49184930 '''Wraps an lvalue to prohibit write. Useful when a composite
49194931 expression is reduced down to a single variable.'''
4920- writable = False
49214932 @auto_init
49224933 def __init__ (self , site , expr ): pass
49234934 def __str__ (self ):
@@ -4926,11 +4937,22 @@ def ctype(self):
49264937 return self .expr .ctype ()
49274938 def read (self ):
49284939 return self .expr .read ()
4929- def discard (self ): pass
4940+ def discard (self ):
4941+ return self .expr .discard ()
49304942 def incref (self ):
49314943 self .expr .incref ()
49324944 def decref (self ):
49334945 self .expr .decref ()
4946+ @property
4947+ def explicit_type (self ):
4948+ return self .expr .explicit_type
4949+ @property
4950+ def type (self ):
4951+ assert self .explicit_type
4952+ return self .expr .type
4953+ @property
4954+ def is_pointer_to_stack_allocation (self ):
4955+ return self .expr .is_pointer_to_stack_allocation
49344956
49354957def mkRValue (expr ):
49364958 if isinstance (expr , LValue ) or expr .writable :
0 commit comments