Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3d7f0fa

Browse files
Merge pull request#987 from github/michaelrfairhurst/preconditions-rule-22-4-1-literal-value-0-errno
Implement Rule 22-4-1, only assign literal 0 to errno.
2 parentsb0d2c22 +0d3a06e commit3d7f0fa

File tree

11 files changed

+270
-1
lines changed

11 files changed

+270
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtypePreconditions4Query=TInvalidAssignmentToErrnoQuery()
7+
8+
predicateisPreconditions4QueryMetadata(Queryquery,stringqueryId,stringruleId,stringcategory){
9+
query=
10+
// `Query` instance for the `invalidAssignmentToErrno` query
11+
Preconditions4Package::invalidAssignmentToErrnoQuery()and
12+
queryId=
13+
// `@id` for the `invalidAssignmentToErrno` query
14+
"cpp/misra/invalid-assignment-to-errno"and
15+
ruleId="RULE-22-4-1"and
16+
category="required"
17+
}
18+
19+
module Preconditions4Package{
20+
QueryinvalidAssignmentToErrnoQuery(){
21+
//autogenerate `Query` type
22+
result=
23+
// `Query` type for `invalidAssignmentToErrno` query
24+
TQueryCPP(TPreconditions4PackageQuery(TInvalidAssignmentToErrnoQuery()))
25+
}
26+
}

‎cpp/common/src/codingstandards/cpp/exclusions/cpp/RuleMetadata.qll‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import OrderOfEvaluation
4545
import OutOfBounds
4646
import Pointers
4747
import Preconditions1
48+
import Preconditions4
4849
import Representation
4950
import Scope
5051
import SideEffects1
@@ -105,6 +106,7 @@ newtype TCPPQuery =
105106
TOutOfBoundsPackageQuery(OutOfBoundsQueryq)or
106107
TPointersPackageQuery(PointersQueryq)or
107108
TPreconditions1PackageQuery(Preconditions1Queryq)or
109+
TPreconditions4PackageQuery(Preconditions4Queryq)or
108110
TRepresentationPackageQuery(RepresentationQueryq)or
109111
TScopePackageQuery(ScopeQueryq)or
110112
TSideEffects1PackageQuery(SideEffects1Queryq)or
@@ -165,6 +167,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
165167
isOutOfBoundsQueryMetadata(query,queryId,ruleId,category)or
166168
isPointersQueryMetadata(query,queryId,ruleId,category)or
167169
isPreconditions1QueryMetadata(query,queryId,ruleId,category)or
170+
isPreconditions4QueryMetadata(query,queryId,ruleId,category)or
168171
isRepresentationQueryMetadata(query,queryId,ruleId,category)or
169172
isScopeQueryMetadata(query,queryId,ruleId,category)or
170173
isSideEffects1QueryMetadata(query,queryId,ruleId,category)or
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import cpp
2+
3+
predicateisErrno(VariableAccessva){
4+
va.getTarget().hasName("errno")or
5+
va.getTarget().hasName("__errno")
6+
}

‎cpp/common/test/includes/standard-library/errno.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
#define_GHLIBCPP_ERRNO
33
int__errno;
44
#defineerrno __errno
5+
#defineEINVAL 22
6+
#defineERANGE 34
7+
#defineEDOM 33
58
#endif// _GHLIBCPP_ERRNO

‎cpp/common/test/includes/standard-library/string‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,8 @@ public:
248248
int compare(size_type pos1, size_type n1, const charT *s) const;
249249
int compare(size_type pos1, size_type n1, const charT *s, size_type n2) const;
250250

