Skip to content

Commit 3734236

Browse files
author
Nicolas Kraiouchkine
authored
Merge pull request #548 from rvermeulen/rvermeulen/fix-152
Fix 152: Adding query for depencence on operator precedence
2 parents b221f4e + a78dd7a commit 3734236

File tree

7 files changed

+100
-0
lines changed

7 files changed

+100
-0
lines changed

.vscode/tasks.json

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@
271271
"Null",
272272
"OperatorInvariants",
273273
"Operators",
274+
"OrderOfEvaluation",
274275
"OutOfBounds",
275276
"Pointers",
276277
"Pointers1",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* @id cpp/autosar/insufficient-use-of-parentheses
3+
* @name M5-0-2: Limited dependence should be placed on C++ operator precedence rules in expressions
4+
* @description The use of parentheses can be used to emphasize precedence and increase code
5+
* readability.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity recommendation
9+
* @tags external/autosar/id/m5-0-2
10+
* external/autosar/audit
11+
* readability
12+
* external/autosar/allocated-target/implementation
13+
* external/autosar/enforcement/partially-automated
14+
* external/autosar/obligation/advisory
15+
*/
16+
17+
import cpp
18+
import codingstandards.cpp.autosar
19+
import semmle.code.cpp.commons.Assertions
20+
21+
class InsufficientlyParenthesizedExpr extends Expr {
22+
InsufficientlyParenthesizedExpr() {
23+
// Exclude expressions affected by macros, including assertions, because
24+
// it is unclear that the expression must be parenthesized since it seems
25+
// to be the top-level expression instead of an operand of a binary or ternary operation.
26+
not this.isAffectedByMacro() and
27+
(
28+
exists(BinaryOperation root, BinaryOperation child | child = this |
29+
root.getAnOperand() = child and
30+
root.getOperator() != child.getOperator() and
31+
not any(ParenthesisExpr pe).getExpr() = child
32+
)
33+
or
34+
exists(ConditionalExpr root, BinaryOperation child | child = this |
35+
root.getAnOperand() = child and
36+
not any(ParenthesisExpr pe).getExpr() = child
37+
)
38+
)
39+
}
40+
}
41+
42+
from InsufficientlyParenthesizedExpr e
43+
where not isExcluded(e, OrderOfEvaluationPackage::insufficientUseOfParenthesesQuery())
44+
select e, "Dependence on operator precedence rules."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
| test.cpp:40:8:40:13 | ... * ... | Dependence on operator precedence rules. |
2+
| test.cpp:41:19:41:24 | ... * ... | Dependence on operator precedence rules. |
3+
| test.cpp:42:8:42:13 | ... * ... | Dependence on operator precedence rules. |
4+
| test.cpp:42:17:42:22 | ... * ... | Dependence on operator precedence rules. |
5+
| test.cpp:48:8:48:15 | ... == ... | Dependence on operator precedence rules. |
6+
| test.cpp:49:26:49:32 | ... - ... | Dependence on operator precedence rules. |
7+
| test.cpp:50:8:50:15 | ... == ... | Dependence on operator precedence rules. |
8+
| test.cpp:50:24:50:30 | ... - ... | Dependence on operator precedence rules. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/M5-0-2/InsufficientUseOfParentheses.ql

cpp/autosar/test/rules/M5-0-2/test.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,21 @@ void f1() {
3131
int **l7;
3232
l1 = (*l7)[l2]; // NON_COMPLIANT[FALSE_NEGATIVE]
3333
char l8 = (char)(l1 + 1); // NON_COMPLIANT[FALSE_NEGATIVE]
34+
}
35+
36+
void test_insufficient_parentheses() {
37+
int l1, l2, l3;
38+
39+
l1 = (2 * l2) + (3 * l3); // COMPLIANT
40+
l1 = 2 * l2 + (3 * l3); // NON_COMPLIANT
41+
l1 = (2 * l2) + 3 * l3; // NON_COMPLIANT
42+
l1 = 2 * l2 + 3 * l3; // NON_COMPLIANT
43+
l1 = (2 * l2) + l3 + 1; // COMPLIANT
44+
l1 = (l2 + 1) - (l2 + l3); // COMPLIANT
45+
l1 = l2 + l3 + 1; // COMPLIANT
46+
47+
l1 = (l2 == l3) ? l2 : (l2 - l3); // COMPLIANT
48+
l1 = l2 == l3 ? l2 : (l2 - l3); // NON_COMPLIANT
49+
l1 = (l2 == l3) ? l2 : l2 - l3; // NON_COMPLIANT
50+
l1 = l2 == l3 ? l2 : l2 - l3; // NON_COMPLIANT
3451
}

cpp/common/src/codingstandards/cpp/exclusions/cpp/OrderOfEvaluation.qll

+17
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ newtype OrderOfEvaluationQuery =
88
TOperandsOfALogicalAndOrNotParenthesizedQuery() or
99
TExplicitConstructionOfUnnamedTemporaryQuery() or
1010
TGratuitousUseOfParenthesesQuery() or
11+
TInsufficientUseOfParenthesesQuery() or
1112
TIncrementAndDecrementOperatorsMixedWithOtherOperatorsInExpressionQuery() or
1213
TAssignmentInSubExpressionQuery()
1314

@@ -50,6 +51,15 @@ predicate isOrderOfEvaluationQueryMetadata(
5051
ruleId = "M5-0-2" and
5152
category = "advisory"
5253
or
54+
query =
55+
// `Query` instance for the `insufficientUseOfParentheses` query
56+
OrderOfEvaluationPackage::insufficientUseOfParenthesesQuery() and
57+
queryId =
58+
// `@id` for the `insufficientUseOfParentheses` query
59+
"cpp/autosar/insufficient-use-of-parentheses" and
60+
ruleId = "M5-0-2" and
61+
category = "advisory"
62+
or
5363
query =
5464
// `Query` instance for the `incrementAndDecrementOperatorsMixedWithOtherOperatorsInExpression` query
5565
OrderOfEvaluationPackage::incrementAndDecrementOperatorsMixedWithOtherOperatorsInExpressionQuery() and
@@ -98,6 +108,13 @@ module OrderOfEvaluationPackage {
98108
TQueryCPP(TOrderOfEvaluationPackageQuery(TGratuitousUseOfParenthesesQuery()))
99109
}
100110

111+
Query insufficientUseOfParenthesesQuery() {
112+
//autogenerate `Query` type
113+
result =
114+
// `Query` type for `insufficientUseOfParentheses` query
115+
TQueryCPP(TOrderOfEvaluationPackageQuery(TInsufficientUseOfParenthesesQuery()))
116+
}
117+
101118
Query incrementAndDecrementOperatorsMixedWithOtherOperatorsInExpressionQuery() {
102119
//autogenerate `Query` type
103120
result =

rule_packages/cpp/OrderOfEvaluation.json

+12
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@
9090
"external/autosar/audit",
9191
"readability"
9292
]
93+
},
94+
{
95+
"description": "The use of parentheses can be used to emphasize precedence and increase code readability.",
96+
"kind": "problem",
97+
"name": "Limited dependence should be placed on C++ operator precedence rules in expressions",
98+
"precision": "medium",
99+
"severity": "recommendation",
100+
"short_name": "InsufficientUseOfParentheses",
101+
"tags": [
102+
"external/autosar/audit",
103+
"readability"
104+
]
93105
}
94106
],
95107
"title": "Limited dependence should be placed on C++ operator precedence rules in expressions."

0 commit comments

Comments
 (0)