@@ -1616,18 +1616,35 @@ predicate localExprFlow(Expr e1, Expr e2) {
1616
1616
localExprFlowPlus ( e1 , e2 )
1617
1617
}
1618
1618
1619
+ bindingset [ f]
1620
+ pragma [ inline_late]
1621
+ private int getFieldSize ( Field f ) { result = f .getType ( ) .getSize ( ) }
1622
+
1623
+ /**
1624
+ * Gets a field in the union `u` whose size
1625
+ * is `bytes` number of bytes.
1626
+ */
1627
+ private Field getAFieldWithSize ( Union u , int bytes ) {
1628
+ result = u .getAField ( ) and
1629
+ bytes = getFieldSize ( result )
1630
+ }
1631
+
1619
1632
cached
1620
1633
private newtype TContent =
1621
1634
TFieldContent ( Field f , int indirectionIndex ) {
1622
1635
indirectionIndex = [ 1 .. Ssa:: getMaxIndirectionsForType ( f .getUnspecifiedType ( ) ) ] and
1623
1636
// Reads and writes of union fields are tracked using `UnionContent`.
1624
1637
not f .getDeclaringType ( ) instanceof Union
1625
1638
} or
1626
- TUnionContent ( Union u , int indirectionIndex ) {
1627
- // We key `UnionContent` by the union instead of its fields since a write to one
1628
- // field can be read by any read of the union's fields.
1629
- indirectionIndex =
1630
- [ 1 .. max ( Ssa:: getMaxIndirectionsForType ( u .getAField ( ) .getUnspecifiedType ( ) ) ) ]
1639
+ TUnionContent ( Union u , int bytes , int indirectionIndex ) {
1640
+ exists ( Field f |
1641
+ f = u .getAField ( ) and
1642
+ bytes = getFieldSize ( f ) and
1643
+ // We key `UnionContent` by the union instead of its fields since a write to one
1644
+ // field can be read by any read of the union's fields.
1645
+ indirectionIndex =
1646
+ [ 1 .. max ( Ssa:: getMaxIndirectionsForType ( getAFieldWithSize ( u , bytes ) .getUnspecifiedType ( ) ) ) ]
1647
+ )
1631
1648
}
1632
1649
1633
1650
/**
@@ -1669,8 +1686,9 @@ class FieldContent extends Content, TFieldContent {
1669
1686
class UnionContent extends Content , TUnionContent {
1670
1687
Union u ;
1671
1688
int indirectionIndex ;
1689
+ int bytes ;
1672
1690
1673
- UnionContent ( ) { this = TUnionContent ( u , indirectionIndex ) }
1691
+ UnionContent ( ) { this = TUnionContent ( u , bytes , indirectionIndex ) }
1674
1692
1675
1693
override string toString ( ) {
1676
1694
indirectionIndex = 1 and result = u .toString ( )
@@ -1679,7 +1697,7 @@ class UnionContent extends Content, TUnionContent {
1679
1697
}
1680
1698
1681
1699
/** Gets a field of the underlying union of this `UnionContent`, if any. */
1682
- Field getAField ( ) { result = u .getAField ( ) }
1700
+ Field getAField ( ) { result = u .getAField ( ) and getFieldSize ( result ) = bytes }
1683
1701
1684
1702
/** Gets the underlying union of this `UnionContent`. */
1685
1703
Union getUnion ( ) { result = u }
0 commit comments