C++: Fix lambda creation for objects with no constructor.

This commit is contained in:
Mathias Vorreiter Pedersen
2025-07-10 21:08:07 +01:00
parent b53c3547d0
commit df241ad4f6
3 changed files with 24 additions and 1 deletions

View File

@@ -1414,6 +1414,17 @@ private class OperatorCall extends Cpp::MemberFunction {
OperatorCall() { this.hasName("operator()") }
}
private predicate isFunctorCreationWithoutConstructor(Node creation, OperatorCall operator) {
exists(UninitializedInstruction init, Instruction dest |
// A construction of an object with no constructor. In this case we use
// the `UninitializedInstruction` as the creation node.
init = creation.asInstruction() and
dest = init.getDestinationAddress() and
not any(ConstructorCallInstruction constructorCall).getThisArgument() = dest and
operator.getDeclaringType() = init.getResultType()
)
}
private predicate isFunctorCreationWithConstructor(Node creation, OperatorCall operator) {
exists(DataFlowCall constructorCall, IndirectionPosition pos |
// A construction of an object with a constructor. In this case we use
@@ -1432,6 +1443,8 @@ predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c)
or
kind.isFunctor() and
exists(OperatorCall operator | operator = c.asSourceCallable() |
isFunctorCreationWithoutConstructor(creation, operator)
or
isFunctorCreationWithConstructor(creation, operator)
)
}

View File

@@ -76,14 +76,19 @@ edges
| test.cpp:59:55:59:64 | *& ... [x] | test.cpp:52:5:52:18 | [summary param] *3 in pthread_create [x] | provenance | |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | provenance | MaD:23 |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:68:22:68:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:74:22:74:22 | y | provenance | |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | test.cpp:82:22:82:22 | y | provenance | |
| test.cpp:68:22:68:22 | y | test.cpp:69:11:69:11 | y | provenance | Sink:MaD:1 |
| test.cpp:74:22:74:22 | y | test.cpp:75:11:75:11 | y | provenance | Sink:MaD:1 |
| test.cpp:82:22:82:22 | y | test.cpp:83:11:83:11 | y | provenance | Sink:MaD:1 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:94:10:94:18 | call to ymlSource | provenance | Src:MaD:16 |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:97:26:97:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:101:26:101:26 | x | provenance | |
| test.cpp:94:10:94:18 | call to ymlSource | test.cpp:103:63:103:63 | x | provenance | |
| test.cpp:97:26:97:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:101:26:101:26 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| test.cpp:103:63:103:63 | x | test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | provenance | |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | provenance | MaD:18 |
| windows.cpp:22:15:22:29 | *call to GetCommandLineA | windows.cpp:22:15:22:29 | *call to GetCommandLineA | provenance | Src:MaD:3 |
@@ -223,15 +228,20 @@ nodes
| test.cpp:59:55:59:64 | *& ... [x] | semmle.label | *& ... [x] |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary param] 1 in callWithArgument | semmle.label | [summary param] 1 in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:63:6:63:21 | [summary] to write: Argument[0].Parameter[0] in callWithArgument | semmle.label | [summary] to write: Argument[0].Parameter[0] in callWithArgument |
| test.cpp:68:22:68:22 | y | semmle.label | y |
| test.cpp:69:11:69:11 | y | semmle.label | y |
| test.cpp:74:22:74:22 | y | semmle.label | y |
| test.cpp:75:11:75:11 | y | semmle.label | y |
| test.cpp:82:22:82:22 | y | semmle.label | y |
| test.cpp:83:11:83:11 | y | semmle.label | y |
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:94:10:94:18 | call to ymlSource | semmle.label | call to ymlSource |
| test.cpp:97:26:97:26 | x | semmle.label | x |
| test.cpp:101:26:101:26 | x | semmle.label | x |
| test.cpp:103:63:103:63 | x | semmle.label | x |
| windows.cpp:17:8:17:25 | [summary param] *0 in CommandLineToArgvA | semmle.label | [summary param] *0 in CommandLineToArgvA |
| windows.cpp:17:8:17:25 | [summary] to write: ReturnValue[**] in CommandLineToArgvA | semmle.label | [summary] to write: ReturnValue[**] in CommandLineToArgvA |

View File

@@ -72,7 +72,7 @@ struct StructWithOperatorCall_has_constructor {
struct StructWithOperatorCall_no_constructor {
void operator()(int y) {
ymlSink(y); // $ MISSING: ir
ymlSink(y); // $ ir
}
};