251+
bool empty() const noexcept;
252+
251253
void reserve(size_type new_cap = 0);
252254
};
253255

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
* @id cpp/misra/invalid-assignment-to-errno
3+
* @name RULE-22-4-1: The literal value zero shall be the only value assigned to errno
4+
* @description C++ provides better options for error handling than the use of errno. Errno should
5+
* not be used for reporting errors within project code.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-22-4-1
10+
* scope/single-translation-unit
11+
* maintainability
12+
* external/misra/enforcement/decidable
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.misra
18+
import codingstandards.cpp.standardlibrary.Errno
19+
import codingstandards.cpp.Literals
20+
21+
fromAssignmentassign,VariableAccesserrno,Exprrvalue,stringmessage
22+
where
23+
notisExcluded(assign, Preconditions4Package::invalidAssignmentToErrnoQuery())and
24+
assign.getLValue()=errnoand
25+
isErrno(errno)and
26+
assign.getRValue().getExplicitlyConverted()=rvalueand
27+
(
28+
notrvalueinstanceofLiteralZeroand
29+
message=
30+
"Assignment to 'errno' with value '"+rvalue.toString()+
31+
"' that is not a zero integer literal."
32+
or
33+
assigninstanceofAssignOperationand
34+
message=
35+
"Compound assignment to 'errno' with operator '"+assign.getOperator()+"' is not allowed."
36+
)
37+
selectassign,message
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
| test.cpp:26:3:26:13 | ... = ... | Assignment to 'errno' with value '0.0' that is not a zero integer literal. |
2+
| test.cpp:27:3:27:14 | ... = ... | Assignment to 'errno' with value '0.0' that is not a zero integer literal. |
3+
| test.cpp:31:3:31:11 | ... = ... | Assignment to 'errno' with value '1' that is not a zero integer literal. |
4+
| test.cpp:32:3:32:12 | ... = ... | Assignment to 'errno' with value '42' that is not a zero integer literal. |
5+
| test.cpp:33:3:33:12 | ... = ... | Assignment to 'errno' with value '- ...' that is not a zero integer literal. |
6+
| test.cpp:39:3:39:22 | ... = ... | Assignment to 'errno' with value '42' that is not a zero integer literal. |
7+
| test.cpp:49:3:49:12 | ... = ... | Assignment to 'errno' with value 'l1' that is not a zero integer literal. |
8+
| test.cpp:50:3:50:12 | ... = ... | Assignment to 'errno' with value 'l2' that is not a zero integer literal. |
9+
| test.cpp:51:3:51:12 | ... = ... | Assignment to 'errno' with value 'l3' that is not a zero integer literal. |
10+
| test.cpp:52:3:52:12 | ... = ... | Assignment to 'errno' with value 'l4' that is not a zero integer literal. |
11+
| test.cpp:53:3:53:12 | ... = ... | Assignment to 'errno' with value 'l5' that is not a zero integer literal. |
12+
| test.cpp:57:3:57:16 | ... = ... | Assignment to 'errno' with value '22' that is not a zero integer literal. |
13+
| test.cpp:58:3:58:16 | ... = ... | Assignment to 'errno' with value '34' that is not a zero integer literal. |
14+
| test.cpp:59:3:59:14 | ... = ... | Assignment to 'errno' with value '33' that is not a zero integer literal. |
15+
| test.cpp:63:3:63:15 | ... = ... | Assignment to 'errno' with value '... + ...' that is not a zero integer literal. |
16+
| test.cpp:64:3:64:15 | ... = ... | Assignment to 'errno' with value '... - ...' that is not a zero integer literal. |
17+
| test.cpp:65:3:65:15 | ... = ... | Assignment to 'errno' with value '... * ...' that is not a zero integer literal. |
18+
| test.cpp:66:3:66:35 | ... = ... | Assignment to 'errno' with value '... - ...' that is not a zero integer literal. |
19+
| test.cpp:70:3:70:11 | ... = ... | Assignment to 'errno' with value '5' that is not a zero integer literal. |
20+
| test.cpp:71:3:71:12 | ... += ... | Compound assignment to 'errno' with operator '+=' is not allowed. |
21+
| test.cpp:72:3:72:12 | ... -= ... | Assignment to 'errno' with value '5' that is not a zero integer literal. |
22+
| test.cpp:72:3:72:12 | ... -= ... | Compound assignment to 'errno' with operator '-=' is not allowed. |
23+
| test.cpp:73:3:73:12 | ... *= ... | Compound assignment to 'errno' with operator '*=' is not allowed. |
24+
| test.cpp:74:3:74:12 | ... /= ... | Assignment to 'errno' with value '1' that is not a zero integer literal. |
25+
| test.cpp:74:3:74:12 | ... /= ... | Compound assignment to 'errno' with operator '/=' is not allowed. |
26+
| test.cpp:81:3:81:14 | ... = ... | Assignment to 'errno' with value 'call to operator()' that is not a zero integer literal. |
27+
| test.cpp:82:3:82:14 | ... = ... | Assignment to 'errno' with value 'call to operator()' that is not a zero integer literal. |
28+
| test.cpp:86:3:86:29 | ... = ... | Assignment to 'errno' with value 'static_cast<int>...' that is not a zero integer literal. |
29+
| test.cpp:87:3:87:31 | ... = ... | Assignment to 'errno' with value 'static_cast<int>...' that is not a zero integer literal. |
30+
| test.cpp:88:3:88:16 | ... = ... | Assignment to 'errno' with value '(int)...' that is not a zero integer literal. |
31+
| test.cpp:89:3:89:16 | ... = ... | Assignment to 'errno' with value '(int)...' that is not a zero integer literal. |
32+
| test.cpp:108:3:108:40 | ... = ... | Assignment to 'errno' with value 'reinterpret_cast<int>...' that is not a zero integer literal. |
33+
| test.cpp:110:3:110:35 | ... = ... | Assignment to 'errno' with value 'reinterpret_cast<int>...' that is not a zero integer literal. |
34+
| test.cpp:111:3:111:35 | ... = ... | Assignment to 'errno' with value 'reinterpret_cast<int>...' that is not a zero integer literal. |
35+
| test.cpp:113:3:113:40 | ... = ... | Assignment to 'errno' with value 'reinterpret_cast<int>...' that is not a zero integer literal. |
36+
| test.cpp:122:3:122:13 | ... = ... | Assignment to 'errno' with value '48' that is not a zero integer literal. |
37+
| test.cpp:128:3:128:14 | ... = ... | Assignment to 'errno' with value '1' that is not a zero integer literal. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-22-4-1/InvalidAssignmentToErrno.ql
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#include<cerrno>
2+
#include<cstdint>
3+
#include<optional>
4+
#include<string>
5+
6+
voiderrnoSettingFunction();
7+
voidhandleError();
8+
voidf();
9+
10+
#defineOK0
11+
#defineCUSTOM_ERROR42
12+
#defineZERO_MACRO0
13+
14+
voidtest_literal_zero_assignment() {
15+
errno =0;// COMPLIANT
16+
}
17+
18+
voidtest_different_zero_literal_formats() {
19+
errno =0;// COMPLIANT - decimal zero literal
20+
errno =0x0;// COMPLIANT - hexadecimal zero literal
21+
errno =00;// COMPLIANT - octal zero literal
22+
errno =0b0;// COMPLIANT - binary zero literal
23+
}
24+
25+
voidtest_floating_point_zero_literals() {
26+
errno =0.0;// NON_COMPLIANT - floating point literal, not integer literal
27+
errno =0.0f;// NON_COMPLIANT - floating point literal, not integer literal
28+
}
29+
30+
voidtest_non_zero_literal_assignment() {
31+
errno =1;// NON_COMPLIANT
32+
errno =42;// NON_COMPLIANT
33+
errno = -1;// NON_COMPLIANT
34+
}
35+
36+
voidtest_macro_assignments() {
37+
errno = OK;// COMPLIANT - expands to literal 0
38+
errno = ZERO_MACRO;// COMPLIANT - expands to literal 0
39+
errno = CUSTOM_ERROR;// NON_COMPLIANT - expands to non-zero literal
40+
}
41+
42+
voidtest_variable_assignments() {
43+
std::uint32_t l1 =0;
44+
const std::uint32_t l2 =0;
45+
constexpr std::uint32_t l3 =0;
46+
std::uint32_t l4 =42;
47+
const std::uint32_t l5 =42;
48+
49+
errno = l1;// NON_COMPLIANT - variable, not literal
50+
errno = l2;// NON_COMPLIANT - constant variable, not literal
51+
errno = l3;// NON_COMPLIANT - constexpr variable, not literal
52+
errno = l4;// NON_COMPLIANT - variable with non-zero value
53+
errno = l5;// NON_COMPLIANT - constant variable with non-zero value
54+
}
55+
56+
voidtest_standard_error_macros() {
57+
errno = EINVAL;// NON_COMPLIANT - standard error macro
58+
errno = ERANGE;// NON_COMPLIANT - standard error macro
59+
errno = EDOM;// NON_COMPLIANT - standard error macro
60+
}
61+
62+
voidtest_expressions() {
63+
errno =0 +0;// NON_COMPLIANT - expression, not literal
64+
errno =1 -1;// NON_COMPLIANT - expression, not literal
65+
errno =0 *5;// NON_COMPLIANT - expression, not literal
66+
errno =sizeof(int) -sizeof(int);// NON_COMPLIANT - expression, not literal
67+
}
68+
69+
voidtest_compound_assignments() {
70+
errno =5;// NON_COMPLIANT - initial assignment to non-zero value
71+
errno +=0;// NON_COMPLIANT - compound assignment, not simple assignment
72+
errno -=5;// NON_COMPLIANT - compound assignment, not simple assignment
73+
errno *=0;// NON_COMPLIANT - compound assignment, not simple assignment
74+
errno /=1;// NON_COMPLIANT - compound assignment, not simple assignment
75+
}
76+
77+
voidtest_function_return_values() {
78+
auto l1 = []() {return0; };
79+
auto l2 = []() {return42; };
80+
81+
errno =l1();// NON_COMPLIANT - function return value, not literal
82+
errno =l2();// NON_COMPLIANT - function return value, not literal
83+
}
84+
85+
voidtest_cast_expressions() {
86+
errno =static_cast<int>(0);// NON_COMPLIANT - cast expression
87+
errno =static_cast<int>(0.0);// NON_COMPLIANT - cast expression
88+
errno = (int)0;// NON_COMPLIANT - C-style cast
89+
errno =int(0);// NON_COMPLIANT - functional cast
90+
}
91+
92+
voidtest_reading_errno_is_allowed() {
93+
std::uint32_t l1 = errno;// COMPLIANT - reading errno is allowed
94+
if (errno !=0) {// COMPLIANT - reading errno is allowed
95+
handleError();
96+
}
97+
98+
errnoSettingFunction();
99+
std::uint32_t l2 =0;
100+
if (errno != l2) {// COMPLIANT - reading errno is allowed
101+
handleError();
102+
}
103+
}
104+
105+
voidtest_pointer_and_null_assignments() {
106+
label:
107+
staticconstint x =0;
108+
errno =reinterpret_cast<int>(nullptr);// NON_COMPLIANT - nullptr is
109+
// not an integer literal
110+
errno =reinterpret_cast<int>(&x);// NON_COMPLIANT - pointer cast to integer
111+
errno =reinterpret_cast<int>(&f);// NON_COMPLIANT - pointer cast to
112+
// integer
113+
errno =reinterpret_cast<int>(&&label);// NON_COMPLIANT - pointer
114+
// cast to integer
115+
errno =NULL;// NON_COMPLIANT[FALSE_NEGATIVE] - NULL may expand to 0 but not
116+
// literal
117+
}
118+
119+
voidtest_character_literals() {
120+
errno ='\0';// NON_COMPLIANT[FALSE_NEGATIVE] - character literal, not
121+
// integer literal
122+
errno ='0';// NON_COMPLIANT - character '0' has value 48
123+
}
124+
125+
voidtest_boolean_literals() {
126+
errno =false;// NON_COMPLIANT[FALSE_NEGATIVE] - boolean literal, not integer
127+
// literal
128+
errno =true;// NON_COMPLIANT - boolean literal with non-zero value
129+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"MISRA-C++-2023": {
3+
"RULE-22-4-1": {
4+
"properties": {
5+
"enforcement":"decidable",
6+
"obligation":"required"
7+
},
8+
"queries": [
9+
{
10+
"description":"C++ provides better options for error handling than the use of errno. Errno should not be used for reporting errors within project code.",
11+
"kind":"problem",
12+
"name":"The literal value zero shall be the only value assigned to errno",
13+
"precision":"very-high",
14+
"severity":"error",
15+
"short_name":"InvalidAssignmentToErrno",
16+
"tags": [
17+
"scope/single-translation-unit",
18+
"maintainability"
19+
]
20+
}
21+
],
22+
"title":"The literal value zero shall be the only value assigned to errno"
23+
}
24+
}
25+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp