Skip to content

Commit 7415769

Browse files
committed
Merge branch 'main' into rvermeulen/fix-366
2 parents 60179be + 5ff2a10 commit 7415769

File tree

61 files changed

+708
-151
lines changed

Some content is hidden

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

61 files changed

+708
-151
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* `A7-1-1` - no longer report parameters as contravening this rule. This is inline with the rule intent as described in the referenced C++ Core Guidelines rule [CON.1](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#con1-by-default-make-objects-immutable), which states "To avoid confusion and lots of false positives, don’t enforce this rule for function parameters."
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
- `A3-9-1` - `VariableWidthIntegerTypesUsed.ql`:
2+
- Exclude the plain char type. Still includes `signed char` and `unsigned char`.
3+
- Include CV-qualified variable width integer types.
4+
- `A3-9-1` - `VariableWidthPlainCharTypeUsed.ql`:
5+
- New query to support fine grained deviation support for the plain char type.
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: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A2-3-1`: ` cpp/autosar/invalid-character-in-string-literal`
2+
- Fixes #311. Exclude wide string literals and utf8 string literal.
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+
`M9-3-3` - `MemberFunctionConstIfPossible.ql`, `MemberFunctionStaticIfPossible.ql`:
2+
- Fixes #413. Exclude deleted member functions.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
`A8-4-7` - `InParametersForCheapToCopyTypesNotPassedByValue.ql`, `InParametersForNotCheapToCopyTypesNotPassedByReference.ql`:
2+
- Fixes #397. Exclude user defined operators and move constructors.`
3+
- Exclude parameters for instantiated templates because the declaration location of the function does not contain enough information about the type used in the instantiation to make an actionable alert.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A5-0-2` - `NonBooleanIfStmt.qll`, `NonBooleanIterationStmt.qll`:
2+
- Exclude compiler generated conditions.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A13-3-1` - `FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql`:
2+
- Fixes #399. Exclude functions that have different number of parameters.
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: 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+
`M9-3-3`: `MemberFunctionConstIfPossible.ql`:
2+
- Fix FP reported in 467. Excluding candidates in uninstantiated templates.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
`A7-1-1` - `DeclarationUnmodifiedObjectMissingConstSpecifier.ql`
2+
- Fix FP reported in #372. Exclude compiler generated variables.

cpp/autosar/src/rules/A13-3-1/FunctionThatContainsForwardingReferenceAsItsArgumentOverloaded.ql

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,36 @@ class Candidate extends TemplateFunction {
2121
}
2222
}
2323

24-
from Candidate c, Function f
24+
from
25+
Candidate c, Function f, Function overload, Function overloaded, string msg,
26+
string firstMsgSegment
2527
where
2628
not isExcluded(f,
2729
OperatorsPackage::functionThatContainsForwardingReferenceAsItsArgumentOverloadedQuery()) and
2830
not f.isDeleted() and
29-
f = c.getAnOverload()
30-
select f, "Function overloads a $@ with a forwarding reference parameter.", c, "function"
31+
f = c.getAnOverload() and
32+
// allow for overloading with different number of parameters, because there is no
33+
// confusion on what function will be called.
34+
f.getNumberOfParameters() = c.getNumberOfParameters() and
35+
//build a dynamic select statement that guarantees to read that the overloading function is the explicit one
36+
if
37+
(f instanceof CopyConstructor or f instanceof MoveConstructor) and
38+
f.isCompilerGenerated()
39+
then (
40+
(
41+
f instanceof CopyConstructor and
42+
msg = "implicit copy constructor"
43+
or
44+
f instanceof MoveConstructor and
45+
msg = "implicit move constructor"
46+
) and
47+
firstMsgSegment = " with a forwarding reference parameter " and
48+
overloaded = f and
49+
overload = c
50+
) else (
51+
msg = "function with a forwarding reference parameter" and
52+
firstMsgSegment = " " and
53+
overloaded = c and
54+
overload = f
55+
)
56+
select overload, "Function" + firstMsgSegment + "overloads a $@.", overloaded, msg

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-3-1/InvalidCharacterInStringLiteral.ql

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import cpp
1919
import codingstandards.cpp.autosar
20+
import codingstandards.cpp.Literals
2021

