From a9c412d9fc2c4034393a4cf8b982d2f7b2f7d6cf Mon Sep 17 00:00:00 2001 From: Mike Fairhurst Date: Tue, 15 Jul 2025 20:57:29 -0700 Subject: [PATCH] Fix bad joins on function names and unnecessarily large relation on integer constant macros --- .../IncompatibleFunctionDeclarations.ql | 26 +++++++++++-------- ...rectlySizedIntegerConstantMacroArgument.ql | 1 + .../CompatibleDeclarationFunctionDefined.ql | 15 +++++------ ...5-7-15-fix-performance-issues-in-2.20.7.md | 4 +++ 4 files changed, 26 insertions(+), 20 deletions(-) create mode 100644 change_notes/2025-7-15-fix-performance-issues-in-2.20.7.md diff --git a/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql b/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql index 8c25fe3350..3811d4e417 100644 --- a/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql +++ b/c/cert/src/rules/DCL40-C/IncompatibleFunctionDeclarations.ql @@ -24,28 +24,32 @@ import codingstandards.c.cert import codingstandards.cpp.types.Compatible import ExternalIdentifiers -predicate interestedInFunctions(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) { +predicate interestedInFunctions( + FunctionDeclarationEntry f1, FunctionDeclarationEntry f2, ExternalIdentifiers d +) { not f1 = f2 and - f1.getDeclaration() = f2.getDeclaration() and - f1.getName() = f2.getName() + d = f1.getDeclaration() and + d = f2.getDeclaration() +} + +predicate interestedInFunctions(FunctionDeclarationEntry f1, FunctionDeclarationEntry f2) { + interestedInFunctions(f1, f2, _) } +module FuncDeclEquiv = + FunctionDeclarationTypeEquivalence; + from ExternalIdentifiers d, FunctionDeclarationEntry f1, FunctionDeclarationEntry f2 where not isExcluded(f1, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and not isExcluded(f2, Declarations2Package::incompatibleFunctionDeclarationsQuery()) and - not f1 = f2 and - f1.getDeclaration() = d and - f2.getDeclaration() = d and - f1.getName() = f2.getName() and + interestedInFunctions(f1, f2, d) and ( //return type check - not FunctionDeclarationTypeEquivalence::equalReturnTypes(f1, - f2) + not FuncDeclEquiv::equalReturnTypes(f1, f2) or //parameter type check - not FunctionDeclarationTypeEquivalence::equalParameterTypes(f1, - f2) + not FuncDeclEquiv::equalParameterTypes(f1, f2) ) and // Apply ordering on start line, trying to avoid the optimiser applying this join too early // in the pipeline diff --git a/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql b/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql index 87c945d6b6..1fe052aaae 100644 --- a/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql +++ b/c/misra/src/rules/RULE-7-5/IncorrectlySizedIntegerConstantMacroArgument.ql @@ -20,6 +20,7 @@ predicate matchesSign(IntegerConstantMacro macro, PossiblyNegativeLiteral litera literal.isNegative() implies macro.isSigned() } +bindingset[literal] predicate matchesSize(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) { literal.getRawValue() <= macro.maxValue() and literal.getRawValue() >= macro.minValue() diff --git a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql index 73abc1e048..e7eba7e42a 100644 --- a/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql +++ b/c/misra/src/rules/RULE-8-4/CompatibleDeclarationFunctionDefined.ql @@ -23,13 +23,14 @@ predicate interestedInFunctions(FunctionDeclarationEntry f1, FunctionDeclaration f1.getDeclaration() instanceof ExternalIdentifiers and f1.isDefinition() and f1.getDeclaration() = f2.getDeclaration() and - // This condition should always hold, but removing it affects join order performance. - f1.getName() = f2.getName() and not f2.isDefinition() and not f1.isFromTemplateInstantiation(_) and not f2.isFromTemplateInstantiation(_) } +module FunDeclEquiv = + FunctionDeclarationTypeEquivalence; + from FunctionDeclarationEntry f1 where not isExcluded(f1, Declarations4Package::compatibleDeclarationFunctionDefinedQuery()) and @@ -44,17 +45,13 @@ where or //or one exists that is close but incompatible in some way exists(FunctionDeclarationEntry f2 | - f1.getName() = f2.getName() and - not f2.isDefinition() and - f2.getDeclaration() = f1.getDeclaration() and + interestedInFunctions(f1, f2) and ( //return types differ - not FunctionDeclarationTypeEquivalence::equalReturnTypes(f1, - f2) + not FunDeclEquiv::equalReturnTypes(f1, f2) or //parameter types differ - not FunctionDeclarationTypeEquivalence::equalParameterTypes(f1, - f2) + not FunDeclEquiv::equalParameterTypes(f1, f2) or //parameter names differ parameterNamesUnmatched(f1, f2) diff --git a/change_notes/2025-7-15-fix-performance-issues-in-2.20.7.md b/change_notes/2025-7-15-fix-performance-issues-in-2.20.7.md new file mode 100644 index 0000000000..a936579a97 --- /dev/null +++ b/change_notes/2025-7-15-fix-performance-issues-in-2.20.7.md @@ -0,0 +1,4 @@ + - `DCL40-C`, `RULE-8-4`: `IncompatibleFunctionDeclarations.ql`, `CompatibleDeclarationFunctionDefined.ql`. + - Fixed performance issues introduced when upgrading to CodeQL `2.20.7` by removing unnecessary check that matching function declarations have matching names. + - `RULE-7-5`: `IncorrectlySizedIntegerConstantMacroArgument.ql`. + - Added a `bindingset` to improve performance when checking if a literal matches the size of an integer constant macro. \ No newline at end of file