Skip to content

Commit 6de14ca

Browse files
Implement Language4 package, banning obsolete language features.
Many of the cases outlined in the amendment are covered by other rules. Add support for new cases where possible (was not possible for ID 3, storage class specifiers not at beginning of declaration, or ID 2, which is a feature of the implementation not determinable by static analysis), and reference existing rules in one comprehensive test for maximal clarity that those parts of rule 1-5 are indeed supported by our existing queries.
1 parent 6536606 commit 6de14ca

22 files changed

+278
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/call-to-realloc-with-size-zero
3+
* @name RULE-1-5: Disallowed size argument value equal to zero in call to realloc
4+
* @description Invoking realloc with a size argument set to zero is implementation-defined behavior
5+
* and declared as an obsolete feature in C18.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-1-5
10+
* correctness
11+
* external/misra/obligation/required
12+
*/
13+
14+
import cpp
15+
import codingstandards.c.misra
16+
import semmle.code.cpp.rangeanalysis.new.RangeAnalysis
17+
18+
from FunctionCall call, Expr arg
19+
where
20+
not isExcluded(call, Language4Package::callToReallocWithSizeZeroQuery()) and
21+
call.getTarget().hasGlobalOrStdName("realloc") and
22+
arg = call.getArgument(1) and
23+
upperBound(arg) = 0
24+
select arg, "Calling realloc with size zero results in implementation-defined behavior."
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/**
2+
* @id c/misra/invalid-define-or-undef-of-std-bool-macro
3+
* @name RULE-1-5: Programs may not undefine or redefine the macros bool, true, or false
4+
* @description Directives that undefine and/or redefine the standard boolean macros has been
5+
* declared an obsolescent language feature since C99.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-1-5
10+
* maintainability
11+
* readability
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
18+
string getABoolMacroName() { result = ["true", "false", "bool"] }
19+
20+
from PreprocessorDirective directive, string opString, string macroName
21+
where
22+
not isExcluded(directive, Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery()) and
23+
macroName = getABoolMacroName() and
24+
(
25+
macroName = directive.(Macro).getName() and
26+
opString = "define"
27+
or
28+
macroName = directive.(PreprocessorUndef).getName() and
29+
opString = "undefine"
30+
)
31+
select directive, "Invalid " + opString + " of boolean standard macro " + macroName
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/use-of-obsolete-macro-atomic-var-init
3+
* @name RULE-1-5: Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18
4+
* @description The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since
5+
* C18.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity recommendation
9+
* @tags external/misra/id/rule-1-5
10+
* maintainability
11+
* readability
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
18+
from MacroInvocation invoke, Compilation c, string flag
19+
where
20+
not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and
21+
invoke.getMacroName() = "ATOMIC_VAR_INIT" and
22+
flag = c.getAnArgument() and
23+
flag.regexpMatch("-std=c1[78]")
24+
select invoke, "Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version " + flag
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:13:14:13:14 | 0 | Calling realloc with size zero results in implementation-defined behavior. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/CallToReallocWithSizeZero.ql
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.c:40:6:40:7 | f2 | Function f2 does not specify void for no parameters present. |
2+
| test.c:44:5:44:6 | f5 | Function f5 declares parameter in unsupported declaration list. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| test.c:23:1:23:14 | #define true 3 | Invalid define of boolean standard macro true |
2+
| test.c:24:1:24:15 | #define false 3 | Invalid define of boolean standard macro false |
3+
| test.c:25:1:25:18 | #define bool int * | Invalid define of boolean standard macro bool |
4+
| test.c:26:1:26:11 | #undef true | Invalid undefine of boolean standard macro true |
5+
| test.c:27:1:27:12 | #undef false | Invalid undefine of boolean standard macro false |
6+
| test.c:28:1:28:11 | #undef bool | Invalid undefine of boolean standard macro bool |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:10:12:10:17 | call to malloc | Use of banned dynamic memory allocation. |
2+
| test.c:13:3:13:9 | call to realloc | Use of banned dynamic memory allocation. |
3+
| test.c:16:3:16:9 | call to realloc | Use of banned dynamic memory allocation. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-21-3/MemoryAllocDeallocFunctionsOfStdlibhUsed.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:37:12:37:13 | declaration of g5 | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:36:12:36:13 | definition of g5 | g5 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:57:3:57:8 | call to ungetc | Call to banned function ungetc. |
2+
| test.c:60:3:60:7 | call to fread | Call to banned function fread. |
3+
| test.c:62:3:62:8 | call to ungetc | Call to banned function ungetc. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-21-6/StandardLibraryInputoutputFunctionsUsed.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:30:18:30:36 | ATOMIC_VAR_INIT(value) | Usage of macro ATOMIC_VAR_INIT() is considered obsolete for c version -std=c17 |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql

c/misra/test/rules/RULE-1-5/options

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
semmle-extractor-options:-std=c17 -I../../../../common/test/includes/standard-library

c/misra/test/rules/RULE-1-5/test.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Compiled with -std=c17
2+
3+
#include "stdatomic.h"
4+
#include "stdbool.h"
5+
#include "stdio.h"
6+
#include "stdlib.h"
7+
8+
void f1(void) {
9+
// malloc() is not obsolete, but banned by Rule 21.3
10+
int *t = malloc(10); // COMPLIANT[False Negative]
11+
12+
// Obsolete usage of realloc.
13+
realloc(t, 0); // NON-COMPLIANT
14+
15+
// Valid usage of realloc, but all use of realloc is banned by Rule 21.3
16+
realloc(t, 20); // NON-COMPLIANT
17+
}
18+
19+
extern const int g1; // COMPLIANT
20+
const extern int g2; // NON-COMPLIANT
21+
22+
#define MY_TRUE 3 // COMPLIANT
23+
#define true 3 // NON-COMPLIANT
24+
#define false 3 // NON-COMPLIANT
25+
#define bool int * // NON-COMPLIANT
26+
#undef true // NON-COMPLIANT
27+
#undef false // NON-COMPLIANT
28+
#undef bool // NON-COMPLIANT
29+
30+
_Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT
31+
_Atomic int g4 = 18; // COMPLIANT
32+
33+
// The following cases are already covered by other rules:
34+
35+
// Rule 8.8:
36+
static int g5 = 3; // COMPLIANT
37+
extern int g5; // NON-COMPLIANT
38+
39+
// Rule 8.2:
40+
void f2(); // NON-COMPLIANT
41+
void f3(void); // COMPLIANT
42+
43+
void f4(int p1) {}; // COMPLIANT
44+
int f5(x) // NON_COMPLIANT
45+
int x;
46+
{
47+
return 1;
48+
}
49+
50+
// Rule 21.6 covers the below cases:
51+
void f6(void) {
52+
// `gets` was removed from C11.
53+
// gets(stdin); // NON_COMPLIANT
54+
55+
FILE *file = fopen("", 0);
56+
// Obsolete usage of ungetc.
57+
ungetc('c', file); // NON-COMPLIANT
58+
59+
char buf[10];
60+
fread(buf, sizeof(buf), 10, file);
61+
// This is not an obsolete usage of ungetc, but ungetc isn't allowed.
62+
ungetc('c', file); // NON-COMPLIANT[FALSE NEGATIVE]
63+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
2+
import cpp
3+
import RuleMetadata
4+
import codingstandards.cpp.exclusions.RuleMetadata
5+
6+
newtype Language4Query =
7+
TUseOfObsoleteMacroAtomicVarInitQuery() or
8+
TInvalidDefineOrUndefOfStdBoolMacroQuery() or
9+
TCallToReallocWithSizeZeroQuery()
10+
11+
predicate isLanguage4QueryMetadata(Query query, string queryId, string ruleId, string category) {
12+
query =
13+
// `Query` instance for the `useOfObsoleteMacroAtomicVarInit` query
14+
Language4Package::useOfObsoleteMacroAtomicVarInitQuery() and
15+
queryId =
16+
// `@id` for the `useOfObsoleteMacroAtomicVarInit` query
17+
"c/misra/use-of-obsolete-macro-atomic-var-init" and
18+
ruleId = "RULE-1-5" and
19+
category = "required"
20+
or
21+
query =
22+
// `Query` instance for the `invalidDefineOrUndefOfStdBoolMacro` query
23+
Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery() and
24+
queryId =
25+
// `@id` for the `invalidDefineOrUndefOfStdBoolMacro` query
26+
"c/misra/invalid-define-or-undef-of-std-bool-macro" and
27+
ruleId = "RULE-1-5" and
28+
category = "required"
29+
or
30+
query =
31+
// `Query` instance for the `callToReallocWithSizeZero` query
32+
Language4Package::callToReallocWithSizeZeroQuery() and
33+
queryId =
34+
// `@id` for the `callToReallocWithSizeZero` query
35+
"c/misra/call-to-realloc-with-size-zero" and
36+
ruleId = "RULE-1-5" and
37+
category = "required"
38+
}
39+
40+
module Language4Package {
41+
Query useOfObsoleteMacroAtomicVarInitQuery() {
42+
//autogenerate `Query` type
43+
result =
44+
// `Query` type for `useOfObsoleteMacroAtomicVarInit` query
45+
TQueryC(TLanguage4PackageQuery(TUseOfObsoleteMacroAtomicVarInitQuery()))
46+
}
47+
48+
Query invalidDefineOrUndefOfStdBoolMacroQuery() {
49+
//autogenerate `Query` type
50+
result =
51+
// `Query` type for `invalidDefineOrUndefOfStdBoolMacro` query
52+
TQueryC(TLanguage4PackageQuery(TInvalidDefineOrUndefOfStdBoolMacroQuery()))
53+
}
54+
55+
Query callToReallocWithSizeZeroQuery() {
56+
//autogenerate `Query` type
57+
result =
58+
// `Query` type for `callToReallocWithSizeZero` query
59+
TQueryC(TLanguage4PackageQuery(TCallToReallocWithSizeZeroQuery()))
60+
}
61+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import InvalidMemory2
3939
import Language1
4040
import Language2
4141
import Language3
42+
import Language4
4243
import Memory1
4344
import Memory2
4445
import Memory3
@@ -112,6 +113,7 @@ newtype TCQuery =
112113
TLanguage1PackageQuery(Language1Query q) or
113114
TLanguage2PackageQuery(Language2Query q) or
114115
TLanguage3PackageQuery(Language3Query q) or
116+
TLanguage4PackageQuery(Language4Query q) or
115117
TMemory1PackageQuery(Memory1Query q) or
116118
TMemory2PackageQuery(Memory2Query q) or
117119
TMemory3PackageQuery(Memory3Query q) or
@@ -185,6 +187,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
185187
isLanguage1QueryMetadata(query, queryId, ruleId, category) or
186188
isLanguage2QueryMetadata(query, queryId, ruleId, category) or
187189
isLanguage3QueryMetadata(query, queryId, ruleId, category) or
190+
isLanguage4QueryMetadata(query, queryId, ruleId, category) or
188191
isMemory1QueryMetadata(query, queryId, ruleId, category) or
189192
isMemory2QueryMetadata(query, queryId, ruleId, category) or
190193
isMemory3QueryMetadata(query, queryId, ruleId, category) or

rule_packages/c/Language4.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"MISRA-C-2012": {
3+
"RULE-1-5": {
4+
"properties": {
5+
"obligation": "required"
6+
},
7+
"queries": [
8+
{
9+
"description": "The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since C18.",
10+
"kind": "problem",
11+
"name": "Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18",
12+
"precision": "very-high",
13+
"severity": "recommendation",
14+
"short_name": "UseOfObsoleteMacroAtomicVarInit",
15+
"tags": [
16+
"maintainability",
17+
"readability"
18+
]
19+
},
20+
{
21+
"description": "Directives that undefine and/or redefine the standard boolean macros has been declared an obsolescent language feature since C99.",
22+
"kind": "problem",
23+
"name": "Programs may not undefine or redefine the macros bool, true, or false",
24+
"precision": "very-high",
25+
"severity": "warning",
26+
"short_name": "InvalidDefineOrUndefOfStdBoolMacro",
27+
"tags": [
28+
"maintainability",
29+
"readability"
30+
]
31+
},
32+
{
33+
"description": "Invoking realloc with a size argument set to zero is implementation-defined behavior and declared as an obsolete feature in C18.",
34+
"kind": "problem",
35+
"name": "Disallowed size argument value equal to zero in call to realloc",
36+
"precision": "very-high",
37+
"severity": "error",
38+
"short_name": "CallToReallocWithSizeZero",
39+
"tags": [
40+
"correctness"
41+
]
42+
}
43+
],
44+
"title": "Obsolencent language features shall not be used"
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)