@@ -1631,18 +1631,35 @@ predicate localExprFlow(Expr e1, Expr e2) {
1631
1631
localExprFlowPlus ( e1 , e2 )
1632
1632
}
1633
1633
1634
+ bindingset [ f]
1635
+ pragma [ inline_late]
1636
+ private int getFieldSize ( Field f ) { result = f .getType ( ) .getSize ( ) }
1637
+
1638
+ /**
1639
+ * Gets a field in the union `u` whose size
1640
+ * is `bytes` number of bytes.
1641
+ */
1642
+ private Field getAFieldWithSize ( Union u , int bytes ) {
1643
+ result = u .getAField ( ) and
1644
+ bytes = getFieldSize ( result )
1645
+ }
1646
+
1634
1647
cached
1635
1648
private newtype TContent =
1636
1649
TFieldContent ( Field f , int indirectionIndex ) {
1637
1650
indirectionIndex = [ 1 .. Ssa:: getMaxIndirectionsForType ( f .getUnspecifiedType ( ) ) ] and
1638
1651
// Reads and writes of union fields are tracked using `UnionContent`.
1639
1652
not f .getDeclaringType ( ) instanceof Union
1640
1653
} or
1641
- TUnionContent ( Union u , int indirectionIndex ) {
1642
- // We key `UnionContent` by the union instead of its fields since a write to one
1643
- // field can be read by any read of the union's fields.
1644
- indirectionIndex =
1645
- [ 1 .. max ( Ssa:: getMaxIndirectionsForType ( u .getAField ( ) .getUnspecifiedType ( ) ) ) ]
1654
+ TUnionContent ( Union u , int bytes , int indirectionIndex ) {
1655
+ exists ( Field f |
1656
+ f = u .getAField ( ) and
1657
+ bytes = getFieldSize ( f ) and
1658
+ // We key `UnionContent` by the union instead of its fields since a write to one
1659
+ // field can be read by any read of the union's fields.
1660
+ indirectionIndex =
1661
+ [ 1 .. max ( Ssa:: getMaxIndirectionsForType ( getAFieldWithSize ( u , bytes ) .getUnspecifiedType ( ) ) ) ]
1662
+ )
1646
1663
}
1647
1664
1648
1665
/**
@@ -1684,8 +1701,9 @@ class FieldContent extends Content, TFieldContent {
1684
1701
class UnionContent extends Content , TUnionContent {
1685
1702
Union u ;
1686
1703
int indirectionIndex ;
1704
+ int bytes ;
1687
1705
1688
- UnionContent ( ) { this = TUnionContent ( u , indirectionIndex ) }
1706
+ UnionContent ( ) { this = TUnionContent ( u , bytes , indirectionIndex ) }
1689
1707
1690
1708
override string toString ( ) {
1691
1709
indirectionIndex = 1 and result = u .toString ( )
@@ -1694,7 +1712,7 @@ class UnionContent extends Content, TUnionContent {
1694
1712
}
1695
1713
1696
1714
/** Gets a field of the underlying union of this `UnionContent`, if any. */
1697
- Field getAField ( ) { result = u .getAField ( ) }
1715
+ Field getAField ( ) { result = u .getAField ( ) and getFieldSize ( result ) = bytes }
1698
1716
1699
1717
/** Gets the underlying union of this `UnionContent`. */
1700
1718
Union getUnion ( ) { result = u }
0 commit comments