Skip to content

Commit b778360

Browse files
Use shared queries / generally report obsolescent features even if redundant.
Redundant reports should not be a common user issue; these features are obsolescent and likely rarely used and less often to be excepted. Implement ungetc() on a zero-offset stream and specific banning of gets(), as the redundant rules for those obsolescent features report a far wider set of issues than banned by RULE-1-5. Implementation of banning ungetc() on a zero-offset stream is not thorough or comprehensive. This should be fine. False positives should not create any user issues because the call of the function overall is banned. And false negatives should not be an issue, for the same reason.
1 parent 730341f commit b778360

File tree

44 files changed

+450
-114
lines changed

Some content is hidden

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

44 files changed

+450
-114
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:3:6:3:7 | f1 | Function f1 declares parameter that is unnamed. |
2+
| test.c:4:6:4:7 | f2 | Function f2 does not specify void for no parameters present. |
3+
| test.c:5:6:5:7 | f3 | Function f3 does not specify void for no parameters present. |
4+
| test.c:7:5:7:6 | f5 | Function f5 declares parameter in unsupported declaration list. |
Lines changed: 4 additions & 0 deletions
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 { }

c/misra/test/rules/RULE-8-2/test.c renamed to c/common/test/rules/functiontypesnotinprototypeformshared/test.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
// Note: A subset of these cases are also tested in c/misra/test/rules/RULE-1-5
2-
// via a FunctionTypesNotInPrototypeForm.qlref and .expected file in that
3-
// directory. Changes to these tests may require updating the test code or
4-
// expectations in that directory as well.
5-
61
void f(int x); // COMPLIANT
72
void f0(void); // COMPLIANT
83
void f1(int); // NON_COMPLIANT
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:2:12:2:12 | declaration of g | The redeclaration of $@ with internal linkage misses the static specifier. | test.c:1:12:1:12 | definition of g | g |
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+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
static int g = 0;
2+
extern int g; // NON_COMPLIANT
3+
4+
static int g1;
5+
static int g1 = 0; // COMPLIANT
6+
7+
int g2;
8+
int g2 = 0; // COMPLIANT
Lines changed: 22 additions & 0 deletions
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'."
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
FunctionTypesNotInPrototypeFormObsoleteQuery() {
21+
this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery()
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
MissingStaticSpecifierFuncRedeclarationObsoleteQuery() {
21+
this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery()
22+
}
23+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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+
MissingStaticSpecifierObjectRedeclarationObsoleteQuery() {
21+
this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery()
22+
}
23+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
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 problem
7+
* @precision medium
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+
from FunctionCall ungetc, DataFlow::Node file
56+
where
57+
not isExcluded(ungetc, Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
58+
// ungetc() called on file stream
59+
ungetc.getTarget().hasGlobalOrStdName("ungetc") and
60+
DataFlow::localFlow(file, DataFlow::exprNode(ungetc.getArgument(1))) and
61+
// ungetc() is not dominated by a fread() etc to that file stream
62+
not exists(MoveStreamPositionCall moveStreamCall |
63+
DataFlow::localFlow(file, DataFlow::exprNode(moveStreamCall.getStreamArgument())) and
64+
dominates(moveStreamCall, ungetc)
65+
)
66+
// the file stream is the root of the local data flow
67+
and not DataFlow::localFlow(any(DataFlow::Node n | not n = file), file)
68+
select ungetc, "Obsolescent call to ungetc on file stream $@ at position zero.", file,
69+
file.toString()

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

Lines changed: 5 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +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 placeholder file location associated only
53-
exists(Parameter p |
54-
p.getFunction() = f and
55-
not p.getFile() = f.getFile() and
56-
msg = "Function " + f + " declares parameter in unsupported declaration list."
57-
)
58-
)
59-
select f, msg

c/misra/src/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.ql

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,10 @@
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+
MissingStaticSpecifierObjectRedeclarationCQuery() {
21+
this = Declarations5Package::missingStaticSpecifierObjectRedeclarationCQuery()
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:36:3:36:6 | call to gets | Call to obsolescent function 'gets'. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/CallToObsolescentFunctionGets.ql

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

Lines changed: 0 additions & 2 deletions
This file was deleted.

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql

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

Lines changed: 0 additions & 3 deletions
This file was deleted.

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/missingstaticspecifierfunctionredeclarationshared/MissingStaticSpecifierFunctionRedeclarationShared.ql

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

Lines changed: 0 additions & 1 deletion
This file was deleted.

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql

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

Lines changed: 0 additions & 3 deletions
This file was deleted.

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

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.c:40:3:40:8 | call to ungetc | Obsolescent call to ungetc on file stream $@ at position zero. | test.c:38:16:38:20 | call to fopen | call to fopen |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql

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

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
#include "stdlib.h"
55

66
void f1(void) {
7-
// malloc() is not obsolete, but banned by Rule 21.3
8-
int *t = malloc(10); // COMPLIANT[False Negative]
7+
// malloc() is not obsolete, though it is banned by Rule 21.3
8+
int *t = malloc(10); // COMPLIANT
99

1010
// Obsolete usage of realloc.
1111
realloc(t, 0); // NON-COMPLIANT
@@ -28,32 +28,19 @@ const extern int g2; // NON-COMPLIANT
2828
_Atomic int g3 = ATOMIC_VAR_INIT(18); // NON-COMPLIANT
2929
_Atomic int g4 = 18; // COMPLIANT
3030

31-
// The following cases are already covered by other rules:
32-
33-
// Rule 8.8:
34-
static int g5 = 3; // COMPLIANT
35-
extern int g5; // NON-COMPLIANT
36-
37-
// Rule 8.2:
38-
void f2(); // NON-COMPLIANT
39-
void f3(void); // COMPLIANT
40-
41-
void f4(int p1){}; // COMPLIANT
42-
int f5(x) // NON_COMPLIANT
43-
int x;
44-
{ return 1; }
31+
// `gets` was removed from C11.
32+
extern char* gets(FILE *stream);
4533

4634
// Rule 21.6 covers the below cases:
4735
void f6(void) {
48-
// `gets` was removed from C11.
49-
// gets(stdin); // NON_COMPLIANT
36+
gets(stdin); // NON_COMPLIANT
5037

5138
FILE *file = fopen("", 0);
5239
// Obsolete usage of ungetc.
5340
ungetc('c', file); // NON-COMPLIANT
5441

5542
char buf[10];
5643
fread(buf, sizeof(buf), 10, file);
57-
// This is not an obsolete usage of ungetc, but ungetc isn't allowed.
58-
ungetc('c', file); // NON-COMPLIANT[FALSE NEGATIVE]
44+
// This is not an obsolete usage of ungetc, though ungetc isn't allowed by 21-3.
45+
ungetc('c', file); // COMPLIANT
5946
}

c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.expected

Lines changed: 0 additions & 4 deletions
This file was deleted.

c/misra/test/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/functiontypesnotinprototypeformshared/FunctionTypesNotInPrototypeFormShared.ql

c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.expected

Lines changed: 0 additions & 1 deletion
This file was deleted.

c/misra/test/rules/RULE-8-8/MissingStaticSpecifierObjectRedeclarationC.qlref

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/missingstaticspecifierobjectredeclarationshared/MissingStaticSpecifierObjectRedeclarationShared.ql

0 commit comments

Comments
 (0)