Skip to content

Commit 373b793

Browse files
Merge pull request #730 from github/michaelrfairhurst/implement-lanugage4-package-rule-1-5
Implement Language4 package, banning obsolete language features.
2 parents 85036d5 + b1c7619 commit 373b793

File tree

52 files changed

+836
-79
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+836
-79
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
3+
4+
class TestFileQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery, TestQuery { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
3+
4+
class TestFileQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery, TestQuery {
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* @id c/misra/call-to-obsolescent-function-gets
3+
* @name RULE-1-5: Disallowed usage of obsolescent function 'gets'
4+
* @description The function 'gets' is an obsolescent language feature which was removed in C11.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-1-5
9+
* external/misra/c/2012/amendment3
10+
* security
11+
* maintainability
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
18+
from FunctionCall fc
19+
where
20+
not isExcluded(fc, Language4Package::callToObsolescentFunctionGetsQuery()) and
21+
fc.getTarget().hasGlobalOrStdName("gets")
22+
select fc, "Call to obsolescent function 'gets'."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/function-types-not-in-prototype-form-obsolete
3+
* @name RULE-1-5: Function types shall be in prototype form with named parameters
4+
* @description The use of non-prototype format parameter type declarators is an obsolescent
5+
* language feature.
6+
* @kind problem
7+
* @precision medium
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-1-5
10+
* correctness
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
18+
19+
class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery
20+
{
21+
FunctionTypesNotInPrototypeFormObsoleteQuery() {
22+
this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery()
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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/c/2012/amendment3
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
19+
string getABoolMacroName() { result = ["true", "false", "bool"] }
20+
21+
from PreprocessorDirective directive, string opString, string macroName
22+
where
23+
not isExcluded(directive, Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery()) and
24+
macroName = getABoolMacroName() and
25+
(
26+
macroName = directive.(Macro).getName() and
27+
opString = "define"
28+
or
29+
macroName = directive.(PreprocessorUndef).getName() and
30+
opString = "undefine"
31+
)
32+
select directive, "Invalid " + opString + " of boolean standard macro '" + macroName + "'."
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/missing-static-specifier-func-redeclaration-obsolete
3+
* @name RULE-1-5: If a function has internal linkage then all re-declarations shall include the static storage class
4+
* @description Declaring a function with internal linkage without the static storage class
5+
* specifier is an obselescent feature.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-1-5
10+
* readability
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.missingstaticspecifierfunctionredeclarationshared.MissingStaticSpecifierFunctionRedeclarationShared
18+
19+
class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery
20+
{
21+
MissingStaticSpecifierFuncRedeclarationObsoleteQuery() {
22+
this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery()
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/missing-static-specifier-object-redeclaration-obsolete
3+
* @name RULE-1-5: If an object has internal linkage then all re-declarations shall include the static storage class
4+
* @description Declaring an identifier with internal linkage without the static storage class
5+
* specifier is an obselescent feature.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-1-5
10+
* readability
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
18+
19+
class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery
20+
{
21+
MissingStaticSpecifierObjectRedeclarationObsoleteQuery() {
22+
this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery()
23+
}
24+
}
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id c/misra/size-in-realloc-call-is-zero
3+
* @name RULE-1-5: Size argument value in realloc call is equal zero
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/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import semmle.code.cpp.rangeanalysis.new.RangeAnalysis
18+
import codingstandards.cpp.Realloc
19+
20+
from ReallocCall call
21+
where
22+
not isExcluded(call, Language4Package::sizeInReallocCallIsZeroQuery()) and
23+
call.sizeIsExactlyZero()
24+
select call,
25+
"Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
26+
call.getSizeArgument(), call.getSizeArgument().toString()
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/**
2+
* @id c/misra/size-in-realloc-call-may-be-zero
3+
* @name RULE-1-5: Size argument value in realloc call may equal zero
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 medium
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-1-5
10+
* correctness
11+
* external/misra/c/2012/amendment3
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.Realloc
18+
19+
from ReallocCall call
20+
where
21+
not isExcluded(call, Language4Package::sizeInReallocCallMayBeZeroQuery()) and
22+
call.sizeMayBeZero() and
23+
not call.sizeIsExactlyZero()
24+
select call,
25+
"Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
26+
call.getSizeArgument(), call.getSizeArgument().toString()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/**
2+
* @id c/misra/ungetc-call-on-stream-position-zero
3+
* @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero
4+
* @description Calling the function 'ungetc' on a file stream with a position of zero is an
5+
* obsolescent language feature.
6+
* @kind path-problem
7+
* @precision high
8+
* @problem.severity error
9+
* @tags external/misra/id/rule-1-5
10+
* external/misra/c/2012/amendment3
11+
* security
12+
* maintainability
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import semmle.code.cpp.dataflow.new.DataFlow
18+
import semmle.code.cpp.controlflow.Dominance
19+
import codingstandards.c.misra
20+
21+
/**
22+
* This is an inconclusive list, which is adequate, as RULE-21-3 provides
23+
* assurance we won't have false negatives, or care too much about false
24+
* positives.
25+
*/
26+
class MoveStreamPositionCall extends FunctionCall {
27+
Expr streamArgument;
28+
29+
MoveStreamPositionCall() {
30+
getTarget().hasGlobalOrStdName("fgetc") and
31+
streamArgument = getArgument(0)
32+
or
33+
getTarget().hasGlobalOrStdName("getc") and
34+
streamArgument = getArgument(0)
35+
or
36+
getTarget().hasGlobalOrStdName("fget") and
37+
streamArgument = getArgument(2)
38+
or
39+
getTarget().hasGlobalOrStdName("fscanf") and
40+
streamArgument = getArgument(0)
41+
or
42+
getTarget().hasGlobalOrStdName("fsetpos") and
43+
streamArgument = getArgument(0)
44+
or
45+
getTarget().hasGlobalOrStdName("fseek") and
46+
streamArgument = getArgument(0)
47+
or
48+
getTarget().hasGlobalOrStdName("fread") and
49+
streamArgument = getArgument(3)
50+
}
51+
52+
Expr getStreamArgument() { result = streamArgument }
53+
}
54+
55+
module FilePositionZeroFlowConfig implements DataFlow::ConfigSig {
56+
predicate isSource(DataFlow::Node node) {
57+
node.asIndirectExpr().(FunctionCall).getTarget().hasGlobalOrStdName("fopen")
58+
}
59+
60+
predicate isSink(DataFlow::Node node) {
61+
exists(FunctionCall fc |
62+
fc.getTarget().hasGlobalOrStdName("ungetc") and
63+
node.asIndirectExpr() = fc.getArgument(1)
64+
)
65+
}
66+
67+
predicate isBarrierIn(DataFlow::Node node) {
68+
exists(MoveStreamPositionCall fc | node.asIndirectExpr() = fc.getStreamArgument())
69+
}
70+
}
71+
72+
module FilePositionZeroFlow = DataFlow::Global<FilePositionZeroFlowConfig>;
73+
74+
import FilePositionZeroFlow::PathGraph
75+
76+
from FilePositionZeroFlow::PathNode sink, FilePositionZeroFlow::PathNode source
77+
where
78+
not isExcluded(sink.getNode().asExpr(), Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
79+
FilePositionZeroFlow::flowPath(source, sink)
80+
select sink.getNode(), source, sink,
81+
"Obsolescent call to ungetc on file stream $@ at position zero.", source, source.toString()
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/c/2012/amendment3
13+
* external/misra/obligation/required
14+
*/
15+
16+
import cpp
17+
import codingstandards.c.misra
18+
19+
from MacroInvocation invoke
20+
where
21+
not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and
22+
invoke.getMacroName() = "ATOMIC_VAR_INIT"
23+
select invoke,
24+
"Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions."

Diff for: c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql

+5-39
Original file line numberDiff line numberDiff line change
@@ -14,44 +14,10 @@
1414

1515
import cpp
1616
import codingstandards.c.misra
17-
import codingstandards.cpp.Identifiers
17+
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared
1818

19-
/**
20-
* `Parameter`s without names
21-
*/
22-
class UnnamedParameter extends Parameter {
23-
UnnamedParameter() { not this.isNamed() }
19+
class FunctionTypesNotInPrototypeFormQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery {
20+
FunctionTypesNotInPrototypeFormQuery() {
21+
this = Declarations4Package::functionTypesNotInPrototypeFormQuery()
22+
}
2423
}
25-
26-
/*
27-
* This is a copy of the private `hasZeroParamDecl` predicate from the standard set of
28-
* queries as of the `codeql-cli/2.11.2` tag in `github/codeql`.
29-
*/
30-
31-
predicate hasZeroParamDecl(Function f) {
32-
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
33-
not fde.isImplicit() and
34-
not fde.hasVoidParamList() and
35-
fde.getNumberOfParameters() = 0 and
36-
not fde.isDefinition()
37-
)
38-
}
39-
40-
from Function f, string msg
41-
where
42-
not isExcluded(f, Declarations4Package::functionTypesNotInPrototypeFormQuery()) and
43-
f instanceof InterestingIdentifiers and
44-
(
45-
f.getAParameter() instanceof UnnamedParameter and
46-
msg = "Function " + f + " declares parameter that is unnamed."
47-
or
48-
hasZeroParamDecl(f) and
49-
msg = "Function " + f + " does not specify void for no parameters present."
50-
or
51-
//parameters declared in declaration list (not in function signature)
52-
//have no prototype
53-
not f.isPrototyped() and
54-
not hasZeroParamDecl(f) and
55-
msg = "Function " + f + " declares parameter in unsupported declaration list."
56-
)
57-
select f, msg

Diff for: c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql

+7-11
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,11 @@
1414

1515
import cpp
1616
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared
1718

18-
from VariableDeclarationEntry redeclaration, VariableDeclarationEntry de
19-
where
20-
not isExcluded(redeclaration,
21-
Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()) and
22-
//following implies de != redeclaration
23-
de.hasSpecifier("static") and
24-
not redeclaration.hasSpecifier("static") and
25-
de.getDeclaration().isTopLevel() and
26-
redeclaration.getDeclaration() = de.getDeclaration()
27-
select redeclaration, "The redeclaration of $@ with internal linkage misses the static specifier.",
28-
de, de.getName()
19+
class MissingStaticSpecifierObjectRedeclarationCQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery
20+
{
21+
MissingStaticSpecifierObjectRedeclarationCQuery() {
22+
this = Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:37:3:37:6 | call to gets | Call to obsolescent function 'gets'. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/CallToObsolescentFunctionGets.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
| test.c:22:1:22:14 | #define true 3 | Invalid define of boolean standard macro 'true'. |
2+
| test.c:23:1:23:15 | #define false 3 | Invalid define of boolean standard macro 'false'. |
3+
| test.c:24:1:24:18 | #define bool int * | Invalid define of boolean standard macro 'bool'. |
4+
| test.c:25:1:25:11 | #undef true | Invalid undefine of boolean standard macro 'true'. |
5+
| test.c:26:1:26:12 | #undef false | Invalid undefine of boolean standard macro 'false'. |
6+
| test.c:27:1:27:11 | #undef bool | Invalid undefine of boolean standard macro 'bool'. |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/missingstaticspecifierfunctionredeclarationshared/MissingStaticSpecifierFunctionRedeclarationShared.ql
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql

0 commit comments

Comments
 (0)