diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql index 84292a4a..a877da76 100644 --- a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql +++ b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.ql @@ -17,22 +17,24 @@ * @tags correctness * wddst * @scope domainspecific - * @query-version v1 + * @query-version v2 */ import cpp +import semmle.code.cpp.exprs.Cast from FunctionCall fc, Parameter p, int n where + fc.getArgument(n).getUnspecifiedType() instanceof FunctionPointerType and p.getFunction() = fc.getTarget() and p.getUnspecifiedType() instanceof FunctionPointerType and p.getIndex() = n and - fc.getArgument(n).getUnspecifiedType() instanceof FunctionPointerType and - fc.getArgument(n).getUnspecifiedType().(FunctionPointerType).getReturnType().getUnspecifiedType() != - p.getUnspecifiedType().(FunctionPointerType).getReturnType().getUnspecifiedType() - + + fc.getArgument(n).hasImplicitConversion() + and not fc.getArgument(n).hasExplicitConversion() select fc, - "Function " + fc + " may use a function pointer (" + fc.getArgument(n) + - ") with an unexpected return type: " + - fc.getArgument(n).getUnspecifiedType().(FunctionPointerType).getReturnType() + " expected: " + - p.getUnspecifiedType().(FunctionPointerType).getReturnType() + "Function $@ may use a function pointer $@ for parameter $@ with an unexpected return type or parameter type. Expected formal parameter is: $@ (" + + p.getFunction().getNumberOfParameters() + " parameters). Actual argument: $@ (" + fc.getTarget().getNumberOfParameters() + " arguments).", + fc, fc.toString(), fc.getArgument(n), fc.getArgument(n).toString(),p,p.getName(), + p, p.getUnspecifiedType().(FunctionPointerType).explain(), + fc.getArgument(n),fc.getArgument(n).getUnspecifiedType().(FunctionPointerType).explain() diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qlhelp b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qlhelp index 1bafd5bb..bb9e707f 100644 --- a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qlhelp +++ b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.qlhelp @@ -2,7 +2,7 @@

- The return type of a function pointer used in a function call should match the declaration of the calling function + The driver is passing or assigning a function (pointer) of an unexpected type (that is, function signature)

diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif index 08476746..385e8071 100644 --- a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif +++ b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/RoutineFunctionTypeNotExpected.sarif @@ -7,22 +7,6 @@ "name" : "CodeQL", "organization" : "GitHub", "semanticVersion" : "2.14.6", - "notifications" : [ { - "id" : "cpp/baseline/expected-extracted-files", - "name" : "cpp/baseline/expected-extracted-files", - "shortDescription" : { - "text" : "Expected extracted files" - }, - "fullDescription" : { - "text" : "Files appearing in the source archive that are expected to be extracted." - }, - "defaultConfiguration" : { - "enabled" : true - }, - "properties" : { - "tags" : [ "expected-extracted-files", "telemetry" ] - } - } ], "rules" : [ { "id" : "cpp/drivers/routine-function-type-not-expected", "name" : "cpp/drivers/routine-function-type-not-expected", @@ -49,120 +33,20 @@ "platform" : "Desktop", "precision" : "high", "problem.severity" : "warning", - "query-version" : "v1", + "query-version" : "v2", "repro.text" : "The following code locations use a function pointer with a return type that does not match the expected type", "scope" : "domainspecific", "security.severity" : "Low" } } ] - }, - "extensions" : [ { - "name" : "microsoft/windows-drivers", - "semanticVersion" : "0.1.0+626ab2156fae247d66b189fb2fa9a69c03082e3a", - "locations" : [ { - "uri" : "file:///c:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/", - "description" : { - "text" : "The QL pack root directory." - } - }, { - "uri" : "file:///c:/codeql-home/Windows-Driver-Developer-Supplemental-Tools/src/qlpack.yml", - "description" : { - "text" : "The QL pack definition file." - } - } ] - } ] + } }, - "invocations" : [ { - "toolExecutionNotifications" : [ { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/driver_snippet.c", - "uriBaseId" : "%SRCROOT%", - "index" : 0 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - }, { - "locations" : [ { - "physicalLocation" : { - "artifactLocation" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } - } - } ], - "message" : { - "text" : "" - }, - "level" : "none", - "descriptor" : { - "id" : "cpp/baseline/expected-extracted-files", - "index" : 0 - }, - "properties" : { - "formattedMessage" : { - "text" : "" - } - } - } ], - "executionSuccessful" : true - } ], "artifacts" : [ { "location" : { "uri" : "driver/driver_snippet.c", "uriBaseId" : "%SRCROOT%", "index" : 0 } - }, { - "location" : { - "uri" : "driver/fail_driver1.c", - "uriBaseId" : "%SRCROOT%", - "index" : 1 - } - }, { - "location" : { - "uri" : "driver/fail_driver1.h", - "uriBaseId" : "%SRCROOT%", - "index" : 2 - } } ], "results" : [ { "ruleId" : "cpp/drivers/routine-function-type-not-expected", @@ -172,7 +56,7 @@ "index" : 0 }, "message" : { - "text" : "Function call to functionCallThatUsesFunctionPointer may use a function pointer (fun_ptr1) with an unexpected return type: int expected: void" + "text" : "Function [call to functionCallThatUsesFunctionPointer](1) may use a function pointer [fun_ptr1](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments ()}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{int}} with arguments ()}}](5) (1 arguments)." }, "locations" : [ { "physicalLocation" : { @@ -182,7 +66,7 @@ "index" : 0 }, "region" : { - "startLine" : 52, + "startLine" : 85, "startColumn" : 5, "endColumn" : 40 } @@ -191,7 +75,93 @@ "partialFingerprints" : { "primaryLocationLineHash" : "b6c3b797b0277bdd:1", "primaryLocationStartColumnFingerprint" : "0" - } + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 85, + "startColumn" : 5, + "endColumn" : 40 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 85, + "startColumn" : 41, + "endColumn" : 49 + } + }, + "message" : { + "text" : "fun_ptr1" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 85, + "startColumn" : 41, + "endColumn" : 49 + } + }, + "message" : { + "text" : "pointer to {{function returning {{int}} with arguments ()}}" + } + } ] }, { "ruleId" : "cpp/drivers/routine-function-type-not-expected", "ruleIndex" : 0, @@ -200,7 +170,7 @@ "index" : 0 }, "message" : { - "text" : "Function call to functionCallThatUsesFunctionPointer may use a function pointer (f3) with an unexpected return type: int expected: void" + "text" : "Function [call to functionCallThatUsesFunctionPointer](1) may use a function pointer [f3](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments ()}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{int}} with arguments ()}}](5) (1 arguments)." }, "locations" : [ { "physicalLocation" : { @@ -210,7 +180,7 @@ "index" : 0 }, "region" : { - "startLine" : 54, + "startLine" : 87, "startColumn" : 5, "endColumn" : 40 } @@ -219,7 +189,93 @@ "partialFingerprints" : { "primaryLocationLineHash" : "789a3ee1dd677a33:1", "primaryLocationStartColumnFingerprint" : "0" - } + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 87, + "startColumn" : 5, + "endColumn" : 40 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 87, + "startColumn" : 41, + "endColumn" : 43 + } + }, + "message" : { + "text" : "f3" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 87, + "startColumn" : 41, + "endColumn" : 43 + } + }, + "message" : { + "text" : "pointer to {{function returning {{int}} with arguments ()}}" + } + } ] }, { "ruleId" : "cpp/drivers/routine-function-type-not-expected", "ruleIndex" : 0, @@ -228,7 +284,7 @@ "index" : 0 }, "message" : { - "text" : "Function call to functionCallThatUsesFunctionPointer may use a function pointer (& ...) with an unexpected return type: int expected: void" + "text" : "Function [call to functionCallThatUsesFunctionPointer](1) may use a function pointer [& ...](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments ()}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{int}} with arguments ()}}](5) (1 arguments)." }, "locations" : [ { "physicalLocation" : { @@ -238,7 +294,7 @@ "index" : 0 }, "region" : { - "startLine" : 56, + "startLine" : 89, "startColumn" : 5, "endColumn" : 40 } @@ -247,18 +303,9 @@ "partialFingerprints" : { "primaryLocationLineHash" : "b16f3331cfb3f2dd:1", "primaryLocationStartColumnFingerprint" : "0" - } - }, { - "ruleId" : "cpp/drivers/routine-function-type-not-expected", - "ruleIndex" : 0, - "rule" : { - "id" : "cpp/drivers/routine-function-type-not-expected", - "index" : 0 - }, - "message" : { - "text" : "Function call to functionCallThatUsesFunctionPointer may use a function pointer (intFunctionToCall) with an unexpected return type: int expected: void" }, - "locations" : [ { + "relatedLocations" : [ { + "id" : 1, "physicalLocation" : { "artifactLocation" : { "uri" : "driver/driver_snippet.c", @@ -266,16 +313,83 @@ "index" : 0 }, "region" : { - "startLine" : 59, + "startLine" : 89, "startColumn" : 5, "endColumn" : 40 } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer" } - } ], - "partialFingerprints" : { - "primaryLocationLineHash" : "8a5840d23f7ece01:1", - "primaryLocationStartColumnFingerprint" : "0" - } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 89, + "startColumn" : 41, + "endColumn" : 59 + } + }, + "message" : { + "text" : "& ..." + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 89, + "startColumn" : 41, + "endColumn" : 59 + } + }, + "message" : { + "text" : "pointer to {{function returning {{int}} with arguments ()}}" + } + } ] }, { "ruleId" : "cpp/drivers/routine-function-type-not-expected", "ruleIndex" : 0, @@ -284,7 +398,7 @@ "index" : 0 }, "message" : { - "text" : "Function call to functionCallThatUsesFunctionPointer2 may use a function pointer (intFunctionToCall) with an unexpected return type: int expected: void" + "text" : "Function [call to functionCallThatUsesFunctionPointer](1) may use a function pointer [intFunctionToCall](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments ()}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{int}} with arguments ()}}](5) (1 arguments)." }, "locations" : [ { "physicalLocation" : { @@ -294,20 +408,448 @@ "index" : 0 }, "region" : { - "startLine" : 61, + "startLine" : 92, "startColumn" : 5, - "endColumn" : 41 + "endColumn" : 40 } } } ], "partialFingerprints" : { - "primaryLocationLineHash" : "b2e192116459028c:1", + "primaryLocationLineHash" : "3156b91ec348a1bb:1", "primaryLocationStartColumnFingerprint" : "0" - } + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 92, + "startColumn" : 5, + "endColumn" : 40 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 92, + "startColumn" : 41, + "endColumn" : 58 + } + }, + "message" : { + "text" : "intFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 50, + "startColumn" : 51, + "endColumn" : 66 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 92, + "startColumn" : 41, + "endColumn" : 58 + } + }, + "message" : { + "text" : "pointer to {{function returning {{int}} with arguments ()}}" + } + } ] + }, { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function [call to functionCallThatUsesFunctionPointer2](1) may use a function pointer [intFunctionToCall](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments ()}}](4) (3 parameters). Actual argument: [pointer to {{function returning {{int}} with arguments ()}}](5) (3 arguments)." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 5, + "endColumn" : 41 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "b2e192116459028c:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 5, + "endColumn" : 41 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer2" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 47, + "endColumn" : 64 + } + }, + "message" : { + "text" : "intFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 55, + "startColumn" : 60, + "endColumn" : 75 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 55, + "startColumn" : 60, + "endColumn" : 75 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 96, + "startColumn" : 47, + "endColumn" : 64 + } + }, + "message" : { + "text" : "pointer to {{function returning {{int}} with arguments ()}}" + } + } ] + }, { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function [call to functionCallThatUsesFunctionPointer3](1) may use a function pointer [f1](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments (int,signed char,long)}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{void}} with arguments ()}}](5) (1 arguments)." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 102, + "startColumn" : 5, + "endColumn" : 41 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "a136406d3848a7ab:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 102, + "startColumn" : 5, + "endColumn" : 41 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer3" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 102, + "startColumn" : 42, + "endColumn" : 44 + } + }, + "message" : { + "text" : "f1" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 53, + "endColumn" : 68 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 53, + "endColumn" : 68 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments (int,signed char,long)}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 102, + "startColumn" : 42, + "endColumn" : 44 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + } ] + }, { + "ruleId" : "cpp/drivers/routine-function-type-not-expected", + "ruleIndex" : 0, + "rule" : { + "id" : "cpp/drivers/routine-function-type-not-expected", + "index" : 0 + }, + "message" : { + "text" : "Function [call to functionCallThatUsesFunctionPointer3](1) may use a function pointer [voidFunctionToCall](2) for parameter [functionPointer](3) with an unexpected return type or parameter type. Expected formal parameter is: [pointer to {{function returning {{void}} with arguments (int,signed char,long)}}](4) (1 parameters). Actual argument: [pointer to {{function returning {{void}} with arguments ()}}](5) (1 arguments)." + }, + "locations" : [ { + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 5, + "endColumn" : 41 + } + } + } ], + "partialFingerprints" : { + "primaryLocationLineHash" : "69e17f41c5580c20:1", + "primaryLocationStartColumnFingerprint" : "0" + }, + "relatedLocations" : [ { + "id" : 1, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 5, + "endColumn" : 41 + } + }, + "message" : { + "text" : "call to functionCallThatUsesFunctionPointer3" + } + }, { + "id" : 2, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 42, + "endColumn" : 60 + } + }, + "message" : { + "text" : "voidFunctionToCall" + } + }, { + "id" : 3, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 53, + "endColumn" : 68 + } + }, + "message" : { + "text" : "functionPointer" + } + }, { + "id" : 4, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 66, + "startColumn" : 53, + "endColumn" : 68 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments (int,signed char,long)}}" + } + }, { + "id" : 5, + "physicalLocation" : { + "artifactLocation" : { + "uri" : "driver/driver_snippet.c", + "uriBaseId" : "%SRCROOT%", + "index" : 0 + }, + "region" : { + "startLine" : 105, + "startColumn" : 42, + "endColumn" : 60 + } + }, + "message" : { + "text" : "pointer to {{function returning {{void}} with arguments ()}}" + } + } ] } ], "columnKind" : "utf16CodeUnits", "properties" : { "semmle.formatSpecifier" : "sarifv2.1.0" } } ] -} \ No newline at end of file +} diff --git a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c index be558b52..b85a9675 100644 --- a/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c +++ b/src/drivers/general/queries/RoutineFunctionTypeNotExpected/driver_snippet.c @@ -11,22 +11,38 @@ void top_level_call() {} typedef void functionCall1(void); - typedef functionCall1 *funcCall; +// Typedef to use for testing function pointer parameter type mismatches +typedef void +functionCall2(int a, char b, long c); +typedef functionCall2 *funcCall2; + typedef int functionCallInt(void); - typedef functionCallInt *funcCallInt; +typedef long +functionCallLong(void); +typedef functionCallLong *funcCallLong; + void voidFunctionToCall(void) { return; } +void voidFunctionToCallWithParams(int a, char b, long c) +{ + long x = a + b + c; + c = x; // do stuff to get rid of compiler warnings +} int intFunctionToCall(void) { return 0; } +long longFunctionToCall(void) +{ + return 0; +} int (*fun_ptr1)(void) = intFunctionToCall; void (*fun_ptr2)(void) = voidFunctionToCall; @@ -41,22 +57,50 @@ char functionCallThatUsesFunctionPointer2(char a, funcCall functionPointer, char functionPointer(); return a + b; } +char functionCallThatUsesFunctionPointerLong(funcCallLong functionPointer) +{ + functionPointer(); + return 'a'; +} + +void functionCallThatUsesFunctionPointer3(funcCall2 functionPointer) +{ + functionPointer(1, 'b', 3); + return; +} void callFunctionCallThatUsesFunctionPointer(void) { funcCall f1 = &voidFunctionToCall; + funcCall2 f_with_params = &voidFunctionToCallWithParams; + + funcCall2 f_bad_params = &voidFunctionToCall; // NOTE the compiler warns about this because voidFunctionToCall has no parameters + funcCall2 f_bad_params2 = (funcCall2)voidFunctionToCall; + funcCall f2 = &intFunctionToCall; // funcCall type specifies a void return type, but this is a function pointer to intFunctionToCall which returns an int funcCallInt f3 = &intFunctionToCall; + functionCallThatUsesFunctionPointer(f1); // pass functionCallThatUsesFunctionPointer(fun_ptr2); // pass - functionCallThatUsesFunctionPointer(fun_ptr1); // fail because fun_ptr1 is a function pointer to intFunctionToCall which returns an int - functionCallThatUsesFunctionPointer(f2); // This SHOULD fail because f2 is a function pointer to intFunctionToCall which returns an int, but it is declared with a funcCall type which specifies a void return type so it passes - functionCallThatUsesFunctionPointer(f3); // fail because f3 is a function pointer to intFunctionToCall which returns an int + functionCallThatUsesFunctionPointer(fun_ptr1); // fail because fun_ptr1 is a function pointer to intFunctionToCall which returns an int + functionCallThatUsesFunctionPointer(f2); // This SHOULD fail because f2 is a function pointer to intFunctionToCall which returns an int, but it is declared with a funcCall type which specifies a void return type so it passes + functionCallThatUsesFunctionPointer(f3); // fail because f3 is a function pointer to intFunctionToCall which returns an int functionCallThatUsesFunctionPointer(&voidFunctionToCall); // pass functionCallThatUsesFunctionPointer(&intFunctionToCall); // fail because this intFunctionToCall returns an int functionCallThatUsesFunctionPointer(voidFunctionToCall); // pass - functionCallThatUsesFunctionPointer(intFunctionToCall); // fail because this intFunctionToCall returns an int + functionCallThatUsesFunctionPointer(intFunctionToCall); // fail because intFunctionToCall returns an int + + functionCallThatUsesFunctionPointerLong((funcCallLong)intFunctionToCall); // should pass because the int type is cast to long type functionCallThatUsesFunctionPointer2('a', intFunctionToCall, 'b'); // fail because this intFunctionToCall returns an int + + // Check both return values and parameters + functionCallThatUsesFunctionPointer3(f_with_params); // pass because voidFunctionToCallWithParams matches the parameters expected by funcCall2 + functionCallThatUsesFunctionPointer3(voidFunctionToCallWithParams); // pass because voidFunctionToCallWithParams matches the parameters expected by funcCall2 + + functionCallThatUsesFunctionPointer3(f1); // fail because voidFunctionToCall has no parameters. NOTE the compiler warns about this + functionCallThatUsesFunctionPointer3(f_bad_params); // pass because voidFunctionToCall f_bad_params is declared with funcCall2 type. The compiler warns about the initial assignemnt of f_bad_params + functionCallThatUsesFunctionPointer3(f_bad_params2); // pass because voidFunctionToCall is cast to funcCall2 type. The compiler does not warn about this and does not warn about the initial assignment of f_bad_params2 because it is cast to a funcCall2 type + functionCallThatUsesFunctionPointer3(voidFunctionToCall); // fail because voidFunctionToCall has no parameters. NOTE the compiler warns about this }