Skip to content

Commit c11218f

Browse files
authored
Merge pull request github#12184 from MathiasVP/discriminate-union-contents
2 parents 899f35a + ba0be2f commit c11218f

File tree

1 file changed

+25
-7
lines changed

1 file changed

+25
-7
lines changed

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,18 +1631,35 @@ predicate localExprFlow(Expr e1, Expr e2) {
16311631
localExprFlowPlus(e1, e2)
16321632
}
16331633

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+
16341647
cached
16351648
private newtype TContent =
16361649
TFieldContent(Field f, int indirectionIndex) {
16371650
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
16381651
// Reads and writes of union fields are tracked using `UnionContent`.
16391652
not f.getDeclaringType() instanceof Union
16401653
} 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+
)
16461663
}
16471664

16481665
/**
@@ -1684,8 +1701,9 @@ class FieldContent extends Content, TFieldContent {
16841701
class UnionContent extends Content, TUnionContent {
16851702
Union u;
16861703
int indirectionIndex;
1704+
int bytes;
16871705

1688-
UnionContent() { this = TUnionContent(u, indirectionIndex) }
1706+
UnionContent() { this = TUnionContent(u, bytes, indirectionIndex) }
16891707

16901708
override string toString() {
16911709
indirectionIndex = 1 and result = u.toString()
@@ -1694,7 +1712,7 @@ class UnionContent extends Content, TUnionContent {
16941712
}
16951713

16961714
/** 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 }
16981716

16991717
/** Gets the underlying union of this `UnionContent`. */
17001718
Union getUnion() { result = u }

0 commit comments

Comments
 (0)