@@ -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`. */
11351144predicate 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