@@ -1220,6 +1220,7 @@ module ConstructorForwarding {
12201220 ( t1 .isVolatile ( ) implies t2 .isVolatile ( ) )
12211221 }
12221222
1223+ bindingset [ arg]
12231224 private predicate baseTypeCompatible ( Type arg , Type param ) {
12241225 param .stripTopLevelSpecifiers ( ) = arg .stripTopLevelSpecifiers ( ) .( Class ) .getABaseClass + ( ) and
12251226 preservesQualifiers ( arg , param )
@@ -1229,6 +1230,7 @@ module ConstructorForwarding {
12291230
12301231 private predicate routineType ( Type t ) { t .stripTopLevelSpecifiers ( ) instanceof RoutineType }
12311232
1233+ bindingset [ arg]
12321234 private predicate pointerConversion ( Cpp:: PointerType arg , Cpp:: PointerType param ) {
12331235 exists ( Type argBase , Type paramBase |
12341236 argBase = arg .getBaseType ( ) and
@@ -1256,6 +1258,7 @@ module ConstructorForwarding {
12561258 t instanceof RoutineType
12571259 }
12581260
1261+ bindingset [ t, category]
12591262 private predicate referenceAcceptsCategory ( Cpp:: ReferenceType t , ValueCategory category ) {
12601263 if t instanceof Cpp:: LValueReferenceType
12611264 then
@@ -1285,19 +1288,13 @@ module ConstructorForwarding {
12851288
12861289 private predicate isUnderlyingType ( Type type ) { type = type .getUnderlyingType ( ) }
12871290
1288- private newtype TTypeState =
1289- MkTypeState ( Type type , ValueCategory category , Boolean conversionUsed , Phase phase ) {
1290- not type instanceof Cpp:: ReferenceType and
1291- not type instanceof FunctionReferenceType and
1292- isUnderlyingType ( type )
1293- }
1294-
12951291 private ValueCategory getCategoryForRef ( Cpp:: ReferenceType reference ) {
12961292 reference instanceof Cpp:: LValueReferenceType and result = LValue ( )
12971293 or
12981294 reference instanceof Cpp:: RValueReferenceType and result = XValue ( )
12991295 }
13001296
1297+ bindingset [ t]
13011298 private Type getValueType ( Type t , ValueCategory category ) {
13021299 result = t .( FunctionReferenceType ) .getBaseType ( ) .getUnderlyingType ( ) and
13031300 category = LValue ( )
@@ -1311,71 +1308,33 @@ module ConstructorForwarding {
13111308 category = PRValue ( )
13121309 }
13131310
1314- bindingset [ arg, param]
1315- pragma [ inline_late]
1311+ bindingset [ arg]
13161312 private predicate qualificationCompatible ( Type arg , Type param ) {
13171313 arg .stripTopLevelSpecifiers ( ) = param .stripTopLevelSpecifiers ( ) and
13181314 preservesQualifiers ( arg , param )
13191315 }
13201316
1321- private class TypeState extends TTypeState {
1322- Type getType ( ) { this = MkTypeState ( result , _, _, _) }
1323-
1324- ValueCategory getCategory ( ) { this = MkTypeState ( _, result , _, _) }
1325-
1326- Phase getPhase ( ) { this = MkTypeState ( _, _, _, result ) }
1327-
1328- /** Holds if this state's phase permits a value or base-class conversion. */
1329- predicate canConvertValue ( ) {
1330- this .getPhase ( ) = Initial ( ) or this .getPhase ( ) = AfterTransformation ( )
1331- }
1332-
1333- predicate hasNotUsedConversion ( ) { this = MkTypeState ( _, _, false , _) }
1334-
1335- string toString ( ) { result = this .getType ( ) .toString ( ) }
1336-
1337- predicate isSource ( Type argType ) {
1338- argType = getForwardedArgumentType ( _, _, _) and
1339- exists ( ValueCategory category |
1340- this = MkTypeState ( getValueType ( argType , category ) , category , false , Initial ( ) )
1341- )
1342- }
1343-
1344- predicate matchesParameter ( Type paramType ) {
1345- exists ( Type base | base = paramType .( Cpp:: ReferenceType ) .getBaseType ( ) |
1346- qualificationCompatible ( this .getType ( ) , base ) and
1347- referenceAcceptsCategory ( paramType , this .getCategory ( ) )
1348- )
1349- or
1350- not paramType instanceof Cpp:: ReferenceType and
1351- this .getType ( ) .stripTopLevelSpecifiers ( ) = paramType .stripTopLevelSpecifiers ( )
1352- }
1353-
1354- predicate isSink ( Type paramType , Cpp:: Constructor constructor ) {
1355- paramType = getConstructorParameterType ( constructor , _) and
1356- this .matchesParameter ( paramType )
1357- }
1317+ bindingset [ argType, category]
1318+ private predicate matchesParameter ( Type argType , ValueCategory category , Type paramType ) {
1319+ exists ( Type base | base = paramType .( Cpp:: ReferenceType ) .getBaseType ( ) |
1320+ qualificationCompatible ( argType , base ) and
1321+ referenceAcceptsCategory ( paramType , category )
1322+ )
1323+ or
1324+ not paramType instanceof Cpp:: ReferenceType and
1325+ argType .stripTopLevelSpecifiers ( ) = paramType .stripTopLevelSpecifiers ( )
13581326 }
13591327
13601328 private Cpp:: PointerType pointerType ( Type base ) {
13611329 result .getBaseType ( ) = base .getUnderlyingType ( )
13621330 }
13631331
1364- private predicate arrayToPointerStep ( TypeState argState , TypeState paramState ) {
1365- exists ( Cpp:: ArrayType array , boolean conversionUsed |
1366- argState = MkTypeState ( array , _, conversionUsed , Initial ( ) ) and
1367- paramState =
1368- MkTypeState ( pointerType ( array .getBaseType ( ) ) , PRValue ( ) , conversionUsed ,
1369- AfterTransformation ( ) )
1370- )
1332+ private predicate arrayToPointerStep ( Cpp:: ArrayType array , Cpp:: PointerType pointer ) {
1333+ pointer = pointerType ( array .getBaseType ( ) )
13711334 }
13721335
1373- private predicate functionToPointerStep ( TypeState argState , TypeState paramState ) {
1374- exists ( RoutineType routine , FunctionPointerType pointer , boolean conversionUsed |
1375- argState = MkTypeState ( routine , _, conversionUsed , Initial ( ) ) and
1376- routine = pointer .getBaseType ( ) .getUnderlyingType ( ) and
1377- paramState = MkTypeState ( pointer , PRValue ( ) , conversionUsed , AfterTransformation ( ) )
1378- )
1336+ private predicate functionToPointerStep ( RoutineType routine , FunctionPointerType pointer ) {
1337+ routine = pointer .getBaseType ( ) .getUnderlyingType ( )
13791338 }
13801339
13811340 private predicate arithmeticConversion ( Type t ) {
@@ -1386,14 +1345,12 @@ module ConstructorForwarding {
13861345
13871346 private predicate hasNoTopLevelSpecifiers ( Type type ) { type = type .stripTopLevelSpecifiers ( ) }
13881347
1389- private predicate valueConversionStep ( TypeState argState , TypeState paramState ) {
1390- exists ( Type argType , Type paramType , boolean conversionUsed |
1391- argState = MkTypeState ( _, _, conversionUsed , _) and
1392- argState .canConvertValue ( ) and
1393- argType = argState .getType ( ) .stripTopLevelSpecifiers ( ) and
1348+ bindingset [ type]
1349+ private predicate valueConversionStep ( Type type , Type paramType ) {
1350+ exists ( Type argType |
1351+ argType = type .stripTopLevelSpecifiers ( ) and
13941352 hasNoTopLevelSpecifiers ( paramType ) and
1395- argType != paramType and
1396- paramState = MkTypeState ( paramType , PRValue ( ) , conversionUsed , AfterValueConversion ( ) )
1353+ argType != paramType
13971354 |
13981355 paramType instanceof ArithmeticType and
13991356 arithmeticConversion ( argType )
@@ -1420,86 +1377,151 @@ module ConstructorForwarding {
14201377 k = FunPtrKind ( )
14211378 }
14221379
1423- private predicate pointerQualificationStep ( TypeState argState , TypeState paramState ) {
1424- exists ( Type argType , Type paramType , boolean conversionUsed , PtrKind k |
1425- argState = MkTypeState ( _, _, conversionUsed , _) and
1426- argState .getPhase ( ) != AfterQualification ( ) and
1427- argType = argState .getType ( ) .stripTopLevelSpecifiers ( ) and
1380+ bindingset [ type]
1381+ private predicate pointerQualificationStep ( Type type , Type paramType ) {
1382+ exists ( Type argType , PtrKind k |
1383+ argType = type .stripTopLevelSpecifiers ( ) and
14281384 hasNoTopLevelSpecifiers ( paramType ) and
14291385 argType != paramType and
1430- qualificationCompatible ( pointerBase ( argType , k ) , pointerBase ( paramType , k ) ) and
1431- paramState = MkTypeState ( paramType , PRValue ( ) , conversionUsed , AfterQualification ( ) )
1386+ qualificationCompatible ( pointerBase ( argType , pragma [ only_bind_into ] ( k ) ) ,
1387+ pointerBase ( paramType , pragma [ only_bind_into ] ( k ) ) )
14321388 )
14331389 }
14341390
1435- private predicate baseClassStep ( TypeState argState , TypeState paramState ) {
1436- exists ( Type arg , Type param , ValueCategory category , boolean conversionUsed |
1437- argState = MkTypeState ( arg , category , conversionUsed , _) and
1438- argState .canConvertValue ( ) and
1439- baseTypeCompatible ( arg , param ) and
1440- paramState = MkTypeState ( param , category , conversionUsed , AfterValueConversion ( ) )
1441- )
1391+ bindingset [ argType]
1392+ private predicate baseClassStep ( Type argType , Type paramType ) {
1393+ baseTypeCompatible ( argType , paramType )
14421394 }
14431395
1444- private predicate convertingConstructorStep ( TypeState argState , TypeState paramState ) {
1396+ bindingset [ argType, argCategory]
1397+ private predicate convertingConstructorStep (
1398+ Type argType , ValueCategory argCategory , Class paramType
1399+ ) {
14451400 exists ( ConvertingConstructor constructor |
1446- argState .hasNotUsedConversion ( ) and
1447- argState .matchesParameter ( constructor .getUnderlyingFromType ( ) ) and
1448- paramState = MkTypeState ( constructor .getDeclaringType ( ) , PRValue ( ) , true , Initial ( ) )
1401+ matchesParameter ( argType , argCategory , constructor .getUnderlyingFromType ( ) ) and
1402+ paramType = constructor .getDeclaringType ( )
14491403 )
14501404 }
14511405
1452- private predicate conversionOperatorStep ( TypeState argState , TypeState paramState ) {
1453- exists ( ConversionOperator conversion , ValueCategory category |
1406+ bindingset [ argType]
1407+ private predicate conversionOperatorStep ( Type argType , Type paramType , ValueCategory paramCategory ) {
1408+ exists ( ConversionOperator conversion |
14541409 not conversion .isFromUninstantiatedTemplate ( _) and
14551410 not conversion .isExplicit ( ) and
14561411 not conversion .isDeleted ( ) and
1457- argState .hasNotUsedConversion ( ) and
1458- conversion .getSourceType ( ) =
1459- argState .getType ( ) .stripTopLevelSpecifiers ( ) .( Class ) .getABaseClass * ( ) and
1460- paramState =
1461- MkTypeState ( getValueType ( conversion .getDestType ( ) .getUnderlyingType ( ) , category ) , category ,
1462- true , Initial ( ) )
1412+ conversion .getSourceType ( ) = argType .stripTopLevelSpecifiers ( ) .( Class ) .getABaseClass * ( ) and
1413+ paramType = getValueType ( conversion .getDestType ( ) .getUnderlyingType ( ) , paramCategory )
14631414 )
14641415 }
14651416
1466- private predicate step ( TypeState argState , TypeState paramState ) {
1467- arrayToPointerStep ( argState , paramState )
1468- or
1469- functionToPointerStep ( argState , paramState )
1470- or
1471- valueConversionStep ( argState , paramState )
1472- or
1473- pointerQualificationStep ( argState , paramState )
1474- or
1475- baseClassStep ( argState , paramState )
1476- or
1477- convertingConstructorStep ( argState , paramState )
1478- or
1479- conversionOperatorStep ( argState , paramState )
1480- }
1481-
1482- private predicate typeFwd ( TypeState state ) {
1483- state .isSource ( _)
1417+ bindingset [ argType, argCategory, argConversionUsed, argPhase]
1418+ pragma [ inline_late]
1419+ private predicate typeStep (
1420+ Type argType , ValueCategory argCategory , boolean argConversionUsed , Phase argPhase ,
1421+ Type paramType , ValueCategory paramCategory , boolean paramConversionUsed , Phase paramPhase
1422+ ) {
1423+ paramConversionUsed = argConversionUsed and
1424+ (
1425+ argPhase = Initial ( ) and
1426+ paramCategory = PRValue ( ) and
1427+ paramPhase = AfterTransformation ( ) and
1428+ (
1429+ arrayToPointerStep ( argType , paramType )
1430+ or
1431+ functionToPointerStep ( argType , paramType )
1432+ )
1433+ or
1434+ ( argPhase = Initial ( ) or argPhase = AfterTransformation ( ) ) and
1435+ paramPhase = AfterValueConversion ( ) and
1436+ (
1437+ valueConversionStep ( argType , paramType ) and paramCategory = PRValue ( )
1438+ or
1439+ baseClassStep ( argType , paramType ) and paramCategory = argCategory
1440+ )
1441+ or
1442+ argPhase != AfterQualification ( ) and
1443+ pointerQualificationStep ( argType , paramType ) and
1444+ paramCategory = PRValue ( ) and
1445+ paramPhase = AfterQualification ( )
1446+ )
14841447 or
1485- exists ( TypeState previous |
1486- typeFwd ( previous ) and
1487- step ( previous , state )
1448+ argConversionUsed = false and
1449+ paramConversionUsed = true and
1450+ paramPhase = Initial ( ) and
1451+ (
1452+ convertingConstructorStep ( argType , argCategory , paramType ) and paramCategory = PRValue ( )
1453+ or
1454+ conversionOperatorStep ( argType , paramType , paramCategory )
14881455 )
14891456 }
14901457
1491- private predicate typeRev ( TypeState state , Cpp:: Constructor constructor ) {
1492- typeFwd ( state ) and
1458+ private predicate typeFwd ( Type type , ValueCategory category , boolean conversionUsed , Phase phase ) {
1459+ not type instanceof Cpp:: ReferenceType and
1460+ not type instanceof FunctionReferenceType and
1461+ isUnderlyingType ( type ) and
14931462 (
1494- state .isSink ( _, constructor )
1463+ type = getValueType ( getForwardedArgumentType ( _, _, _) , category ) and
1464+ conversionUsed = false and
1465+ phase = Initial ( )
14951466 or
1496- exists ( TypeState next |
1497- typeRev ( next , constructor ) and
1498- step ( state , next )
1467+ exists (
1468+ Type previousType , ValueCategory previousCategory , boolean previousConversionUsed ,
1469+ Phase previousPhase
1470+ |
1471+ typeFwd ( previousType , previousCategory , previousConversionUsed , previousPhase ) and
1472+ typeStep ( previousType , previousCategory , previousConversionUsed , previousPhase , type ,
1473+ category , conversionUsed , phase )
14991474 )
15001475 )
15011476 }
15021477
1478+ private newtype TTypeState =
1479+ MkTypeState ( Type type , ValueCategory category , Boolean conversionUsed , Phase phase ) {
1480+ typeFwd ( type , category , conversionUsed , phase )
1481+ }
1482+
1483+ private class TypeState extends TTypeState {
1484+ Type getType ( ) { this = MkTypeState ( result , _, _, _) }
1485+
1486+ ValueCategory getCategory ( ) { this = MkTypeState ( _, result , _, _) }
1487+
1488+ Phase getPhase ( ) { this = MkTypeState ( _, _, _, result ) }
1489+
1490+ string toString ( ) { result = this .getType ( ) .toString ( ) }
1491+
1492+ predicate isSource ( Type argType ) {
1493+ argType = getForwardedArgumentType ( _, _, _) and
1494+ exists ( ValueCategory category |
1495+ this = MkTypeState ( getValueType ( argType , category ) , category , false , Initial ( ) )
1496+ )
1497+ }
1498+
1499+ predicate isSink ( Type paramType , Cpp:: Constructor constructor ) {
1500+ paramType = getConstructorParameterType ( constructor , _) and
1501+ matchesParameter ( this .getType ( ) , this .getCategory ( ) , paramType )
1502+ }
1503+ }
1504+
1505+ private predicate step ( TypeState argState , TypeState paramState ) {
1506+ exists (
1507+ Type t1 , Type t2 , ValueCategory vc1 , ValueCategory vc2 , boolean b1 , boolean b2 , Phase p1 ,
1508+ Phase p2
1509+ |
1510+ argState = MkTypeState ( t1 , vc1 , b1 , p1 ) and
1511+ paramState = MkTypeState ( t2 , vc2 , b2 , p2 ) and
1512+ typeStep ( t1 , vc1 , b1 , p1 , t2 , vc2 , b2 , p2 )
1513+ )
1514+ }
1515+
1516+ private predicate typeRev ( TypeState state , Cpp:: Constructor constructor ) {
1517+ state .isSink ( _, constructor )
1518+ or
1519+ exists ( TypeState next |
1520+ typeRev ( next , constructor ) and
1521+ step ( state , next )
1522+ )
1523+ }
1524+
15031525 private predicate prunedStep ( TypeState argState , TypeState paramState ) {
15041526 exists ( Cpp:: Constructor constructor |
15051527 typeRev ( argState , constructor ) and
0 commit comments