Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Language4 package, banning obsolete language features. #730

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// GENERATED FILE - DO NOT MODIFY
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared

class TestFileQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery, TestQuery { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// GENERATED FILE - DO NOT MODIFY
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared

class TestFileQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery, TestQuery {
}
22 changes: 22 additions & 0 deletions c/misra/src/rules/RULE-1-5/CallToObsolescentFunctionGets.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @id c/misra/call-to-obsolescent-function-gets
* @name RULE-1-5: Disallowed usage of obsolescent function 'gets'
* @description The function 'gets' is an obsolescent language feature which was removed in C11.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-1-5
* external/misra/c/2012/amendment3
* security
* maintainability
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra

from FunctionCall fc
where
not isExcluded(fc, Language4Package::callToObsolescentFunctionGetsQuery()) and
fc.getTarget().hasGlobalOrStdName("gets")
select fc, "Call to obsolescent function 'gets'."
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/function-types-not-in-prototype-form-obsolete
* @name RULE-1-5: Function types shall be in prototype form with named parameters
* @description The use of non-prototype format parameter type declarators is an obsolescent
* language feature.
* @kind problem
* @precision medium
* @problem.severity error
* @tags external/misra/id/rule-1-5
* correctness
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared

class FunctionTypesNotInPrototypeFormObsoleteQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery
{
FunctionTypesNotInPrototypeFormObsoleteQuery() {
this = Language4Package::functionTypesNotInPrototypeFormObsoleteQuery()
}
}
32 changes: 32 additions & 0 deletions c/misra/src/rules/RULE-1-5/InvalidDefineOrUndefOfStdBoolMacro.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @id c/misra/invalid-define-or-undef-of-std-bool-macro
* @name RULE-1-5: Programs may not undefine or redefine the macros bool, true, or false
* @description Directives that undefine and/or redefine the standard boolean macros has been
* declared an obsolescent language feature since C99.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-1-5
* maintainability
* readability
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra

string getABoolMacroName() { result = ["true", "false", "bool"] }

from PreprocessorDirective directive, string opString, string macroName
where
not isExcluded(directive, Language4Package::invalidDefineOrUndefOfStdBoolMacroQuery()) and
macroName = getABoolMacroName() and
(
macroName = directive.(Macro).getName() and
opString = "define"
or
macroName = directive.(PreprocessorUndef).getName() and
opString = "undefine"
)
select directive, "Invalid " + opString + " of boolean standard macro '" + macroName + "'."
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/missing-static-specifier-func-redeclaration-obsolete
* @name RULE-1-5: If a function has internal linkage then all re-declarations shall include the static storage class
* @description Declaring a function with internal linkage without the static storage class
* specifier is an obselescent feature.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-1-5
* readability
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.missingstaticspecifierfunctionredeclarationshared.MissingStaticSpecifierFunctionRedeclarationShared

class MissingStaticSpecifierFuncRedeclarationObsoleteQuery extends MissingStaticSpecifierFunctionRedeclarationSharedSharedQuery
{
MissingStaticSpecifierFuncRedeclarationObsoleteQuery() {
this = Language4Package::missingStaticSpecifierFuncRedeclarationObsoleteQuery()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/missing-static-specifier-object-redeclaration-obsolete
* @name RULE-1-5: If an object has internal linkage then all re-declarations shall include the static storage class
* @description Declaring an identifier with internal linkage without the static storage class
* specifier is an obselescent feature.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-1-5
* readability
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared

class MissingStaticSpecifierObjectRedeclarationObsoleteQuery extends MissingStaticSpecifierObjectRedeclarationSharedSharedQuery
{
MissingStaticSpecifierObjectRedeclarationObsoleteQuery() {
this = Language4Package::missingStaticSpecifierObjectRedeclarationObsoleteQuery()
}
}
26 changes: 26 additions & 0 deletions c/misra/src/rules/RULE-1-5/SizeInReallocCallIsZero.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @id c/misra/size-in-realloc-call-is-zero
* @name RULE-1-5: Size argument value in realloc call is equal zero
* @description Invoking realloc with a size argument set to zero is implementation-defined behavior
* and declared as an obsolete feature in C18.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-1-5
* correctness
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import semmle.code.cpp.rangeanalysis.new.RangeAnalysis
import codingstandards.cpp.Realloc

from ReallocCall call
where
not isExcluded(call, Language4Package::sizeInReallocCallIsZeroQuery()) and
call.sizeIsExactlyZero()
select call,
"Size argument '$@' may equal zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
call.getSizeArgument(), call.getSizeArgument().toString()
26 changes: 26 additions & 0 deletions c/misra/src/rules/RULE-1-5/SizeInReallocCallMayBeZero.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* @id c/misra/size-in-realloc-call-may-be-zero
* @name RULE-1-5: Size argument value in realloc call may equal zero
* @description Invoking realloc with a size argument set to zero is implementation-defined behavior
* and declared as an obsolete feature in C18.
* @kind problem
* @precision medium
* @problem.severity error
* @tags external/misra/id/rule-1-5
* correctness
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Realloc

from ReallocCall call
where
not isExcluded(call, Language4Package::sizeInReallocCallMayBeZeroQuery()) and
call.sizeMayBeZero() and
not call.sizeIsExactlyZero()
select call,
"Size argument '$@' equals zero in realloc call, resulting in obsolescent and/or implementation-defined behavior.",
call.getSizeArgument(), call.getSizeArgument().toString()
81 changes: 81 additions & 0 deletions c/misra/src/rules/RULE-1-5/UngetcCallOnStreamPositionZero.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/**
* @id c/misra/ungetc-call-on-stream-position-zero
* @name RULE-1-5: Disallowed obsolescent usage of 'ungetc' on a file stream at position zero
* @description Calling the function 'ungetc' on a file stream with a position of zero is an
* obsolescent language feature.
* @kind path-problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-1-5
* external/misra/c/2012/amendment3
* security
* maintainability
* external/misra/obligation/required
*/

import cpp
import semmle.code.cpp.dataflow.new.DataFlow
import semmle.code.cpp.controlflow.Dominance
import codingstandards.c.misra

/**
* This is an inconclusive list, which is adequate, as RULE-21-3 provides
* assurance we won't have false negatives, or care too much about false
* positives.
*/
class MoveStreamPositionCall extends FunctionCall {
Expr streamArgument;

MoveStreamPositionCall() {
getTarget().hasGlobalOrStdName("fgetc") and
streamArgument = getArgument(0)
or
getTarget().hasGlobalOrStdName("getc") and
streamArgument = getArgument(0)
or
getTarget().hasGlobalOrStdName("fget") and
streamArgument = getArgument(2)
or
getTarget().hasGlobalOrStdName("fscanf") and
streamArgument = getArgument(0)
or
getTarget().hasGlobalOrStdName("fsetpos") and
streamArgument = getArgument(0)
or
getTarget().hasGlobalOrStdName("fseek") and
streamArgument = getArgument(0)
or
getTarget().hasGlobalOrStdName("fread") and
streamArgument = getArgument(3)
}

Expr getStreamArgument() { result = streamArgument }
}

module FilePositionZeroFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
node.asIndirectExpr().(FunctionCall).getTarget().hasGlobalOrStdName("fopen")
}

predicate isSink(DataFlow::Node node) {
exists(FunctionCall fc |
fc.getTarget().hasGlobalOrStdName("ungetc") and
node.asIndirectExpr() = fc.getArgument(1)
)
}

predicate isBarrierIn(DataFlow::Node node) {
exists(MoveStreamPositionCall fc | node.asIndirectExpr() = fc.getStreamArgument())
}
}

module FilePositionZeroFlow = DataFlow::Global<FilePositionZeroFlowConfig>;

import FilePositionZeroFlow::PathGraph

from FilePositionZeroFlow::PathNode sink, FilePositionZeroFlow::PathNode source
where
not isExcluded(sink.getNode().asExpr(), Language4Package::ungetcCallOnStreamPositionZeroQuery()) and
FilePositionZeroFlow::flowPath(source, sink)
select sink.getNode(), source, sink,
"Obsolescent call to ungetc on file stream $@ at position zero.", source, source.toString()
24 changes: 24 additions & 0 deletions c/misra/src/rules/RULE-1-5/UseOfObsoleteMacroAtomicVarInit.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @id c/misra/use-of-obsolete-macro-atomic-var-init
* @name RULE-1-5: Disallowed usage of obsolete macro ATOMIC_VAR_INIT compiled as C18
* @description The macro ATOMIC_VAR_INIT is has been declared an obsolescent language feature since
* C18.
* @kind problem
* @precision very-high
* @problem.severity recommendation
* @tags external/misra/id/rule-1-5
* maintainability
* readability
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra

from MacroInvocation invoke
where
not isExcluded(invoke, Language4Package::useOfObsoleteMacroAtomicVarInitQuery()) and
invoke.getMacroName() = "ATOMIC_VAR_INIT"
select invoke,
"Usage of macro ATOMIC_VAR_INIT() is declared obscelescent in C18, and discouraged in earlier C versions."
44 changes: 5 additions & 39 deletions c/misra/src/rules/RULE-8-2/FunctionTypesNotInPrototypeForm.ql
Original file line number Diff line number Diff line change
Expand Up @@ -14,44 +14,10 @@

import cpp
import codingstandards.c.misra
import codingstandards.cpp.Identifiers
import codingstandards.cpp.rules.functiontypesnotinprototypeformshared.FunctionTypesNotInPrototypeFormShared

/**
* `Parameter`s without names
*/
class UnnamedParameter extends Parameter {
UnnamedParameter() { not this.isNamed() }
class FunctionTypesNotInPrototypeFormQuery extends FunctionTypesNotInPrototypeFormSharedSharedQuery {
FunctionTypesNotInPrototypeFormQuery() {
this = Declarations4Package::functionTypesNotInPrototypeFormQuery()
}
}

/*
* This is a copy of the private `hasZeroParamDecl` predicate from the standard set of
* queries as of the `codeql-cli/2.11.2` tag in `github/codeql`.
*/

predicate hasZeroParamDecl(Function f) {
exists(FunctionDeclarationEntry fde | fde = f.getADeclarationEntry() |
not fde.isImplicit() and
not fde.hasVoidParamList() and
fde.getNumberOfParameters() = 0 and
not fde.isDefinition()
)
}

from Function f, string msg
where
not isExcluded(f, Declarations4Package::functionTypesNotInPrototypeFormQuery()) and
f instanceof InterestingIdentifiers and
(
f.getAParameter() instanceof UnnamedParameter and
msg = "Function " + f + " declares parameter that is unnamed."
or
hasZeroParamDecl(f) and
msg = "Function " + f + " does not specify void for no parameters present."
or
//parameters declared in declaration list (not in function signature)
//have no prototype
not f.isPrototyped() and
not hasZeroParamDecl(f) and
msg = "Function " + f + " declares parameter in unsupported declaration list."
)
select f, msg
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,11 @@

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.missingstaticspecifierobjectredeclarationshared.MissingStaticSpecifierObjectRedeclarationShared

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