Skip to content

Commit

Permalink
Merge branch 'main' into codeql/upgrade-to-2.16.6
Browse files Browse the repository at this point in the history
  • Loading branch information
lcartey authored Oct 22, 2024
2 parents 68c1daf + f9070ca commit f718e2a
Show file tree
Hide file tree
Showing 109 changed files with 2,359 additions and 135 deletions.
24 changes: 24 additions & 0 deletions apply-configuration/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Applies Coding Standard configuration files in the repository
description: |
Installs Python and indexes the CodeQL Coding Standard configuration files in the repository
runs:
using: composite
steps:
- name: Install Python
id: cs-install-python
uses: actions/setup-python@v5
with:
python-version: 3.9
update-environment: false
- name: Install dependencies and process files
shell: bash
run: |
install_dir=$(dirname $(dirname "${{ steps.cs-install-python.outputs.python-path }}"))
if [[ -z "$LD_LIBRARY_PATH" ]]; then
export LD_LIBRARY_PATH="$install_dir/lib"
else
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$install_dir/lib"
fi
${{ steps.cs-install-python.outputs.python-path }} -m pip install -r ${GITHUB_ACTION_PATH}/../scripts/configuration/requirements.txt
${{ steps.cs-install-python.outputs.python-path }} ${GITHUB_ACTION_PATH}/../scripts/configuration/process_coding_standards_config.py
2 changes: 1 addition & 1 deletion c/cert/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/cert-c-coding-standards
version: 2.36.0-dev
version: 2.37.0-dev
description: CERT C 2016
suites: codeql-suites
license: MIT
Expand Down
2 changes: 1 addition & 1 deletion c/cert/test/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/cert-c-coding-standards-tests
version: 2.36.0-dev
version: 2.37.0-dev
extractor: cpp
license: MIT
dependencies:
Expand Down
2 changes: 1 addition & 1 deletion c/common/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/common-c-coding-standards
version: 2.36.0-dev
version: 2.37.0-dev
license: MIT
dependencies:
codeql/common-cpp-coding-standards: '*'
Expand Down
2 changes: 1 addition & 1 deletion c/common/test/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/common-c-coding-standards-tests
version: 2.36.0-dev
version: 2.37.0-dev
extractor: cpp
license: MIT
dependencies:
Expand Down
48 changes: 44 additions & 4 deletions c/misra/src/codingstandards/c/misra/EssentialTypes.qll
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,17 @@ EssentialTypeCategory getEssentialTypeCategory(Type type) {
essentialType.(IntegralType).isSigned() and
not essentialType instanceof PlainCharType
or
// Anonymous enums are considered to be signed
result = EssentiallySignedType() and
essentialType instanceof AnonymousEnumType and
not essentialType instanceof MisraBoolType
or
result = EssentiallyUnsignedType() and
essentialType.(IntegralType).isUnsigned() and
not essentialType instanceof PlainCharType
or
result = EssentiallyEnumType() and
essentialType instanceof Enum and
essentialType instanceof NamedEnumType and
not essentialType instanceof MisraBoolType
or
result = EssentiallyFloatingType() and
Expand Down Expand Up @@ -348,16 +353,51 @@ class EssentialBinaryArithmeticExpr extends EssentialExpr, BinaryArithmeticOpera
}
}

/**
* A named Enum type, as per D.5.
*/
class NamedEnumType extends Enum {
NamedEnumType() {
not isAnonymous()
or
exists(Type useOfEnum | this = useOfEnum.stripType() |
exists(TypedefType t | t.getBaseType() = useOfEnum)
or
exists(Function f | f.getType() = useOfEnum or f.getAParameter().getType() = useOfEnum)
or
exists(Struct s | s.getAField().getType() = useOfEnum)
or
exists(Variable v | v.getType() = useOfEnum)
)
}
}

/**
* An anonymous Enum type, as per D.5.
*/
class AnonymousEnumType extends Enum {
AnonymousEnumType() { not this instanceof NamedEnumType }
}

/**
* The EssentialType of an EnumConstantAccess, which may be essentially enum or essentially signed.
*/
class EssentialEnumConstantAccess extends EssentialExpr, EnumConstantAccess {
override Type getEssentialType() { result = getTarget().getDeclaringEnum() }
override Type getEssentialType() {
exists(Enum e | e = getTarget().getDeclaringEnum() |
if e instanceof NamedEnumType then result = e else result = stlr(this)
)
}
}