2122
bindingset[s]
2223
string getCharOutsideBasicSourceCharSet(string s) {
@@ -27,6 +28,9 @@ string getCharOutsideBasicSourceCharSet(string s) {
2728
from StringLiteral s, string ch
2829
where
2930
not isExcluded(s, NamingPackage::invalidCharacterInStringLiteralQuery()) and
30-
ch = getCharOutsideBasicSourceCharSet(s.getValueText())
31+
ch = getCharOutsideBasicSourceCharSet(s.getValueText()) and
32+
// wide string and utf8 string literals are exempted.
33+
not s instanceof WideStringLiteral and
34+
not s instanceof Utf8StringLiteral
3135
select s,
3236
"String literal uses the character '" + ch + "' that is outside the language basic character set."

cpp/autosar/src/rules/A3-9-1/VariableWidthIntegerTypesUsed.ql

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
/**
22
* @id cpp/autosar/variable-width-integer-types-used
33
* @name A3-9-1: Use fixed-width integer types instead of basic, variable-width, integer types
4-
* @description The basic numerical types of char, int, short, long are not supposed to be used. The
5-
* specific-length types from <cstdint> header need be used instead.
4+
* @description The basic numerical types of signed/unsigned char, int, short, long are not supposed
5+
* to be used. The specific-length types from <cstdint> header need be used instead.
66
* @kind problem
77
* @precision very-high
88
* @problem.severity error
@@ -19,15 +19,16 @@ import cpp
1919
import codingstandards.cpp.autosar
2020
import codingstandards.cpp.EncapsulatingFunctions
2121
import codingstandards.cpp.BuiltInNumericTypes
22+
import codingstandards.cpp.Type
2223

23-
from Variable v
24+
from Variable v, Type typeStrippedOfSpecifiers
2425
where
2526
not isExcluded(v, DeclarationsPackage::variableWidthIntegerTypesUsedQuery()) and
27+
typeStrippedOfSpecifiers = stripSpecifiers(v.getType()) and
2628
(
27-
v.getType() instanceof BuiltInIntegerType or
28-
v.getType() instanceof PlainCharType or
29-
v.getType() instanceof UnsignedCharType or
30-
v.getType() instanceof SignedCharType
29+
typeStrippedOfSpecifiers instanceof BuiltInIntegerType or
30+
typeStrippedOfSpecifiers instanceof UnsignedCharType or
31+
typeStrippedOfSpecifiers instanceof SignedCharType
3132
) and
3233
not v instanceof ExcludedVariable
3334
select v, "Variable '" + v.getName() + "' has variable-width type."
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id cpp/autosar/variable-width-plain-char-type-used
3+
* @name A3-9-1: Use a fixed-width integer type instead of a char type
4+
* @description The basic numerical type char is not supposed to be used. The specific-length types
5+
* from <cstdint> header need be used instead.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/autosar/id/a3-9-1
10+
* correctness
11+
* security
12+
* maintainability
13+
* external/autosar/allocated-target/implementation
14+
* external/autosar/enforcement/automated
15+
* external/autosar/obligation/required
16+
*/
17+
18+
import cpp
19+
import codingstandards.cpp.autosar
20+
import codingstandards.cpp.Type
21+
22+
from Variable variable
23+
where
24+
not isExcluded(variable, DeclarationsPackage::variableWidthPlainCharTypeUsedQuery()) and
25+
stripSpecifiers(variable.getType()) instanceof PlainCharType
26+
select variable, "Variable '" + variable.getName() + "' has variable-width char type."

cpp/autosar/src/rules/A7-1-1/DeclarationUnmodifiedObjectMissingConstSpecifier.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ where
3636
else cond = " is used for an object"
3737
) and
3838
not exists(LambdaExpression lc | lc.getACapture().getField() = v) and
39-
not v.isFromUninstantiatedTemplate(_)
39+
not v.isFromUninstantiatedTemplate(_) and
40+
not v.isCompilerGenerated()
4041
select v, "Non-constant variable " + v.getName() + cond + " and is not modified."

cpp/autosar/src/rules/A7-1-1/DeclarationUnmodifiedParamMissingConstSpecifier.ql

Lines changed: 0 additions & 42 deletions
This file was deleted.

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/A8-4-7/InParametersForCheapToCopyTypesNotPassedByValue.ql

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import cpp
1717
import codingstandards.cpp.autosar
1818
import TriviallySmallType
1919
import codingstandards.cpp.CommonTypes as CommonTypes
20+
import codingstandards.cpp.Class
2021

2122
/*
2223
* For the purposes of this rule, "cheap to copy" is defined as a trivially copyable type that is no
@@ -34,8 +35,10 @@ where
3435
) and
3536
t.isConst() and
3637
not exists(CatchBlock cb | cb.getParameter() = v) and
37-
not exists(CopyConstructor cc | cc.getAParameter() = v) and
38-
not v.isFromUninstantiatedTemplate(_)
38+
not exists(SpecialMemberFunction cc | cc.getAParameter() = v) and
39+
not exists(Operator op | op.getAParameter() = v) and
40+
not v.isFromUninstantiatedTemplate(_) and
41+
not v.isFromTemplateInstantiation(_)
3942
select v,
40-
"Parameter " + v.getName() + " is the trivially copyable type " + t.getName() +
41-
" but it is passed by reference instead of by value."
43+
"Parameter '" + v.getName() + "' is the trivially copyable type '" + t.getName() +
44+
"' but it is passed by reference instead of by value."

0 commit comments

Comments
 (0)