Skip to content

Commit 21af40d

Browse files
committed
Add implementation of Banned2
1 parent 6dc64be commit 21af40d

File tree

6 files changed

+214
-0
lines changed

6 files changed

+214
-0
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+
newtype Banned2Query = TUnscopedEnumerationsShouldNotBeDeclaredQuery()
7+
8+
predicate isBanned2QueryMetadata(Query query, string queryId, string ruleId, string category) {
9+
query =
10+
// `Query` instance for the `unscopedEnumerationsShouldNotBeDeclared` query
11+
Banned2Package::unscopedEnumerationsShouldNotBeDeclaredQuery() and
12+
queryId =
13+
// `@id` for the `unscopedEnumerationsShouldNotBeDeclared` query
14+
"cpp/misra/unscoped-enumerations-should-not-be-declared" and
15+
ruleId = "RULE-10-2-2" and
16+
category = "advisory"
17+
}
18+
19+
module Banned2Package {
20+
Query unscopedEnumerationsShouldNotBeDeclaredQuery() {
21+
//autogenerate `Query` type
22+
result =
23+
// `Query` type for `unscopedEnumerationsShouldNotBeDeclared` query
24+
TQueryCPP(TBanned2PackageQuery(TUnscopedEnumerationsShouldNotBeDeclaredQuery()))
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
@@ -4,6 +4,7 @@ import codingstandards.cpp.exclusions.RuleMetadata
44
//** Import packages for this language **/
55
import Allocations
66
import Banned1
7+
import Banned2
78
import BannedAPIs
89
import BannedFunctions
910
import BannedLibraries
@@ -92,6 +93,7 @@ import VirtualFunctions
9293
newtype TCPPQuery =
9394
TAllocationsPackageQuery(AllocationsQuery q) or
9495
TBanned1PackageQuery(Banned1Query q) or
96+
TBanned2PackageQuery(Banned2Query q) or
9597
TBannedAPIsPackageQuery(BannedAPIsQuery q) or
9698
TBannedFunctionsPackageQuery(BannedFunctionsQuery q) or
9799
TBannedLibrariesPackageQuery(BannedLibrariesQuery q) or
@@ -180,6 +182,7 @@ newtype TCPPQuery =
180182
predicate isQueryMetadata(Query query, string queryId, string ruleId, string category) {
181183
isAllocationsQueryMetadata(query, queryId, ruleId, category) or
182184
isBanned1QueryMetadata(query, queryId, ruleId, category) or
185+
isBanned2QueryMetadata(query, queryId, ruleId, category) or
183186
isBannedAPIsQueryMetadata(query, queryId, ruleId, category) or
184187
isBannedFunctionsQueryMetadata(query, queryId, ruleId, category) or
185188
isBannedLibrariesQueryMetadata(query, queryId, ruleId, category) or
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @id cpp/misra/unscoped-enumerations-should-not-be-declared
3+
* @name RULE-10-2-2: Unscoped enumerations should not be declared
4+
* @description An unscoped enumeration should not be used outside of a class/struct scope; use
5+
* 'enum class' instead to prevent name clashes and implicit conversions to integral
6+
* types.
7+
* @kind problem
8+
* @precision very-high
9+
* @problem.severity error
10+
* @tags external/misra/id/rule-10-2-2
11+
* scope/single-translation-unit
12+
* correctness
13+
* external/misra/enforcement/decidable
14+
* external/misra/obligation/advisory
15+
*/
16+
17+
import cpp
18+
import codingstandards.cpp.misra
19+
20+
class MemberUnscopedEnum extends Enum {
21+
MemberUnscopedEnum() {
22+
not this instanceof ScopedEnum and
23+
exists(Class klass | klass = this.getEnclosingElement())
24+
}
25+
}
26+
27+
from Enum enum
28+
where
29+
not isExcluded(enum, Banned2Package::unscopedEnumerationsShouldNotBeDeclaredQuery()) and
30+
not (enum instanceof ScopedEnum or enum instanceof MemberUnscopedEnum)
31+
select enum, "This enumeration is an unscoped enum not enclosed in a class or a struct."
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No expected results have yet been specified
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-10-2-2/UnscopedEnumerationsShouldNotBeDeclared.ql
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#include <cstdint>
2+
3+
/* ========== 1. Global scope fixtures ========== */
4+
static int32_t G1 = 1;
5+
static int32_t G2 = 2;
6+
7+
/* ========== 2. Global scope enums ========== */
8+
enum E_Global1 : int32_t { V1, V2, V3 }; // NON_COMPLIANT: unscoped at global scope
9+
enum { GlobalAnon1, GlobalAnon2 }; // NON_COMPLIANT: unscoped anonymous at global scope
10+
enum class E_Global2 : int32_t { V1, V2 }; // COMPLIANT: scoped enum
11+
12+
/* ========== 3. Nested namespaces ========== */
13+
namespace N1 {
14+
static int32_t N1_V1 = 1;
15+
16+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in namespace + hides ::G1
17+
enum { N1_Anon1, N1_Anon2 }; // NON_COMPLIANT: unscoped anonymous in namespace
18+
enum class E2 : int32_t { G1 }; // COMPLIANT: scoped enum
19+
20+
namespace N2 {
21+
static int32_t N2_V1 = 1;
22+
23+
enum E3 : int32_t { N1_V1 }; // NON_COMPLIANT: unscoped in namespace + hides N1::N1_V1
24+
enum E4 : int32_t { G2 }; // NON_COMPLIANT: unscoped in namespace + hides ::G2
25+
enum class E5 : int32_t { N1_V1, G2 }; // COMPLIANT: scoped enum
26+
}
27+
}
28+
29+
/* ========== 4. Anonymous namespace ========== */
30+
namespace {
31+
enum E_Anon1 : int32_t { V1, V2 }; // NON_COMPLIANT: unscoped in anonymous namespace
32+
enum { AnonAnon1, AnonAnon2 }; // NON_COMPLIANT: unscoped anonymous in anonymous namespace
33+
enum class E_Anon2 : int32_t { V1 }; // COMPLIANT: scoped enum
34+
}
35+
36+
/* ========== 5. Anonymous namespace inside named namespace ========== */
37+
namespace N3 {
38+
static int32_t N3_V1 = 1;
39+
40+
namespace {
41+
enum E1 : int32_t { N3_V1 }; // NON_COMPLIANT: unscoped + hides N3::N3_V1
42+
enum class E2 : int32_t { N3_V1 }; // COMPLIANT: scoped enum
43+
}
44+
}
45+
46+
/* ========== 6. Nested classes ========== */
47+
class C1 {
48+
static int32_t C1_V1;
49+
50+
enum E1 { G1 }; // COMPLIANT: unscoped in class (exception) + hides ::G1
51+
enum { C1_Anon1, C1_Anon2 }; // COMPLIANT: unscoped anonymous in class (exception)
52+
enum class E2 { G1 }; // COMPLIANT: scoped enum
53+
54+
class C2 {
55+
enum E3 { C1_V1 }; // COMPLIANT: unscoped in nested class (exception)
56+
enum E4 { G2 }; // COMPLIANT: unscoped in nested class (exception) + hides ::G2
57+
58+
struct S1 {
59+
enum E5 { C1_V1 }; // COMPLIANT: unscoped in struct (exception)
60+
enum class E6 { C1_V1 }; // COMPLIANT: scoped enum
61+
};
62+
};
63+
};
64+
65+
/* ========== 7. Struct at global scope ========== */
66+
struct S_Global {
67+
enum E1 { G1 }; // COMPLIANT: unscoped in struct (exception)
68+
enum { S_Anon1, S_Anon2 }; // COMPLIANT: unscoped anonymous in struct (exception)
69+
enum class E2 { G1 }; // COMPLIANT: scoped enum
70+
};
71+
72+
/* ========== 8. Class inside namespace ========== */
73+
namespace N4 {
74+
static int32_t N4_V1 = 1;
75+
76+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in namespace
77+
78+
class C1 {
79+
enum E2 { N4_V1 }; // COMPLIANT: unscoped in class (exception) + hides N4::N4_V1
80+
enum E3 { G2 }; // COMPLIANT: unscoped in class (exception) + hides ::G2
81+
enum class E4 { N4_V1, G2 }; // COMPLIANT: scoped enum
82+
};
83+
}
84+
85+
/* ========== 9. Function body ========== */
86+
void f1() {
87+
int F1_V1 = 1;
88+
89+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in function + hides ::G1
90+
enum { F1_Anon1, F1_Anon2 }; // NON_COMPLIANT: unscoped anonymous in function
91+
enum class E2 : int32_t { G1 }; // COMPLIANT: scoped enum
92+
}
93+
94+
/* ========== 10. Nested blocks ========== */
95+
void f2() {
96+
int F2_V1 = 1;
97+
98+
{
99+
int F2_V2 = 2;
100+
101+
enum E1 : int32_t { F2_V1 }; // NON_COMPLIANT: unscoped in block + hides outer F2_V1
102+
enum E2 : int32_t { G2 }; // NON_COMPLIANT: unscoped in block + hides ::G2
103+
104+
{
105+
enum E3 : int32_t { F2_V2 }; // NON_COMPLIANT: unscoped in nested block + hides outer F2_V2
106+
enum class E4 : int32_t { F2_V1, F2_V2, G1 }; // COMPLIANT: scoped enum
107+
}
108+
}
109+
}
110+
111+
/* ========== 11. Local class in function ========== */
112+
void f3() {
113+
int F3_V1 = 1;
114+
115+
class LocalC1 {
116+
enum E1 { F3_V1 }; // COMPLIANT: unscoped in local class (exception)
117+
enum E2 { G1 }; // COMPLIANT: unscoped in local class (exception) + hides ::G1
118+
enum { Local_Anon1 }; // COMPLIANT: unscoped anonymous in local class (exception)
119+
enum class E3 { F3_V1, G1 }; // COMPLIANT: scoped enum
120+
};
121+
}
122+
123+
/* ========== 12. Lambda body ========== */
124+
auto lambda1 = []() {
125+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in lambda body
126+
enum { Lambda_Anon1 }; // NON_COMPLIANT: unscoped anonymous in lambda body
127+
enum class E2 : int32_t { G1 }; // COMPLIANT: scoped enum
128+
};
129+
130+
/* ========== 13. Nested lambdas ========== */
131+
namespace N5 {
132+
auto lambda2 = []() {
133+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in lambda body
134+
135+
auto nested_lambda = []() {
136+
enum E2 : int32_t { G2 }; // NON_COMPLIANT: unscoped in nested lambda body
137+
enum class E3 : int32_t { G1, G2 }; // COMPLIANT: scoped enum
138+
};
139+
};
140+
}
141+
142+
/* ========== 14. Lambda inside class ========== */
143+
class C3 {
144+
static inline auto member_lambda = []() {
145+
enum E1 : int32_t { G1 }; // NON_COMPLIANT: unscoped in lambda body (not class scope!)
146+
enum class E2 : int32_t { G1 }; // COMPLIANT: scoped enum
147+
};
148+
};
149+
150+
int main() {
151+
return 0;
152+
}

0 commit comments

Comments
 (0)