Skip to content

Fix deviations through use of deprecated isExcluded predicates #472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions change_notes/2023-12-06-m16-1-1-perf.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
* `M16-1-1`
- Optimize query to improve performance
- Improve detection of macros whose body contains the `defined` operator after the start of the macro (e.g. `#define X Y || defined(Z)`).
- Enable exclusions to be applied for this rule.
2 changes: 2 additions & 0 deletions change_notes/2023-12-07-fix-deviations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* The following queries have been updated to address issues with applying deviations:
- `A18-5-11`, `A23-0-1`, `A9-3-1`, `M0-1-2`, `M3-1-2`, `M3-2-1`, `M3-2-3`, `M3-9-1`, `M4-5-3`, `M5-0-2`, `M5-2-10`, `A23-0-2`, `CTR51-CPP`, `STR52-CPP`
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import codingstandards.cpp.autosar

from MemberFunction operator_new, Class c
where
not isExcluded(operator_new) and
not isExcluded(operator_new,
DeclarationsPackage::operatorNewAndOperatorDeleteNotDefinedLocallyQuery()) and
not isExcluded(c, DeclarationsPackage::operatorNewAndOperatorDeleteNotDefinedLocallyQuery()) and
operator_new.hasName("operator new") and
operator_new.getDeclaringType() = c and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ import codingstandards.cpp.Iterators

