Skip to content

Commit f52d18c

Browse files
committed
C++: Handle forwarding without a constructor.
1 parent d9331e9 commit f52d18c

1 file changed

Lines changed: 36 additions & 5 deletions

File tree

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1097,9 +1097,9 @@ private Type getForwardedConstructorType(
10971097
)
10981098
}
10991099

1100-
/** Interprets a forwarding model, retaining its output and provenance. */
1101-
private predicate interpretForwardsModel(
1102-
Function forwarder, Constructor constructor, int start, string output, string provenance,
1100+
/** Interprets a forwarding model, retaining its constructed type, output, and provenance. */
1101+
private predicate interpretForwardsModelType(
1102+
Function forwarder, Type constructedType, int start, string output, string provenance,
11031103
string model
11041104
) {
11051105
exists(
@@ -1114,7 +1114,7 @@ private predicate interpretForwardsModel(
11141114
// Either the row specifies forwarding to a type given by the type or
11151115
// function template, in which case we need to resolve that from the type
11161116
// or function name.
1117-
constructor.getDeclaringType() =
1117+
constructedType =
11181118
getForwardedConstructorType(forwarder, namespace, type, subtypes, name, signature, ext,
11191119
constructorType).getUnspecifiedType()
11201120
or
@@ -1123,7 +1123,7 @@ private predicate interpretForwardsModel(
11231123
getForwardedConstructorType(forwarder, namespace, type, subtypes, name, signature, ext,
11241124
constructorType)
11251125
) and
1126-
classHasQualifiedName(constructor.getDeclaringType(), namespace, constructorType)
1126+
classHasQualifiedName(constructedType, namespace, constructorType)
11271127
)
11281128
}
11291129

@@ -1132,6 +1132,15 @@ private predicate interpretForwardsModel(
11321132
* actual constructor being forwarded to depends on the types of arguments from `start`
11331133
* at calls to `forwarder`.
11341134
*/
1135+
private predicate interpretForwardsModel(
1136+
Function forwarder, Constructor constructor, int start, string output, string provenance,
1137+
string model
1138+
) {
1139+
interpretForwardsModelType(forwarder, constructor.getDeclaringType(), start, output, provenance,
1140+
model)
1141+
}
1142+
1143+
/** Holds if `forwarder` forwards its arguments starting at `start` to `constructor`. */
11351144
predicate forwards(Function forwarder, Constructor constructor, int start) {
11361145
interpretForwardsModel(forwarder, constructor, start, _, _, _)
11371146
}
@@ -1140,6 +1149,14 @@ private int referenceIndirection(Type unspecified) {
11401149
if unspecified instanceof ReferenceType then result = 1 else result = 0
11411150
}
11421151

1152+
/** Gets `unspecified`, but with its outermost reference removed, if any. */
1153+
private Type stripReference(Type unspecified) {
1154+
result = unspecified.(ReferenceType).getBaseType().getUnspecifiedType()
1155+
or
1156+
not unspecified instanceof ReferenceType and
1157+
result = unspecified
1158+
}
1159+
11431160
/**
11441161
* In order to support flow summaries for functions that perform "perfect
11451162
* forwarding" we interpret a call such as:
@@ -1183,6 +1200,20 @@ private predicate interpretForwardingSummary(
11831200
input = "Argument[forward].Parameter[-1]" and
11841201
output = constructorOutput
11851202
)
1203+
or
1204+
// Scalar types have no constructor to synthesize. In this case, directly
1205+
// preserve the value of the single forwarded argument at the modeled output.
1206+
exists(Type constructedType, int start, Parameter p, int indirection |
1207+
interpretForwardsModelType(forwarder, constructedType, start, output, provenance, model) and
1208+
not constructedType instanceof Class and
1209+
forwarder.getNumberOfParameters() = start + 1 and
1210+
p = forwarder.getParameter(start) and
1211+
stripReference(p.getUnspecifiedType()) = constructedType and
1212+
indirection = [0 .. SsaImpl::getMaxIndirectionsForPRType(constructedType)] and
1213+
input =
1214+
"Argument[" + repeatStars(indirection + referenceIndirection(p.getUnspecifiedType())) + start +
1215+
"]"
1216+
)
11861217
}
11871218

11881219
/**

0 commit comments

Comments
 (0)