Skip to content

Commit 4225420

Browse files
committed
Merge branch 'main' into rvermeulen/fix-issue-#311
2 parents ad26759 + 7693a3c commit 4225420

File tree

68 files changed

+1062
-243
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+1062
-243
lines changed

.vscode/tasks.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,28 @@
140140
},
141141
"problemMatcher": []
142142
},
143+
{
144+
"label": "🧪 Standards Automation: Build Case Test DB from test file",
145+
"type": "shell",
146+
"windows": {
147+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}Scripts${pathSeparator}python.exe scripts${pathSeparator}build_test_database.py ${file}"
148+
},
149+
"linux": {
150+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}bin${pathSeparator}python3 scripts${pathSeparator}build_test_database.py ${file}"
151+
},
152+
"osx": {
153+
"command": ".${pathSeparator}scripts${pathSeparator}.venv${pathSeparator}bin${pathSeparator}python3 scripts${pathSeparator}build_test_database.py ${file}"
154+
},
155+
"presentation": {
156+
"reveal": "always",
157+
"panel": "new",
158+
"focus": true
159+
},
160+
"runOptions": {
161+
"reevaluateOnRerun": false
162+
},
163+
"problemMatcher": []
164+
},
143165
{
144166
"label": "📝 Standards Automation: Format CodeQL",
145167
"type": "shell",
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`M8-5-2` - `AggregateLiteralEnhancements.qll`:
2+
- recognise aggregate literals initialized with parameters from variadic templates.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- `A2-10-1`, `RULE-5-3`:
2+
- Reduce false positives by considering point of declaration for local variables.
3+
- Reduce false negatives by considering catch block parameters to be in scope in the catch block.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
- `M6-5-5`:
2+
- Reduce false positives by no longer considering the taking of a const reference as a modification.
3+
- Improve detection of non-local modification of loop iteration variables to reduce false positives.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
* `A2-7-3` - `UndocumentedUserDefinedType.ql`:
2+
- Excluding declarations in function scope. The rationale is that these declarations are not exposed outside the scope of the function.
3+
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`M5-3-3` - `UnaryOperatorOverloaded.ql`:
2+
- Exclude binary user defined `operator&` from this rule.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`M5-2-10` - `IncrementAndDecrementOperatorsMixedWithOtherOperatorsInExpression.ql`:
2+
- only report use of the increment and decrement operations in conjunction with arithmetic operators, as specified by the rule. Notably we no longer report the expressions of the form `*p++`, which combine increment and dereferencing operations.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* `A4-7-1` - exclude pointer increment and decrement operators from this rule.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
* Exceptions are no longer propagated from calls to `noexcept` functions, or calls functions with dynamic exception specifications where the exception is not permitted. This is consistent with the default behaviour specified in `[expect.spec]` which indicates that `std::terminate` is called. This has the following impact:
2+
- `A15-4-2`, `ERR55-CPP` - reduce false positives for `noexcept` functions which call other `noexcept` function which may throw.
3+
- `A15-2-2` - reduce false positives for constructors which call `noexcept` functions.
4+
- `A15-4-5` - reduce false positives for checked exceptions that are thrown from `noexcept` functions called by the original function.
5+
- `DCL57-CPP` - do not report exceptions thrown from `noexcept` functions called by deallocation functions or destructors.
6+
- `A15-5-1`, `M15-3-1` - do not report exceptions thrown from `noexcept` functions called by special functions.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A4-7-1`: `IntegerExpressionLeadToDataLoss.ql`
2+
- Fix #368: Incorrectly reporting `/=` as a cause for data loss.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A16-0-1` - `PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql`:
2+
- Exclude all preprocessor elses and also consider elifs separately (ie do not affect valid ifs) but not valid if not meeting the same criteria as an ifdef etc.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
`A4-5-1`: `EnumUsedInArithmeticContexts.ql`:
2+
- Address incorrect exclusion of the binary operator `&`.
3+
- Address incorrect inclusion of the unary operator `&`.
4+
- Fix FP reported in #366.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A7-1-2` - `VariableMissingConstexpr.ql`:
2+
- Fix FP reported in #466. Addresses incorrect assumption that calls to `constexpr` functions are always compile-time evaluated.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `A2-10-4` - `IdentifierNameOfStaticNonMemberObjectReusedInNamespace.ql`:
2+
- Fix FP reported in #385. Addresses incorrect detection of partially specialized template variables as conflicting reuses.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- `M7-3-6` - `UsingDeclarationsUsedInHeaderFiles.ql`:
2+
- Address FN reported in #400. Only using-declarations are exempted from class- and function-scope.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-`A15-4-4` - `MissingNoExcept.ql`:
2+
- Fix FP reported in #424. Exclude functions calling `std::string::reserve` or `std::string::append` that may throw even if their signatures don't specify it.

cpp/autosar/src/rules/A16-0-1/PreProcessorShallOnlyBeUsedForCertainDirectivesPatterns.ql

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,26 @@ import cpp
2121
import codingstandards.cpp.autosar
2222
import codingstandards.cpp.FunctionLikeMacro
2323

24+
class PermittedInnerDirectiveType extends PreprocessorDirective {
25+
PermittedInnerDirectiveType() {
26+
//permissive listing for directives that can be used in a valid wrapper
27+
this instanceof MacroWrapper or
28+
this instanceof PreprocessorEndif or
29+
this instanceof Include or
30+
this instanceof PermittedMacro or
31+
this instanceof PreprocessorElif or
32+
this instanceof PreprocessorElse
33+
}
34+
}
35+
2436
class PermittedDirectiveType extends PreprocessorDirective {
2537
PermittedDirectiveType() {
2638
//permissive listing in case directive types modelled in ql ever expands (example non valid directives)
2739
this instanceof MacroWrapper or
2840
this instanceof PreprocessorEndif or
2941
this instanceof Include or
30-
this instanceof PermittedMacro
42+
this instanceof PermittedMacro or
43+
this instanceof PreprocessorElse
3144
}
3245
}
3346

@@ -40,9 +53,9 @@ pragma[noinline]
4053
predicate isPreprocConditionalRange(
4154
PreprocessorBranch pb, string filepath, int startLine, int endLine
4255
) {
43-
exists(PreprocessorEndif end | pb.getEndIf() = end |
44-
isPreprocFileAndLine(pb, filepath, startLine) and
45-
isPreprocFileAndLine(end, filepath, endLine)
56+
isPreprocFileAndLine(pb, filepath, startLine) and
57+
exists(PreprocessorDirective end |
58+
pb.getNext() = end and isPreprocFileAndLine(end, filepath, endLine)
4659
)
4760
}
4861

@@ -73,7 +86,7 @@ class MacroWrapper extends PreprocessorIfndef {
7386
class AcceptableWrapper extends PreprocessorBranch {
7487
AcceptableWrapper() {
7588
forall(Element inner | not inner instanceof Comment and this = getAGuard(inner) |
76-
inner instanceof PermittedDirectiveType
89+
inner instanceof PermittedInnerDirectiveType
7790
)
7891
}
7992
}

cpp/autosar/src/rules/A2-10-4/IdentifierNameOfStaticNonMemberObjectReusedInNamespace.ql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ class CandidateVariable extends Variable {
2020
CandidateVariable() {
2121
hasDefinition() and
2222
isStatic() and
23-
not this instanceof MemberVariable
23+
not this instanceof MemberVariable and
24+
//exclude partially specialized template variables
25+
not exists(TemplateVariable v | this = v.getAnInstantiation())
2426
}
2527
}
2628

cpp/autosar/src/rules/A2-7-3/UndocumentedUserDefinedType.ql

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,14 @@
1717
import cpp
1818
import codingstandards.cpp.autosar
1919

20+
private predicate isInFunctionScope(Declaration d) {
21+
// Type declared in function
22+
exists(d.(UserType).getEnclosingFunction())
23+
or
24+
// Member declared in type which is in function scope
25+
isInFunctionScope(d.getDeclaringType())
26+
}
27+
2028
/**
2129
* A declaration which is required to be preceded by documentation by AUTOSAR A2-7-3.
2230
*/
@@ -42,10 +50,8 @@ class DocumentableDeclaration extends Declaration {
4250
declarationType = "member variable" and
4351
// Exclude memeber variables in instantiated templates, which cannot reasonably be documented.
4452
not this.(MemberVariable).isFromTemplateInstantiation(_) and
45-
// Exclude anonymous lambda functions.
46-
// TODO: replace with the following when support is added.
47-
// not this.(MemberVariable).isCompilerGenerated()
48-
not exists(LambdaExpression lc | lc.getACapture().getField() = this)
53+
// Exclude compiler generated variables, such as those for anonymous lambda functions
54+
not this.(MemberVariable).isCompilerGenerated()
4955
}
5056

5157
/** Gets a `DeclarationEntry` for this declaration that should be documented. */
@@ -96,6 +102,7 @@ from DocumentableDeclaration d, DeclarationEntry de
96102
where
97103
not isExcluded(de, CommentsPackage::undocumentedUserDefinedTypeQuery()) and
98104
not isExcluded(d, CommentsPackage::undocumentedUserDefinedTypeQuery()) and
105+
not isInFunctionScope(d) and
99106
d.getAnUndocumentedDeclarationEntry() = de
100107
select de,
101108
"Declaration entry for " + d.getDeclarationType() + " " + d.getName() +

cpp/autosar/src/rules/A4-5-1/EnumUsedInArithmeticContexts.ql

Lines changed: 17 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -18,44 +18,26 @@
1818

1919
import cpp
2020
import codingstandards.cpp.autosar
21+
import codingstandards.cpp.Operator
22+
import codingstandards.cpp.Type
2123

22-
/*
23-
* Get an operand to all overloaded operator member functions, except:
24-
* operator[]
25-
* operator=
26-
* operator==
27-
* operator!=
28-
* operator&
29-
* operator<
30-
* operator<=
31-
* operator>
32-
* operator>=
33-
*/
34-
35-
Expr getAnOperandOfAllowedOverloadedOperator(FunctionCall fc) {
36-
fc.getAnArgument() = result and
37-
fc.getTarget().getName().regexpMatch("operator(?!\\[]$|=$|==$|!=$|&$|<$|<=$|>$|>=$).+")
38-
}
39-
40-
Expr getAnOperandOfAllowedOperation(Operation o) {
41-
o.getAnOperand() = result and
42-
not (
43-
o instanceof AssignExpr or
44-
o instanceof BitwiseAndExpr or
45-
o instanceof ComparisonOperation
46-
)
24+
class AllowedOperatorUse extends OperatorUse {
25+
AllowedOperatorUse() {
26+
this.getOperator() in ["[]", "=", "==", "!=", "<", "<=", ">", ">="]
27+
or
28+
this.(UnaryOperatorUse).getOperator() = "&"
29+
}
4730
}
4831

49-
from Expr e, Expr operand
32+
from OperatorUse operatorUse, Access access, Enum enum
5033
where
51-
not isExcluded(e, ExpressionsPackage::enumUsedInArithmeticContextsQuery()) and
34+
not isExcluded(access, ExpressionsPackage::enumUsedInArithmeticContextsQuery()) and
35+
operatorUse.getAnOperand() = access and
5236
(
53-
operand = getAnOperandOfAllowedOverloadedOperator(e)
54-
or
55-
operand = getAnOperandOfAllowedOperation(e)
37+
access.(EnumConstantAccess).getTarget().getDeclaringEnum() = enum or
38+
access.(VariableAccess).getType() = enum
5639
) and
57-
(
58-
operand instanceof EnumConstantAccess or
59-
operand.(VariableAccess).getType() instanceof Enum
60-
)
61-
select e, "Enum $@ is used as an operand of arithmetic operation.", operand, "expression"
40+
not operatorUse instanceof AllowedOperatorUse and
41+
// Enums that implement the BitmaskType trait are an exception.
42+
not enum instanceof BitmaskType
43+
select access, "Enum $@ is used as an operand of arithmetic operation.", enum, enum.getName()

cpp/autosar/src/rules/A4-7-1/IntegerExpressionLeadToDataLoss.ql

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,7 @@ where
3030
not e instanceof MulExpr and
3131
// Not covered by this query - overflow/underflow in division is rare
3232
not e instanceof DivExpr and
33-
not e instanceof RemExpr
33+
not e instanceof AssignDivExpr and
34+
not e instanceof RemExpr and
35+
not e instanceof AssignRemExpr
3436
select e, "Binary expression ..." + e.getOperator() + "... may overflow."

cpp/autosar/src/rules/A7-1-2/VariableMissingConstexpr.ql

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import cpp
1717
import codingstandards.cpp.autosar
1818
import codingstandards.cpp.TrivialType
1919
import codingstandards.cpp.SideEffect
20+
import semmle.code.cpp.controlflow.SSA
2021

2122
predicate isZeroInitializable(Variable v) {
2223
not exists(v.getInitializer().getExpr()) and
@@ -33,6 +34,78 @@ predicate isTypeZeroInitializable(Type t) {
3334
t.getUnderlyingType() instanceof ArrayType
3435
}
3536

37+
/**
38+
* An optimized set of expressions used to determine the flow through constexpr variables.
39+
*/
40+
class VariableAccessOrCallOrLiteral extends Expr {
41+
VariableAccessOrCallOrLiteral() {
42+
this instanceof VariableAccess or
43+
this instanceof Call or
44+
this instanceof Literal
45+
}
46+
}
47+
48+
/**
49+
* Holds if the value of source flows through compile time evaluated variables to target.
50+
*/
51+
predicate flowsThroughConstExprVariables(
52+
VariableAccessOrCallOrLiteral source, VariableAccessOrCallOrLiteral target
53+
) {
54+
(
55+
source = target
56+
or
57+
source != target and
58+
exists(SsaDefinition intermediateDef, StackVariable intermediate |
59+
intermediateDef.getAVariable().getFunction() = source.getEnclosingFunction() and
60+
intermediateDef.getAVariable().getFunction() = target.getEnclosingFunction() and
61+
intermediateDef.getAVariable() = intermediate and
62+
intermediate.isConstexpr()
63+
|
64+
DataFlow::localExprFlow(source, intermediateDef.getDefiningValue(intermediate)) and
65+
flowsThroughConstExprVariables(intermediateDef.getAUse(intermediate), target)
66+
)
67+
)
68+
}
69+
70+
/*
71+
* Returns true if the given call may be evaluated at compile time and is compile time evaluated because
72+
* all its arguments are compile time evaluated and its default values are compile time evaluated.
73+
*/
74+
75+
predicate isCompileTimeEvaluated(Call call) {
76+
// 1. The call may be evaluated at compile time, because it is constexpr, and
77+
call.getTarget().isConstexpr() and
78+
// 2. all its arguments are compile time evaluated, and
79+
forall(DataFlow::Node ultimateArgSource, DataFlow::Node argSource |
80+
argSource = DataFlow::exprNode(call.getAnArgument()) and
81+
DataFlow::localFlow(ultimateArgSource, argSource) and
82+
not DataFlow::localFlowStep(_, ultimateArgSource)
83+
|
84+
(
85+
ultimateArgSource.asExpr() instanceof Literal
86+
or
87+
any(Call c | isCompileTimeEvaluated(c)) = ultimateArgSource.asExpr()
88+
) and
89+
// If the ultimate argument source is not the same as the argument source, then it must flow through
90+
// constexpr variables.
91+
(
92+
ultimateArgSource != argSource
93+
implies
94+
flowsThroughConstExprVariables(ultimateArgSource.asExpr(), argSource.asExpr())
95+
)
96+
) and
97+
// 3. all the default values used are compile time evaluated.
98+
forall(Expr defaultValue, Parameter parameterUsingDefaultValue, int idx |
99+
parameterUsingDefaultValue = call.getTarget().getParameter(idx) and
100+
not exists(call.getArgument(idx)) and
101+
parameterUsingDefaultValue.getAnAssignedValue() = defaultValue
102+
|
103+
defaultValue instanceof Literal
104+
or
105+
any(Call c | isCompileTimeEvaluated(c)) = defaultValue
106+
)
107+
}
108+
36109
from Variable v
37110
where
38111
not isExcluded(v, ConstPackage::variableMissingConstexprQuery()) and
@@ -46,7 +119,7 @@ where
46119
(
47120
v.getInitializer().getExpr().isConstant()
48121
or
49-
v.getInitializer().getExpr().(Call).getTarget().isConstexpr()
122+
any(Call call | isCompileTimeEvaluated(call)) = v.getInitializer().getExpr()
50123
or
51124
isZeroInitializable(v)
52125
or

cpp/autosar/src/rules/M3-9-1/TypesNotIdenticalInReturnDeclarations.ql

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515

1616
import cpp
1717
import codingstandards.cpp.autosar
18-
import cpp
19-
import codingstandards.cpp.autosar
2018

2119
from FunctionDeclarationEntry f1, FunctionDeclarationEntry f2
2220
where

cpp/autosar/src/rules/M5-2-10/IncrementAndDecrementOperatorsMixedWithOtherOperatorsInExpression.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@
1616

1717
import cpp
1818
import codingstandards.cpp.autosar
19+
import codingstandards.cpp.Expr
1920

20-
from CrementOperation cop, Operation op, string name
21+
from CrementOperation cop, ArithmeticOperation op, string name
2122
where
2223
not isExcluded(cop) and
2324
not isExcluded(op,

cpp/autosar/src/rules/M5-3-3/UnaryOperatorOverloaded.ql

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313

1414
import cpp
1515
import codingstandards.cpp.autosar
16+
import codingstandards.cpp.Operator
1617

17-
from Operator o
18-
where not isExcluded(o, OperatorsPackage::unaryOperatorOverloadedQuery()) and o.hasName("operator&")
18+
from UnaryAddressOfOperator o
19+
where not isExcluded(o, OperatorsPackage::unaryOperatorOverloadedQuery())
1920
select o, "The unary & operator overloaded."

0 commit comments

Comments
 (0)