from ConstIteratorVariable v, STLContainer c, Expr e
where
not isExcluded(v) and
not isExcluded(e) and
not isExcluded(v, IteratorsPackage::iteratorImplicitlyConvertedToConstIteratorQuery()) and
not isExcluded(e, IteratorsPackage::iteratorImplicitlyConvertedToConstIteratorQuery()) and
e = v.getAnAssignedValue() and
e.getAChild*() = /* see note at top of query */ c.getANonConstIteratorFunctionCall()
select e, "Non-const version of container call immediately converted to a `const_iterator`."
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ class AccessAwareMemberFunction extends MemberFunction {

from Class c, AccessAwareMemberFunction mf, FieldAccess a, ReturnStmt rs
where
not isExcluded(c) and
not isExcluded(c,
ClassesPackage::returnsNonConstRawPointersOrReferencesToPrivateOrProtectedDataQuery()) and
not isExcluded(mf,
ClassesPackage::returnsNonConstRawPointersOrReferencesToPrivateOrProtectedDataQuery()) and
// Find all of the methods within this class
Expand Down
2 changes: 1 addition & 1 deletion cpp/autosar/src/rules/M0-1-2/InfeasiblePath.ql
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,6 @@ predicate hasInfeasiblePath(

from ConditionalControlFlowNode cond, boolean infeasiblePath, string explanation
where
not isExcluded(cond) and
not isExcluded(cond, DeadCodePackage::infeasiblePathQuery()) and
hasInfeasiblePath(cond, infeasiblePath, explanation)
select cond, "The " + infeasiblePath + " path is infeasible because " + explanation + "."
36 changes: 18 additions & 18 deletions cpp/autosar/src/rules/M16-1-1/DefinedMacro.qll
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@ import cpp
import codingstandards.cpp.autosar

/**
* A helper class describing macros wrapping defined operator
* A helper class describing macros wrapping the defined operator
*/
class DefinedMacro extends Macro {
DefinedMacro() {
this.getBody().regexpMatch("defined\\s*\\(.*")
class MacroUsesDefined extends Macro {
MacroUsesDefined() {
// Uses `defined` directly
exists(this.getBody().regexpFind("\\bdefined\\b", _, _))
or
this.getBody().regexpMatch("defined[\\s]+|defined$")
// Uses a macro that uses `defined` (directly or indirectly)
exists(MacroUsesDefined dm | exists(this.getBody().regexpFind(dm.getRegexForMatch(), _, _)))
}

Macro getAUse() {
result = this or
anyAliasing(result, this)
/**
* Gets a regex for matching uses of this macro.
*/
string getRegexForMatch() {
exists(string arguments |
// If there are arguments
if getHead() = getName() then arguments = "" else arguments = "\\s*\\("
|
// Use word boundary matching to find identifiers that match
result = "\\b" + getName() + "\\b" + arguments
)
}
}

predicate directAlias(Macro alias, Macro aliased) {
not alias.getBody() = alias.getBody().replaceAll(aliased.getHead(), "")
}

predicate anyAliasing(Macro alias, Macro inQ) {
directAlias(alias, inQ)
or
exists(Macro intermediate | anyAliasing(intermediate, inQ) and anyAliasing(alias, intermediate))
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,19 @@ import cpp
import codingstandards.cpp.autosar
import DefinedMacro

from DefinedMacro m, PreprocessorBranch e
/**
* An `if` or `elif` preprocessor branch.
*/
class PreprocessorIfOrElif extends PreprocessorBranch {
PreprocessorIfOrElif() {
this instanceof PreprocessorIf or
this instanceof PreprocessorElif
}
}

from PreprocessorIfOrElif e, MacroUsesDefined m
where
(
e instanceof PreprocessorIf or
e instanceof PreprocessorElif
) and
(
e.getHead().regexpMatch(m.getAUse().getHead() + "\\s*\\(.*")
or
e.getHead().regexpMatch(m.getAUse().getHead().replaceAll("(", "\\(").replaceAll(")", "\\)"))
) and
not isExcluded(e)
not isExcluded(e, MacrosPackage::definedPreProcessorOperatorInOneOfTheTwoStandardFormsQuery()) and
// A`#if` or `#elif` which uses a macro which uses `defined`
exists(e.getHead().regexpFind(m.getRegexForMatch(), _, _))
select e, "The macro $@ expands to 'defined'", m, m.getName()
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import codingstandards.cpp.autosar

from DeclStmt decl, Function f
where
not isExcluded(decl) and
not isExcluded(decl, DeclarationsPackage::functionsDeclaredAtBlockScopeQuery()) and
not isExcluded(f, DeclarationsPackage::functionsDeclaredAtBlockScopeQuery()) and
decl.getADeclaration() = f
select f, "Function " + f.getName() + " is declared at block scope."
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import codingstandards.cpp.Typehelpers

from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
where
not isExcluded(f1) and
not isExcluded(f1, DeclarationsPackage::declarationsOfAFunctionShallHaveCompatibleTypesQuery()) and
not isExcluded(f2, DeclarationsPackage::declarationsOfAFunctionShallHaveCompatibleTypesQuery()) and
not f1 = f2 and
f1.getDeclaration() = f2.getDeclaration() and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import codingstandards.cpp.Scope

from DeclarationEntry de, DeclarationEntry otherDeclaration, string kind
where
not isExcluded(de) and
not isExcluded(de, ScopePackage::multipleDeclarationViolationQuery()) and
exists(Declaration d |
de.getDeclaration() = d and
otherDeclaration.getDeclaration() = d and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import codingstandards.cpp.autosar

from VariableDeclarationEntry decl1, VariableDeclarationEntry decl2
where
not isExcluded(decl1) and
not isExcluded(decl1, DeclarationsPackage::typesNotIdenticalInObjectDeclarationsQuery()) and
not isExcluded(decl2, DeclarationsPackage::typesNotIdenticalInObjectDeclarationsQuery()) and
decl1.getDeclaration() = decl2.getDeclaration() and
not decl1.getType() = decl2.getType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import codingstandards.cpp.autosar

from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
where
not isExcluded(f1) and
not isExcluded(f1, DeclarationsPackage::typesNotIdenticalInReturnDeclarationsQuery()) and
not isExcluded(f2, DeclarationsPackage::typesNotIdenticalInReturnDeclarationsQuery()) and
f1.getDeclaration() = f2.getDeclaration() and
not f1.getType() = f2.getType()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import codingstandards.cpp.autosar

from Operation o
where
not isExcluded(o) and
not isExcluded(o, ExpressionsPackage::charUsedAsOperandsToDisallowedBuiltInOperatorsQuery()) and
not (
o instanceof EqualityOperation or
o instanceof BitwiseAndExpr or
Expand Down
2 changes: 1 addition & 1 deletion cpp/autosar/src/rules/M5-0-2/GratuitousUseOfParentheses.ql
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ predicate isGratuitousUseOfParentheses(ParenthesisExpr pe) {

from ParenthesisExpr p
where
not isExcluded(p) and
not isExcluded(p, OrderOfEvaluationPackage::gratuitousUseOfParenthesesQuery()) and
isGratuitousUseOfParentheses(p) and
not p.isInMacroExpansion()
select p, "Gratuitous use of parentheses around $@.", p.getExpr(), p.getExpr().toString()
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import codingstandards.cpp.autosar

from CrementOperation cop, Operation op, string name
where
not isExcluded(cop) and
not isExcluded(cop,
OrderOfEvaluationPackage::incrementAndDecrementOperatorsMixedWithOtherOperatorsInExpressionQuery()) and
not isExcluded(op,
OrderOfEvaluationPackage::incrementAndDecrementOperatorsMixedWithOtherOperatorsInExpressionQuery()) and
op.getAnOperand() = cop and
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
| test.cpp:22:1:22:18 | #if DBLWRAPUSES(X) | The macro $@ expands to 'defined' | test.cpp:18:1:18:22 | #define BADDEF defined | BADDEF |
| test.cpp:22:1:22:18 | #if DBLWRAPUSES(X) | The macro $@ expands to 'defined' | test.cpp:21:1:21:24 | #define DBLWRAPUSES USES | DBLWRAPUSES |
| test.cpp:26:1:26:16 | #if BADDEFTWO(X) | The macro $@ expands to 'defined' | test.cpp:25:1:25:31 | #define BADDEFTWO(X) defined(X) | BADDEFTWO |
| test.cpp:29:1:29:16 | #if BADDEFTWO(Y) | The macro $@ expands to 'defined' | test.cpp:25:1:25:31 | #define BADDEFTWO(X) defined(X) | BADDEFTWO |
| test.cpp:42:1:42:11 | #if WRAPPER | The macro $@ expands to 'defined' | test.cpp:40:1:40:35 | #define WRAPPER X < Y \|\| defined(z) | WRAPPER |
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
| test.cpp:9:1:9:19 | #elif defined X < Y | Use of defined with non-standard form: X < Y. |
| test.cpp:13:1:13:18 | #if defined(X > Y) | Use of defined with non-standard form: X > Y. |
| test.cpp:14:1:14:20 | #elif defined(X < Y) | Use of defined with non-standard form: X < Y. |
| test.cpp:34:1:34:47 | #if defined(X) \|\| defined _Y_ + X && defined(Y) | Use of defined with non-standard form: _Y_ + X. |
| test.cpp:37:1:37:47 | #if defined(X) \|\| defined _Y_ + X && defined(Y) | Use of defined with non-standard form: _Y_ + X. |
8 changes: 8 additions & 0 deletions cpp/autosar/test/rules/M16-1-1/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,18 @@
#if BADDEFTWO(X) // NON_COMPLIANT
#endif

#if BADDEFTWO(Y) // NON_COMPLIANT
#endif

// clang-format off
#if defined (X) || (defined(_Y_)) // COMPLIANT
// clang-format on
#endif

#if defined(X) || defined _Y_ + X && defined(Y) // NON_COMPLIANT
#endif

#define WRAPPER X < Y || defined(z)

#if WRAPPER // NON_COMPLIANT
#endif
10 changes: 0 additions & 10 deletions cpp/common/src/codingstandards/cpp/Exclusions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@ private class ExcludeOutsideSourceLocation extends ExcludedFile {
ExcludeOutsideSourceLocation() { not exists(getRelativePath()) }
}

/** Holds if the element should be excluded. */
predicate isExcluded(Element e) {
e instanceof ExcludedElement
or
e.getFile() instanceof ExcludedFile
or
// Compiler generated
not exists(e.getFile())
}

bindingset[e, query]
predicate isExcluded(Element e, Query query) { isExcluded(e, query, _) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ query predicate problems(
ContainerInvalidationOperation cio, string actionType
) {
not isExcluded(cio, getQuery()) and
not isExcluded(ca) and
not isExcluded(ca, getQuery()) and
// The definition of an invalidation is slightly different
// for references vs iterators -- this check ensures that the conditions
// under which a call should be an invalidator are considered correctly.
Expand Down