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

Appearance settings

Commit b18a89e

Browse filesBrowse files
Merge pull request #174 from github/jeongsoolee09/misra6-1_and_misra6-2
Initiate Types Rule Package and Implement MISRA RULE-6-1 and RULE-6-2
2 parents 3d39c53 + 3e96c5f commit b18a89e
Copy full SHA for b18a89e

13 files changed

+716
-2
lines changed
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @id c/misra/bit-fields-shall-only-be-declared-with-an-appropriate-type
3+
* @name RULE-6-1: Bit-fields shall only be declared with an appropriate type
4+
* @description Declaring bit-fields on types other than appropriate ones causes
5+
* implementation-specific or undefined behavior.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-6-1
10+
* external/misra/obligation/required
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
16+
predicate isAppropriatePrimitive(Type type) {
17+
/* An appropriate primitive types to which a bit-field can be declared. */
18+
type instanceof IntType and
19+
(
20+
type.(IntegralType).isExplicitlySigned() or
21+
type.(IntegralType).isExplicitlyUnsigned()
22+
)
23+
or
24+
type instanceof BoolType
25+
}
26+
27+
from BitField bitField
28+
where
29+
not isExcluded(bitField,
30+
BitfieldTypesPackage::bitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery()) and
31+
/* A violation would neither be an appropriate primitive type nor an appropriate typedef. */
32+
not isAppropriatePrimitive(bitField.getType().resolveTypedefs())
33+
select bitField, "Bit-field " + bitField + " is declared on type " + bitField.getType() + "."
+34Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @id c/misra/single-bit-named-bit-fields-of-a-signed-type
3+
* @name RULE-6-2: Single-bit named bit fields shall not be of a signed type
4+
* @description Single-bit named bit fields carry no useful information and therefore should not be
5+
* declared or used.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-6-2
10+
* external/misra/obligation/required
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
16+
/*
17+
* Check if the DECLARED bit-fields is a single bit, because Rule 6.2 also intends to catch confusion on the programmers' part. Consider:
18+
*
19+
* struct S {
20+
* int32_t x: 1;
21+
* }
22+
*
23+
* In this case, field x is essentially of 32 bits, but is declared as 1 bit and its type int32_t is signed. Therefore, it indicates confusion by the programmer, which is exactly what this rule intends to find.
24+
*/
25+
26+
from BitField bitField
27+
where
28+
not isExcluded(bitField, BitfieldTypesPackage::singleBitNamedBitFieldsOfASignedTypeQuery()) and
29+
bitField.getDeclaredNumBits() = 1 and // Single-bit,
30+
not bitField.isAnonymous() and // named,
31+
bitField.getType().(IntegralType).isSigned() // but its type is signed.
32+
select bitField,
33+
"Single-bit bit-field named " + bitField.toString() + " has a signed type " + bitField.getType() +
34+
"."
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:6:7:6:8 | x1 | Bit-field x1 is declared on type int. |
2+
| test.c:10:15:10:16 | x5 | Bit-field x5 is declared on type signed long. |
3+
| test.c:12:15:12:16 | x6 | Bit-field x6 is declared on type signed char. |
4+
| test.c:14:14:14:15 | x7 | Bit-field x7 is declared on type Color. |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-6-1/BitFieldsShallOnlyBeDeclaredWithAnAppropriateType.ql

‎c/misra/test/rules/RULE-6-1/test.c

Copy file name to clipboard
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
typedef unsigned int UINT16;
2+
3+
enum Color { R, G, B };
4+
5+
struct SampleStruct {
6+
int x1 : 2; // NON_COMPLIANT - not explicitly signed or unsigned
7+
unsigned int x2 : 2; // COMPILANT - explicitly unsigned
8+
signed int x3 : 2; // COMPILANT - explicitly signed
9+
UINT16 x4 : 2; // COMPLIANT - type alias resolves to a compliant type
10+
signed long x5 : 2; // NON_COMPLIANT - cannot declare bit field for long, even
11+
// if it's signed
12+
signed char x6 : 2; // NON_COMPILANT - cannot declare bit field for char, even
13+
// if it's signed
14+
enum Color x7 : 3; // NON_COMPILANT - cannot declare bit field for enum
15+
} sample_struct;
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:4:7:4:8 | x1 | Single-bit bit-field named x1 has a signed type int. |
2+
| test.c:7:14:7:15 | x2 | Single-bit bit-field named x2 has a signed type signed int. |
3+
| test.c:9:7:9:8 | x3 | Single-bit bit-field named x3 has a signed type signed char. |
4+
| test.c:11:7:11:8 | x4 | Single-bit bit-field named x4 has a signed type signed short. |
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-6-2/SingleBitNamedBitFieldsOfASignedType.ql

‎c/misra/test/rules/RULE-6-2/test.c

Copy file name to clipboard
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include <stdint.h>
2+
3+
struct SampleStruct {
4+
int x1 : 1; // NON_COMPILANT: very likely be signed, but if it's not, the
5+
// query will automatically handle it since we use signed(), not
6+
// isExplicitlySigned().
7+
signed int x2 : 1; // NON_COMPILANT: single-bit named field with a signed type
8+
signed char
9+
x3 : 1; // NON_COMPILANT: single-bit named field with a signed type
10+
signed short
11+
x4 : 1; // NON_COMPILANT: single-bit named field with a signed type
12+
unsigned int
13+
x5 : 1; // COMPILANT: single-bit named field but with an unsigned type
14+
signed int x6 : 2; // COMPILANT: named field with a signed type but declared
15+
// to carry more than 1 bit
16+
signed char : 1; // COMPILANT: single-bit bit-field but unnamed
17+
} sample_struct;
+44Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype BitfieldTypesQuery =
7+
TBitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery() or
8+
TSingleBitNamedBitFieldsOfASignedTypeQuery()
9+
10+
predicate isBitfieldTypesQueryMetadata(Query query, string queryId, string ruleId, string category) {
11+
query =
12+
// `Query` instance for the `bitFieldsShallOnlyBeDeclaredWithAnAppropriateType` query
13+
BitfieldTypesPackage::bitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery() and
14+
queryId =
15+
// `@id` for the `bitFieldsShallOnlyBeDeclaredWithAnAppropriateType` query
16+
"c/misra/bit-fields-shall-only-be-declared-with-an-appropriate-type" and
17+
ruleId = "RULE-6-1" and
18+
category = "required"
19+
or
20+
query =
21+
// `Query` instance for the `singleBitNamedBitFieldsOfASignedType` query
22+
BitfieldTypesPackage::singleBitNamedBitFieldsOfASignedTypeQuery() and
23+
queryId =
24+
// `@id` for the `singleBitNamedBitFieldsOfASignedType` query
25+
"c/misra/single-bit-named-bit-fields-of-a-signed-type" and
26+
ruleId = "RULE-6-2" and
27+
category = "required"
28+
}
29+
30+
module BitfieldTypesPackage {
31+
Query bitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery() {
32+
//autogenerate `Query` type
33+
result =
34+
// `Query` type for `bitFieldsShallOnlyBeDeclaredWithAnAppropriateType` query
35+
TQueryC(TBitfieldTypesPackageQuery(TBitFieldsShallOnlyBeDeclaredWithAnAppropriateTypeQuery()))
36+
}
37+
38+
Query singleBitNamedBitFieldsOfASignedTypeQuery() {
39+
//autogenerate `Query` type
40+
result =
41+
// `Query` type for `singleBitNamedBitFieldsOfASignedType` query
42+
TQueryC(TBitfieldTypesPackageQuery(TSingleBitNamedBitFieldsOfASignedTypeQuery()))
43+
}
44+
}

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

Copy file name to clipboardExpand all lines: cpp/common/src/codingstandards/cpp/exclusions/c/RuleMetadata.qll
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import cpp
33
import codingstandards.cpp.exclusions.RuleMetadata
44
//** Import packages for this language **/
55
import Banned
6+
import BitfieldTypes
67
import Concurrency1
78
import Concurrency2
89
import Concurrency3
@@ -47,6 +48,7 @@ import Syntax
4748
/** The TQuery type representing this language * */
4849
newtype TCQuery =
4950
TBannedPackageQuery(BannedQuery q) or
51+
TBitfieldTypesPackageQuery(BitfieldTypesQuery q) or
5052
TConcurrency1PackageQuery(Concurrency1Query q) or
5153
TConcurrency2PackageQuery(Concurrency2Query q) or
5254
TConcurrency3PackageQuery(Concurrency3Query q) or
@@ -91,6 +93,7 @@ newtype TCQuery =
9193
/** The metadata predicate * */
9294
predicate isQueryMetadata(Query query, string queryId, string ruleId, string category) {
9395
isBannedQueryMetadata(query, queryId, ruleId, category) or
96+
isBitfieldTypesQueryMetadata(query, queryId, ruleId, category) or
9497
isConcurrency1QueryMetadata(query, queryId, ruleId, category) or
9598
isConcurrency2QueryMetadata(query, queryId, ruleId, category) or
9699
isConcurrency3QueryMetadata(query, queryId, ruleId, category) or

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.