Skip to content

Commit d79cf17

Browse files
initial implementation of 6-2-3
1 parent d6a6d46 commit d79cf17

15 files changed

+282
-0
lines changed
Lines 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 Declarations8Query =
7+
TSourceCodeImplementedOnlyOnceQuery() or
8+
TTemplateSpecializationWrongLocationQuery()
9+
10+
predicate isDeclarations8QueryMetadata(Query query, string queryId, string ruleId, string category) {
11+
query =
12+
// `Query` instance for the `sourceCodeImplementedOnlyOnce` query
13+
Declarations8Package::sourceCodeImplementedOnlyOnceQuery() and
14+
queryId =
15+
// `@id` for the `sourceCodeImplementedOnlyOnce` query
16+
"cpp/misra/source-code-implemented-only-once" and
17+
ruleId = "RULE-6-2-3" and
18+
category = "required"
19+
or
20+
query =
21+
// `Query` instance for the `templateSpecializationWrongLocation` query
22+
Declarations8Package::templateSpecializationWrongLocationQuery() and
23+
queryId =
24+
// `@id` for the `templateSpecializationWrongLocation` query
25+
"cpp/misra/template-specialization-wrong-location" and
26+
ruleId = "RULE-6-2-3" and
27+
category = "required"
28+
}
29+
30+
module Declarations8Package {
31+
Query sourceCodeImplementedOnlyOnceQuery() {
32+
//autogenerate `Query` type
33+
result =
34+
// `Query` type for `sourceCodeImplementedOnlyOnce` query
35+
TQueryCPP(TDeclarations8PackageQuery(TSourceCodeImplementedOnlyOnceQuery()))
36+
}
37+
38+
Query templateSpecializationWrongLocationQuery() {
39+
//autogenerate `Query` type
40+
result =
41+
// `Query` type for `templateSpecializationWrongLocation` query
42+
TQueryCPP(TDeclarations8PackageQuery(TTemplateSpecializationWrongLocationQuery()))
43+
}
44+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import Declarations1
3939
import Declarations2
4040
import Declarations3
4141
import Declarations4
42+
import Declarations8
4243
import ExceptionSafety
4344
import Exceptions1
4445
import Exceptions2
@@ -141,6 +142,7 @@ newtype TCPPQuery =
141142
TDeclarations2PackageQuery(Declarations2Query q) or
142143
TDeclarations3PackageQuery(Declarations3Query q) or
143144
TDeclarations4PackageQuery(Declarations4Query q) or
145+
TDeclarations8PackageQuery(Declarations8Query q) or
144146
TExceptionSafetyPackageQuery(ExceptionSafetyQuery q) or
145147
TExceptions1PackageQuery(Exceptions1Query q) or
146148
TExceptions2PackageQuery(Exceptions2Query q) or
@@ -243,6 +245,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
243245
isDeclarations2QueryMetadata(query, queryId, ruleId, category) or
244246
isDeclarations3QueryMetadata(query, queryId, ruleId, category) or
245247
isDeclarations4QueryMetadata(query, queryId, ruleId, category) or
248+
isDeclarations8QueryMetadata(query, queryId, ruleId, category) or
246249
isExceptionSafetyQueryMetadata(query, queryId, ruleId, category) or
247250
isExceptions1QueryMetadata(query, queryId, ruleId, category) or
248251
isExceptions2QueryMetadata(query, queryId, ruleId, category) or
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/**
2+
* @id cpp/misra/source-code-implemented-only-once
3+
* @name RULE-6-2-3: The source code used to implement an entity shall appear only once
4+
* @description Implementing an entity in multiple source locations violates the one-definition rule
5+
* and leads to undefined behavior.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-6-2-3
10+
* correctness
11+
* scope/system
12+
* external/misra/enforcement/decidable
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.misra
18+
19+
predicate isInline(DeclarationEntry d) {
20+
// There is no way to detect if a `GlobalVariable` is declared inline.
21+
d.getDeclaration().(Function).isInline()
22+
}
23+
24+
from DeclarationEntry d1, DeclarationEntry d2, string namespace, string name
25+
where
26+
not isExcluded([d1, d2], Declarations8Package::sourceCodeImplementedOnlyOnceQuery()) and
27+
d1 != d2 and
28+
d1.isDefinition() and
29+
d2.isDefinition() and
30+
isInline(d1) and
31+
isInline(d2) and
32+
d1.getDeclaration().hasQualifiedName(namespace, name) and
33+
d2.getDeclaration().hasQualifiedName(namespace, name) and
34+
d1.getFile() != d2.getFile() and
35+
d1.getFile().getAbsolutePath() < d2.getFile().getAbsolutePath()
36+
select d1,
37+
"Inline variable '" + d1.getName() +
38+
"' is defined in multiple files, violating the source code uniqueness requirement."
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* @id cpp/misra/template-specialization-wrong-location
3+
* @name RULE-6-2-3: RULE-6-2-3: Template specializations in wrong location
4+
* @description Template specializations must be defined in the same file as the primary template or
5+
* where a specialized type is defined to ensure visibility and avoid ODR violations.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-6-2-3
10+
* correctness
11+
* scope/system
12+
* external/misra/enforcement/decidable
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.cpp.misra
18+
19+
predicate specializedWithFileDeclaredType(ClassTemplateSpecialization spec) {
20+
exists(Type argType |
21+
spec.getTemplateArgument(_).(Type).getUnderlyingType() = argType and
22+
spec.getFile() = argType.getFile() and
23+
not argType instanceof TypeTemplateParameter
24+
)
25+
}
26+
27+
28+
from ClassTemplateSpecialization spec, Class primaryTemplate, File primaryFile
29+
where
30+
not isExcluded(spec, Declarations8Package::templateSpecializationWrongLocationQuery()) and
31+
spec.getPrimaryTemplate() = primaryTemplate and
32+
primaryFile = primaryTemplate.getFile() and
33+
// The specialization is in a different file than the primary template
34+
spec.getFile() != primaryFile and
35+
// And it's not in the same file as any of its template arguments
36+
not specializedWithFileDeclaredType(spec)
37+
select spec,
38+
"Template specialization '" + spec.getName() +
39+
"' is declared in a different file than $@ and all specialized template arguments.",
40+
primaryTemplate, primaryTemplate.getName()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.cpp:6:13:6:26 | definition of func_redefined | Inline variable 'func_redefined' is defined in multiple files, violating the source code uniqueness requirement. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-6-2-3/SourceCodeImplementedOnlyOnce.ql
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
| noncompliant_specialization.h:3:19:3:28 | Tpl1<long> | Template specialization 'Tpl1<long>' is declared in a different file than $@ and all specialized template arguments. | template.h:10:29:10:32 | Tpl1<T> | Tpl1<T> |
2+
| noncompliant_specialization.h:4:19:4:38 | Tpl1<C2> | Template specialization 'Tpl1<C2>' is declared in a different file than $@ and all specialized template arguments. | template.h:10:29:10:32 | Tpl1<T> | Tpl1<T> |
3+
| noncompliant_specialization.h:5:19:5:35 | Tpl1<C2> | Template specialization 'Tpl1<C2>' is declared in a different file than $@ and all specialized template arguments. | template.h:10:29:10:32 | Tpl1<T> | Tpl1<T> |
4+
| noncompliant_specialization.h:7:19:7:34 | Tpl2<long, long> | Template specialization 'Tpl2<long, long>' is declared in a different file than $@ and all specialized template arguments. | template.h:11:41:11:44 | Tpl2<A, B> | Tpl2<A, B> |
5+
| noncompliant_specialization.h:8:19:8:54 | Tpl2<C2, C2> | Template specialization 'Tpl2<C2, C2>' is declared in a different file than $@ and all specialized template arguments. | template.h:11:41:11:44 | Tpl2<A, B> | Tpl2<A, B> |
6+
| noncompliant_specialization.h:9:19:9:48 | Tpl2<C2, C2> | Template specialization 'Tpl2<C2, C2>' is declared in a different file than $@ and all specialized template arguments. | template.h:11:41:11:44 | Tpl2<A, B> | Tpl2<A, B> |
7+
| noncompliant_specialization.h:11:29:11:41 | Tpl2<long, T> | Template specialization 'Tpl2<long, T>' is declared in a different file than $@ and all specialized template arguments. | template.h:11:41:11:44 | Tpl2<A, B> | Tpl2<A, B> |
8+
| noncompliant_specialization.h:12:29:12:48 | Tpl2<C1, T> | Template specialization 'Tpl2<C1, T>' is declared in a different file than $@ and all specialized template arguments. | template.h:11:41:11:44 | Tpl2<A, B> | Tpl2<A, B> |
9+
| noncompliant_specialization.h:14:19:14:25 | Tpl3<1> | Template specialization 'Tpl3<1>' is declared in a different file than $@ and all specialized template arguments. | template.h:12:22:12:25 | Tpl3<<unnamed>> | Tpl3<<unnamed>> |
10+
| noncompliant_specialization.h:15:19:15:31 | Tpl4<long, 0> | Template specialization 'Tpl4<long, 0>' is declared in a different file than $@ and all specialized template arguments. | template.h:13:34:13:37 | Tpl4<T, <unnamed>> | Tpl4<T, <unnamed>> |
11+
| noncompliant_specialization.h:16:19:16:41 | Tpl4<C1, 1> | Template specialization 'Tpl4<C1, 1>' is declared in a different file than $@ and all specialized template arguments. | template.h:13:34:13:37 | Tpl4<T, <unnamed>> | Tpl4<T, <unnamed>> |
12+
| noncompliant_specialization.h:17:19:17:38 | Tpl4<C1, 1> | Template specialization 'Tpl4<C1, 1>' is declared in a different file than $@ and all specialized template arguments. | template.h:13:34:13:37 | Tpl4<T, <unnamed>> | Tpl4<T, <unnamed>> |
13+
| noncompliant_specialization.h:18:24:18:43 | Tpl4<C2, N> | Template specialization 'Tpl4<C2, N>' is declared in a different file than $@ and all specialized template arguments. | template.h:13:34:13:37 | Tpl4<T, <unnamed>> | Tpl4<T, <unnamed>> |
14+
| noncompliant_specialization.h:19:29:19:38 | Tpl4<T, 2> | Template specialization 'Tpl4<T, 2>' is declared in a different file than $@ and all specialized template arguments. | template.h:13:34:13:37 | Tpl4<T, <unnamed>> | Tpl4<T, <unnamed>> |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-6-2-3/TemplateSpecializationWrongLocation.ql
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#ifndef CLASS_H
2+
#define CLASS_H
3+
4+
namespace class_h {
5+
class C1 {};
6+
class C2 {};
7+
} // namespace class_h
8+
9+
#endif // CLASS_H
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "class.h"
2+
#include "template.h"
3+
4+
namespace compliant_h {
5+
class C1 {};
6+
} // namespace compliant_h
7+
8+
template <> class Tpl1<compliant_h::C1> {}; // COMPLIANT
9+
template <> class Tpl2<compliant_h::C1, compliant_h::C1> {}; // COMPLIANT
10+
template <> class Tpl2<template_h::C1, compliant_h::C1> {}; // COMPLIANT
11+
template <> class Tpl2<class_h::C1, compliant_h::C1> {}; // COMPLIANT
12+
template <> class Tpl2<compliant_h::C1, long> {}; // COMPLIANT
13+
14+
template <typename T> class Tpl2<T, compliant_h::C1> {}; // COMPLIANT
15+
16+
template<> class Tpl4<compliant_h::C1, 0> {}; // COMPLIANT
17+
template<int N> class Tpl4<compliant_h::C1, N> {}; // COMPLIANT

0 commit comments

Comments
 (0)