class EssentialLiteral extends EssentialExpr, Literal {
override Type getEssentialType() {
if this instanceof BooleanLiteral
then result instanceof MisraBoolType
then
// This returns a multitude of types - not sure if we really want that
result instanceof MisraBoolType
else (
if this.(CharLiteral).getCharacter().length() = 1
if this instanceof CharLiteral
then result instanceof PlainCharType
else
exists(Type underlyingStandardType |
Expand Down
2 changes: 1 addition & 1 deletion c/misra/src/qlpack.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: codeql/misra-c-coding-standards
version: 2.36.0-dev
version: 2.37.0-dev
description: MISRA C 2012
suites: codeql-suites
license: MIT
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ where
// be reported as non-compliant.
leftOpTypeCategory = EssentiallyEnumType() and
rightOpTypeCategory = EssentiallyEnumType() and
not leftOpEssentialType = rightOpEssentialType and
not leftOpEssentialType.getUnspecifiedType() = rightOpEssentialType.getUnspecifiedType() and
message =
"The operands of this operator with usual arithmetic conversions have mismatched essentially Enum types (left operand: "
+ leftOpEssentialType + ", right operand: " + rightOpEssentialType + ")."
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import codingstandards.cpp.Pointers
from Cast cast, VoidPointerType type, PointerToObjectType newType
where
not isExcluded(cast, Pointers1Package::conversionFromPointerToVoidIntoPointerToObjectQuery()) and
type = cast.getExpr().getUnderlyingType() and
type = cast.getExpr().getUnspecifiedType() and
newType = cast.getUnderlyingType() and
not isNullPointerConstant(cast.getExpr())
select cast,
Expand Down
81 changes: 78 additions & 3 deletions c/misra/src/rules/RULE-2-2/DeadCode.ql
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,83 @@

import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.deadcode.DeadCode
import codingstandards.cpp.alertreporting.HoldsForAllCopies
import codingstandards.cpp.deadcode.UselessAssignments

class MisraCDeadCodeQuery extends DeadCodeSharedQuery {
MisraCDeadCodeQuery() { this = DeadCodePackage::deadCodeQuery() }
/**
* Gets an explicit cast from `e` if one exists.
*/
Cast getExplicitCast(Expr e) {
exists(Conversion c | c = e.getExplicitlyConverted() |
result = c
or
result = c.(ParenthesisExpr).getExpr()
)
}

class ExprStmtExpr extends Expr {
ExprStmtExpr() { exists(ExprStmt es | es.getExpr() = this) }
}

/**
* An "operation" as defined by MISRA C Rule 2.2 that is dead, i.e. it's removal has no effect on
* the behaviour of the program.
*/
class DeadOperationInstance extends Expr {
string description;

DeadOperationInstance() {
// Exclude cases nested within macro expansions, because the code may be "live" in other
// expansions
isNotWithinMacroExpansion(this) and
exists(ExprStmtExpr e |
if exists(getExplicitCast(e))
then
this = getExplicitCast(e) and
// void conversions are permitted
not getExplicitCast(e) instanceof VoidConversion and
description = "Cast operation is unused"
else (
this = e and
(
if e instanceof Assignment
then
exists(SsaDefinition sd, LocalScopeVariable v |
e = sd.getDefinition() and
sd.getDefiningValue(v).isPure() and
// The definition is useless
isUselessSsaDefinition(sd, v) and
description = "Assignment to " + v.getName() + " is unused and has no side effects"
)
else (
e.isPure() and
description = "Result of operation is unused and has no side effects"
)
)
)
)
}

string getDescription() { result = description }
}

class DeadOperation = HoldsForAllCopies<DeadOperationInstance, Expr>::LogicalResultElement;

from
DeadOperation deadOperation, DeadOperationInstance instance, string message, Element explainer,
string explainerDescription
where
not isExcluded(instance, DeadCodePackage::deadCodeQuery()) and
instance = deadOperation.getAnElementInstance() and
if instance instanceof FunctionCall
then
message = instance.getDescription() + " from call to function $@" and
explainer = instance.(FunctionCall).getTarget() and
explainerDescription = explainer.(Function).getName()
else (
message = instance.getDescription() and
// Ignore the explainer
explainer = instance and
explainerDescription = ""
)
select deadOperation, message + ".", explainer, explainerDescription
23 changes: 23 additions & 0 deletions c/misra/src/rules/RULE-21-24/CallToBannedRandomFunction.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/**
* @id c/misra/call-to-banned-random-function
* @name RULE-21-24: The random number generator functions of <stdlib.h> shall not be used
* @description The standard functions rand() and srand() will not give high quality random results
* in all implementations and are therefore banned.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-21-24
* security
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra

from FunctionCall call, string name
where
not isExcluded(call, Banned2Package::callToBannedRandomFunctionQuery()) and
name = ["rand", "srand"] and
call.getTarget().hasGlobalOrStdName(name)
select call, "Call to banned random number generation function '" + name + "'."
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @id c/misra/incorrectly-sized-integer-constant-macro-argument
* @name RULE-7-5: The argument of an integer constant macro shall have an appropriate size
* @description Integer constant macros argument values should be values of a compatible size.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-7-5
* correctness
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.IntegerConstantMacro
import codingstandards.cpp.Literals

predicate matchesSign(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
literal.isNegative() implies macro.isSigned()
}

predicate matchesSize(IntegerConstantMacro macro, PossiblyNegativeLiteral literal) {
literal.getRawValue() <= macro.maxValue() and
literal.getRawValue() >= macro.minValue()
}

from
PossiblyNegativeLiteral literal, MacroInvocation invoke, IntegerConstantMacro macro,
string explanation
where
not isExcluded(invoke, Types2Package::incorrectlySizedIntegerConstantMacroArgumentQuery()) and
invoke.getMacro() = macro and
literal = invoke.getExpr() and
(
not matchesSign(macro, literal) and
explanation = " cannot be negative"
or
matchesSign(macro, literal) and
// Wait for BigInt support to check 64 bit macro types.
macro.getSize() < 64 and
not matchesSize(macro, literal) and
explanation = " is outside of the allowed range " + macro.getRangeString()
)
select literal, "Value provided to integer constant macro " + macro.getName() + explanation
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* @id c/misra/integer-constant-macro-argument-uses-suffix
* @name RULE-7-5: The argument of an integer constant macro shall not use literal suffixes u, l, or ul
* @description Integer constant macros should be used integer literal values with no u/l suffix.
* @kind problem
* @precision high
* @problem.severity warning
* @tags external/misra/id/rule-7-5
* readability
* maintainability
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.IntegerConstantMacro
import codingstandards.cpp.Literals

string argumentSuffix(MacroInvocation invoke) {
// Extractor strips the suffix unless we look at the unexpanded argument text.
// Unexpanded argument text can be malformed in all sorts of ways, so make
// this match relatively strict, to be safe.
result = invoke.getUnexpandedArgument(0).regexpCapture("([0-9]+|0[xX][0-9A-F]+)([uUlL]+)$", 2)
}

from MacroInvocation invoke, PossiblyNegativeLiteral argument, string suffix
where
not isExcluded(invoke, Types2Package::integerConstantMacroArgumentUsesSuffixQuery()) and
invoke.getMacro() instanceof IntegerConstantMacro and
invoke.getExpr() = argument and
suffix = argumentSuffix(invoke)
select argument,
"Value suffix '" + suffix + "' is not allowed on provided argument to integer constant macro " +
invoke.getMacroName() + "."
30 changes: 30 additions & 0 deletions c/misra/src/rules/RULE-7-5/InvalidIntegerConstantMacroArgument.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @id c/misra/invalid-integer-constant-macro-argument
* @name RULE-7-5: The argument of an integer constant macro shall be a literal
* @description Integer constant macros should be given a literal value as an argument.
* @kind problem
* @precision very-high
* @problem.severity warning
* @tags external/misra/id/rule-7-5
* correctness
* external/misra/c/2012/amendment3
* external/misra/obligation/required
*/

import cpp
import codingstandards.c.misra
import codingstandards.cpp.IntegerConstantMacro
import codingstandards.cpp.Literals
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis

from MacroInvocation invoke, IntegerConstantMacro macro
where
not isExcluded(invoke, Types2Package::invalidIntegerConstantMacroArgumentQuery()) and
invoke.getMacro() = macro and
(
not invoke.getExpr() instanceof PossiblyNegativeLiteral
or
any(MacroInvocation inner).getParentInvocation() = invoke
)
select invoke.getExpr(),
"Argument to integer constant macro " + macro.getName() + " must be an integer literal."
Loading

0 comments on commit f718e2a

Please sign in to comment.