Skip to content

Commit 0a3f958

Browse files
committed
C++: Use content approximations.
1 parent 73d877e commit 0a3f958

File tree

2 files changed

+56
-15
lines changed

2 files changed

+56
-15
lines changed

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

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -795,12 +795,63 @@ predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preserves
795795
*/
796796
predicate allowParameterReturnInSelf(ParameterNode p) { none() }
797797

798+
private predicate fieldHasApproxName(Field f, string s) {
799+
s = f.getName().charAt(0) and
800+
// Reads and writes of union fields are tracked using `UnionContent`.
801+
not f.getDeclaringType() instanceof Cpp::Union
802+
}
803+
804+
private predicate unionHasApproxName(Cpp::Union u, string s) { s = u.getName().charAt(0) }
805+
806+
cached
807+
private newtype TContentApprox =
808+
TFieldApproxContent(string s) { fieldHasApproxName(_, s) } or
809+
TUnionApproxContent(string s) { unionHasApproxName(_, s) }
810+
798811
/** An approximated `Content`. */
799-
class ContentApprox = Unit;
812+
class ContentApprox extends TContentApprox {
813+
string toString() { none() } // overriden in subclasses
814+
}
815+
816+
private class FieldApproxContent extends ContentApprox, TFieldApproxContent {
817+
string s;
818+
819+
FieldApproxContent() { this = TFieldApproxContent(s) }
820+
821+
Field getAField() { fieldHasApproxName(result, s) }
822+
823+
string getPrefix() { result = s }
824+
825+
final override string toString() { result = s }
826+
}
827+
828+
private class UnionApproxContent extends ContentApprox, TUnionApproxContent {
829+
string s;
830+
831+
UnionApproxContent() { this = TUnionApproxContent(s) }
832+
833+
Cpp::Union getAUnion() { unionHasApproxName(result, s) }
834+
835+
string getPrefix() { result = s }
836+
837+
final override string toString() { result = s }
838+
}
800839

801840
/** Gets an approximated value for content `c`. */
802841
pragma[inline]
803-
ContentApprox getContentApprox(Content c) { any() }
842+
ContentApprox getContentApprox(Content c) {
843+
exists(string prefix, Field f |
844+
prefix = result.(FieldApproxContent).getPrefix() and
845+
f = c.(FieldContent).getField() and
846+
fieldHasApproxName(f, prefix)
847+
)
848+
or
849+
exists(string prefix, Cpp::Union u |
850+
prefix = result.(UnionApproxContent).getPrefix() and
851+
u = c.(UnionContent).getUnion() and
852+
unionHasApproxName(u, prefix)
853+
)
854+
}
804855

805856
private class MyConsistencyConfiguration extends Consistency::ConsistencyConfiguration {
806857
override predicate argHasPostUpdateExclude(ArgumentNode n) {

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

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1628,9 +1628,7 @@ private newtype TContent =
16281628
// field can be read by any read of the union's fields.
16291629
indirectionIndex =
16301630
[1 .. max(Ssa::getMaxIndirectionsForType(u.getAField().getUnspecifiedType()))]
1631-
} or
1632-
TCollectionContent() or // Not used in C/C++
1633-
TArrayContent() // Not used in C/C++.
1631+
}
16341632

16351633
/**
16361634
* A description of the way data may be stored inside an object. Examples
@@ -1682,22 +1680,14 @@ class UnionContent extends Content, TUnionContent {
16821680

16831681
Field getAField() { result = u.getAField() }
16841682

1683+
Union getUnion() { result = u }
1684+
16851685
pragma[inline]
16861686
int getIndirectionIndex() {
16871687
pragma[only_bind_into](result) = pragma[only_bind_out](indirectionIndex)
16881688
}
16891689
}
16901690

1691-
/** A reference through an array. */
1692-
class ArrayContent extends Content, TArrayContent {
1693-
override string toString() { result = "[]" }
1694-
}
1695-
1696-
/** A reference through the contents of some collection-like container. */
1697-
private class CollectionContent extends Content, TCollectionContent {
1698-
override string toString() { result = "<element>" }
1699-
}
1700-
17011691
/**
17021692
* An entity that represents a set of `Content`s.
17031693
*

0 commit comments

Comments
 (0)