@@ -1222,7 +1222,7 @@ def mkIfExpr(site, cond, texpr, fexpr):
1222
1222
(texpr , fexpr , utype ) = usual_int_conv (
1223
1223
texpr , ttype , fexpr , ftype )
1224
1224
else :
1225
- if not compatible_types (ttype , ftype ):
1225
+ if not compatible_types_fuzzy (ttype , ftype ):
1226
1226
raise EBINOP (site , ':' , texpr , fexpr )
1227
1227
# TODO: in C, the rules are more complex,
1228
1228
# but our type system is too primitive to cover that
@@ -1396,7 +1396,7 @@ def make(cls, site, lh, rh):
1396
1396
if ((lhtype .is_arith and rhtype .is_arith )
1397
1397
or (isinstance (lhtype , (TPtr , TArray ))
1398
1398
and isinstance (rhtype , (TPtr , TArray ))
1399
- and compatible_types (lhtype .base , rhtype .base ))):
1399
+ and compatible_types_fuzzy (lhtype .base , rhtype .base ))):
1400
1400
return cls .make_simple (site , lh , rh )
1401
1401
raise EILLCOMP (site , lh , lhtype , rh , rhtype )
1402
1402
@@ -1601,7 +1601,7 @@ def make(cls, site, lh, rh):
1601
1601
if ((lhtype .is_arith and rhtype .is_arith )
1602
1602
or (isinstance (lhtype , (TPtr , TArray ))
1603
1603
and isinstance (rhtype , (TPtr , TArray ))
1604
- and compatible_types (lhtype , rhtype ))
1604
+ and compatible_types_fuzzy (lhtype , rhtype ))
1605
1605
or (isinstance (lhtype , TBool ) and isinstance (rhtype , TBool ))):
1606
1606
return Equals (site , lh , rh )
1607
1607
@@ -2932,8 +2932,8 @@ def mkInterfaceMethodRef(site, iface_node, indices, method_name):
2932
2932
if (not isinstance (ftype , TPtr )
2933
2933
or not isinstance (ftype .base , TFunction )
2934
2934
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 ):
2937
2937
# non-method members are not accessible
2938
2938
raise EMEMBER (site , struct_name , method_name )
2939
2939
@@ -4674,7 +4674,10 @@ class ArrayRef(LValue):
4674
4674
explicit_type = True
4675
4675
@auto_init
4676
4676
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 )
4678
4681
def __str__ (self ):
4679
4682
return '%s[%s]' % (self .expr , self .idx )
4680
4683
def read (self ):
@@ -4787,30 +4790,41 @@ def mkCast(site, expr, new_type):
4787
4790
raise ETEMPLATEUPCAST (site , "object" , new_type )
4788
4791
else :
4789
4792
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 ()
4790
4802
old_type = safe_realtype (expr .ctype ())
4791
4803
if (dml .globals .compat_dml12_int (site )
4792
4804
and (isinstance (old_type , (TStruct , TVector ))
4793
4805
or isinstance (real , (TStruct , TVector )))):
4794
4806
# these casts are permitted by C only if old and new are
4795
4807
# the same type, which is useless
4796
4808
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 )):
4804
4810
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 )):
4806
4820
raise ECAST (site , expr , new_type )
4807
4821
if isinstance (old_type , (TVoid , TStruct , TVector , TTraitList , TTrait )):
4808
4822
raise ECAST (site , expr , new_type )
4809
4823
if old_type .is_int and old_type .is_endian :
4810
4824
expr = as_int (expr )
4811
4825
old_type = safe_realtype (expr .ctype ())
4812
4826
if real .is_int and not real .is_endian :
4813
- if isinstance ( expr , IntegerConstant ) :
4827
+ if old_type . is_int and expr . constant :
4814
4828
value = truncate_int_bits (expr .value , real .signed , real .bits )
4815
4829
if dml .globals .compat_dml12_int (site ):
4816
4830
return IntegerConstant_dml12 (site , value , real )
@@ -4821,8 +4835,8 @@ def mkCast(site, expr, new_type):
4821
4835
# Shorten redundant chains of integer casts. Avoids insane C
4822
4836
# output for expressions like a+b+c+d.
4823
4837
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 ):
4826
4840
# (uint64)(int64)x -> (uint64)x
4827
4841
expr = expr .expr
4828
4842
old_type = safe_realtype (expr .ctype ())
@@ -4858,9 +4872,7 @@ def mkCast(site, expr, new_type):
4858
4872
return expr
4859
4873
elif real .is_int and real .is_endian :
4860
4874
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 ):
4864
4876
return mkApply (
4865
4877
expr .site ,
4866
4878
mkLit (expr .site , * real .get_store_fun ()),
@@ -4917,7 +4929,6 @@ def mkCast(site, expr, new_type):
4917
4929
class RValue (Expression ):
4918
4930
'''Wraps an lvalue to prohibit write. Useful when a composite
4919
4931
expression is reduced down to a single variable.'''
4920
- writable = False
4921
4932
@auto_init
4922
4933
def __init__ (self , site , expr ): pass
4923
4934
def __str__ (self ):
@@ -4926,11 +4937,22 @@ def ctype(self):
4926
4937
return self .expr .ctype ()
4927
4938
def read (self ):
4928
4939
return self .expr .read ()
4929
- def discard (self ): pass
4940
+ def discard (self ):
4941
+ return self .expr .discard ()
4930
4942
def incref (self ):
4931
4943
self .expr .incref ()
4932
4944
def decref (self ):
4933
4945
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
4934
4956
4935
4957
def mkRValue (expr ):
4936
4958
if isinstance (expr , LValue ) or expr .writable :
0 commit comments