Merge pull request #791 from github/michaelrfairhurst/concurrency6-package

Implement Concurrency6 package -- split out Concurrency7
This commit is contained in:
Luke Cartey 2025-01-29 10:30:36 +00:00 коммит произвёл GitHub
Родитель a74e904ba6 22e4fd3e07
Коммит 55362d0c6d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
37 изменённых файлов: 1156 добавлений и 67 удалений

Просмотреть файл

@ -14,37 +14,10 @@
import cpp
import codingstandards.c.cert
import codingstandards.cpp.Concurrency
import codingstandards.cpp.rules.joinordetachthreadonlyonce.JoinOrDetachThreadOnlyOnce
// OK
// 1) Thread calls detach parent DOES NOT call join
// 2) Parent calls join, thread does NOT call detach()
// NOT OK
// 1) Thread calls detach, parent calls join
// 2) Thread calls detach twice, parent does not call join
// 3) Parent calls join twice, thread does not call detach
from C11ThreadCreateCall tcc
where
not isExcluded(tcc, Concurrency5Package::threadWasPreviouslyJoinedOrDetachedQuery()) and
// Note: These cases can be simplified but they are presented like this for clarity
// case 1 - calls to `thrd_join` and `thrd_detach` within the parent or
// within the parent / child CFG.
exists(C11ThreadWait tw, C11ThreadDetach dt |
tw = getAThreadContextAwareSuccessor(tcc) and
dt = getAThreadContextAwareSuccessor(tcc)
)
or
// case 2 - multiple calls to `thrd_detach` within the threaded CFG.
exists(C11ThreadDetach dt1, C11ThreadDetach dt2 |
dt1 = getAThreadContextAwareSuccessor(tcc) and
dt2 = getAThreadContextAwareSuccessor(tcc) and
not dt1 = dt2
)
or
// case 3 - multiple calls to `thrd_join` within the threaded CFG.
exists(C11ThreadWait tw1, C11ThreadWait tw2 |
tw1 = getAThreadContextAwareSuccessor(tcc) and
tw2 = getAThreadContextAwareSuccessor(tcc) and
not tw1 = tw2
)
select tcc, "Thread may call join or detach after the thread is joined or detached."
class ThreadWasPreviouslyJoinedOrDetachedQuery extends JoinOrDetachThreadOnlyOnceSharedQuery {
ThreadWasPreviouslyJoinedOrDetachedQuery() {
this = Concurrency5Package::threadWasPreviouslyJoinedOrDetachedQuery()
}
}

Просмотреть файл

@ -1 +0,0 @@
rules/CON39-C/ThreadWasPreviouslyJoinedOrDetached.ql

Просмотреть файл

@ -0,0 +1 @@
c/common/test/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.ql

Просмотреть файл

@ -1,6 +1,6 @@
| test.c:7:18:7:39 | ATOMIC_VAR_INIT(value) | Atomic variable possibly referred to twice in an $@. | test.c:33:3:33:10 | ... += ... | expression |
| test.c:7:18:7:39 | ATOMIC_VAR_INIT(value) | Atomic variable possibly referred to twice in an $@. | test.c:34:3:34:13 | ... = ... | expression |
| test.c:11:3:11:23 | atomic_store(a,b) | Atomic variable possibly referred to twice in an $@. | test.c:11:3:11:23 | atomic_store(a,b) | expression |
| test.c:12:3:12:35 | atomic_store_explicit(a,b,c) | Atomic variable possibly referred to twice in an $@. | test.c:12:3:12:35 | atomic_store_explicit(a,b,c) | expression |
| test.c:25:3:25:49 | atomic_compare_exchange_weak(a,b,c) | Atomic variable possibly referred to twice in an $@. | test.c:25:3:25:49 | atomic_compare_exchange_weak(a,b,c) | expression |
| test.c:26:3:27:42 | atomic_compare_exchange_weak_explicit(a,b,c,d,e) | Atomic variable possibly referred to twice in an $@. | test.c:26:3:27:42 | atomic_compare_exchange_weak_explicit(a,b,c,d,e) | expression |
| test.c:11:3:11:23 | atomic_store(object,desired) | Atomic variable possibly referred to twice in an $@. | test.c:11:3:11:23 | atomic_store(object,desired) | expression |
| test.c:12:3:12:23 | atomic_store_explicit | Atomic variable possibly referred to twice in an $@. | test.c:12:3:12:23 | atomic_store_explicit | expression |
| test.c:25:3:25:49 | atomic_compare_exchange_weak(object,expected,desired) | Atomic variable possibly referred to twice in an $@. | test.c:25:3:25:49 | atomic_compare_exchange_weak(object,expected,desired) | expression |
| test.c:26:3:26:39 | atomic_compare_exchange_weak_explicit | Atomic variable possibly referred to twice in an $@. | test.c:26:3:26:39 | atomic_compare_exchange_weak_explicit | expression |

Просмотреть файл

@ -1,4 +1,4 @@
| test.c:6:8:6:46 | atomic_compare_exchange_weak(a,b,c) | Function that can spuriously fail not wrapped in a loop. |
| test.c:10:3:10:41 | atomic_compare_exchange_weak(a,b,c) | Function that can spuriously fail not wrapped in a loop. |
| test.c:12:8:13:47 | atomic_compare_exchange_weak_explicit(a,b,c,d,e) | Function that can spuriously fail not wrapped in a loop. |
| test.c:17:3:17:56 | atomic_compare_exchange_weak_explicit(a,b,c,d,e) | Function that can spuriously fail not wrapped in a loop. |
| test.c:6:8:6:46 | atomic_compare_exchange_weak(object,expected,desired) | Function that can spuriously fail not wrapped in a loop. |
| test.c:10:3:10:41 | atomic_compare_exchange_weak(object,expected,desired) | Function that can spuriously fail not wrapped in a loop. |
| test.c:12:8:12:44 | atomic_compare_exchange_weak_explicit | Function that can spuriously fail not wrapped in a loop. |
| test.c:17:3:17:39 | atomic_compare_exchange_weak_explicit | Function that can spuriously fail not wrapped in a loop. |

Просмотреть файл

@ -1,9 +1,69 @@
#define atomic_compare_exchange_weak(a, b, c) 0
#define atomic_compare_exchange_weak_explicit(a, b, c, d, e) 0
#define atomic_load(a) 0
#define atomic_load_explicit(a, b)
#define atomic_store(a, b) 0
#define atomic_store_explicit(a, b, c) 0
#define ATOMIC_VAR_INIT(value) (value)
#define atomic_is_lock_free(obj) __c11_atomic_is_lock_free(sizeof(*(obj)))
typedef _Atomic(int) atomic_int;
typedef _Atomic(int) atomic_int;
#define __ATOMIC_RELAXED 0
#define __ATOMIC_CONSUME 1
#define __ATOMIC_ACQUIRE 2
#define __ATOMIC_RELEASE 3
#define __ATOMIC_ACQ_REL 4
#define __ATOMIC_SEQ_CST 5
typedef enum memory_order {
memory_order_relaxed = __ATOMIC_RELAXED,
memory_order_consume = __ATOMIC_CONSUME,
memory_order_acquire = __ATOMIC_ACQUIRE,
memory_order_release = __ATOMIC_RELEASE,
memory_order_acq_rel = __ATOMIC_ACQ_REL,
memory_order_seq_cst = __ATOMIC_SEQ_CST
} memory_order;
void atomic_thread_fence(memory_order);
void atomic_signal_fence(memory_order);
#define atomic_thread_fence(order) __c11_atomic_thread_fence(order)
#define atomic_signal_fence(order) __c11_atomic_signal_fence(order)
#define atomic_store(object, desired) __c11_atomic_store(object, desired, __ATOMIC_SEQ_CST)
#define atomic_store_explicit __c11_atomic_store
#define atomic_load(object) __c11_atomic_load(object, __ATOMIC_SEQ_CST)
#define atomic_load_explicit __c11_atomic_load
#define atomic_exchange(object, desired) __c11_atomic_exchange(object, desired, __ATOMIC_SEQ_CST)
#define atomic_exchange_explicit __c11_atomic_exchange
#define atomic_compare_exchange_strong(object, expected, desired) __c11_atomic_compare_exchange_strong(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_strong_explicit __c11_atomic_compare_exchange_strong
#define atomic_compare_exchange_weak(object, expected, desired) __c11_atomic_compare_exchange_weak(object, expected, desired, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
#define atomic_compare_exchange_weak_explicit __c11_atomic_compare_exchange_weak
#define atomic_fetch_add(object, operand) __c11_atomic_fetch_add(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_add_explicit __c11_atomic_fetch_add
#define atomic_fetch_sub(object, operand) __c11_atomic_fetch_sub(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_sub_explicit __c11_atomic_fetch_sub
#define atomic_fetch_or(object, operand) __c11_atomic_fetch_or(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_or_explicit __c11_atomic_fetch_or
#define atomic_fetch_xor(object, operand) __c11_atomic_fetch_xor(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_xor_explicit __c11_atomic_fetch_xor
#define atomic_fetch_and(object, operand) __c11_atomic_fetch_and(object, operand, __ATOMIC_SEQ_CST)
#define atomic_fetch_and_explicit __c11_atomic_fetch_and
typedef struct atomic_flag { _Atomic(_Bool) _Value; } atomic_flag;
_Bool atomic_flag_test_and_set(volatile atomic_flag *);
_Bool atomic_flag_test_and_set_explicit(volatile atomic_flag *, memory_order);
void atomic_flag_clear(volatile atomic_flag *);
void atomic_flag_clear_explicit(volatile atomic_flag *, memory_order);
#define atomic_flag_test_and_set(object) __c11_atomic_exchange(&(object)->_Value, 1, __ATOMIC_SEQ_CST)
#define atomic_flag_test_and_set_explicit(object, order) __c11_atomic_exchange(&(object)->_Value, 1, order)
#define atomic_flag_clear(object) __c11_atomic_store(&(object)->_Value, 0, __ATOMIC_SEQ_CST)
#define atomic_flag_clear_explicit(object, order) __c11_atomic_store(&(object)->_Value, 0, order)

Просмотреть файл

@ -0,0 +1,4 @@
// GENERATED FILE - DO NOT MODIFY
import codingstandards.cpp.rules.joinordetachthreadonlyonce.JoinOrDetachThreadOnlyOnce
class TestFileQuery extends JoinOrDetachThreadOnlyOnceSharedQuery, TestQuery { }

Просмотреть файл

@ -0,0 +1,8 @@
- description: MISRA C 2012 (Audit)
- qlpack: codeql/misra-c-coding-standards
- include:
kind:
- problem
- path-problem
tags contain:
- external/misra/c/audit

Просмотреть файл

@ -0,0 +1,25 @@
/**
* @id c/misra/not-no-deadlocks-between-threads
* @name DIR-5-2: There shall be no deadlocks between threads
* @description Circular waits leading to thread deadlocks may be avoided by locking in a predefined
* order.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/dir-5-2
* external/misra/c/2012/amendment4
* correctness
* concurrency
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.preventdeadlockbylockinginpredefinedorder.PreventDeadlockByLockingInPredefinedOrder
class NotNoDeadlocksBetweenThreadsQuery extends PreventDeadlockByLockingInPredefinedOrderSharedQuery
{
NotNoDeadlocksBetweenThreadsQuery() {
this = Concurrency6Package::notNoDeadlocksBetweenThreadsQuery()
}
}

Просмотреть файл

@ -0,0 +1,29 @@
/**
* @id c/misra/banned-dynamic-thread-creation
* @name DIR-5-3: There shall be no dynamic thread creation
* @description Creating threads outside of a well-defined program start-up phase creates
* uncertainty in program behavior and concurrency overhead costs.
* @kind problem
* @precision low
* @problem.severity error
* @tags external/misra/id/dir-5-3
* external/misra/c/2012/amendment4
* external/misra/c/audit
* correctness
* maintainability
* concurrency
* performance
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.Concurrency
from CThreadCreateCall tc, Function enclosingFunction
where
not isExcluded(tc, Concurrency6Package::bannedDynamicThreadCreationQuery()) and
enclosingFunction = tc.getEnclosingFunction() and
not enclosingFunction.getName() = "main"
select tc, "Possible dynamic creation of thread outside initialization in function '$@'.",
enclosingFunction, enclosingFunction.toString()

Просмотреть файл

@ -0,0 +1,38 @@
/**
* @id c/misra/thread-created-by-thread
* @name DIR-5-3: Threads shall not be created by other threads
* @description Creating threads within threads creates uncertainty in program behavior and
* concurrency overhead costs.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/dir-5-3
* external/misra/c/2012/amendment4
* correctness
* maintainability
* concurrency
* performance
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.Concurrency
class CThreadRoot extends Function {
CThreadCreateCall threadCreate;
CThreadRoot() { threadCreate.getFunction() = this }
/* Get a function which is reachable from this function */
Function getAReachableFunction() { calls*(result) }
CThreadCreateCall getACThreadCreateCall() { result = threadCreate }
}
from CThreadCreateCall tc, CThreadRoot threadRoot
where
not isExcluded(tc, Concurrency6Package::threadCreatedByThreadQuery()) and
tc.getEnclosingFunction() = threadRoot.getAReachableFunction()
select tc, "Thread creation call reachable from function '$@', which may also be $@.", threadRoot,
threadRoot.toString(), threadRoot.getACThreadCreateCall(), "started as a thread"

Просмотреть файл

@ -0,0 +1,40 @@
/**
* @id c/misra/atomic-aggregate-object-directly-accessed
* @name RULE-12-6: Structure and union members of atomic objects shall not be directly accessed
* @description Accessing a member of an atomic structure or union results in undefined behavior.
* @kind problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-12-6
* external/misra/c/2012/amendment4
* correctness
* concurrency
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
from Expr expr, Field field
where
not isExcluded(expr, Concurrency6Package::atomicAggregateObjectDirectlyAccessedQuery()) and
not expr.isUnevaluated() and
(
exists(FieldAccess fa |
expr = fa and
fa.getQualifier().getType().hasSpecifier("atomic") and
field = fa.getTarget()
)
or
exists(PointerFieldAccess fa |
expr = fa and
fa.getQualifier()
.getType()
.stripTopLevelSpecifiers()
.(PointerType)
.getBaseType()
.hasSpecifier("atomic") and
field = fa.getTarget()
)
)
select expr, "Invalid access to member '$@' on atomic struct or union.", field, field.getName()

Просмотреть файл

@ -0,0 +1,154 @@
/**
* @id c/misra/invalid-memory-order-argument
* @name RULE-21-25: All memory synchronization operations shall be executed in sequentially consistent order
* @description Only the memory ordering of 'memory_order_seq_cst' is fully portable and consistent.
* @kind path-problem
* @precision very-high
* @problem.severity error
* @tags external/misra/id/rule-21-25
* external/misra/c/2012/amendment4
* correctness
* concurrency
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import semmle.code.cpp.dataflow.new.DataFlow
/* A member of the set of memory orders defined in the `memory_order` enum */
class MemoryOrder extends EnumConstant {
MemoryOrder() { getDeclaringEnum().getName() = "memory_order" }
int getIntValue() { result = getValue().toInt() }
}
/* This is the only standardized memory order, allowed by RULE-21-25. */
class AllowedMemoryOrder extends MemoryOrder {
AllowedMemoryOrder() { getName() = "memory_order_seq_cst" }
}
/* An expression referring to a memory order */
class MemoryOrderConstantAccess extends EnumConstantAccess {
MemoryOrderConstantAccess() { getTarget() instanceof MemoryOrder }
predicate isAllowedOrder() { getTarget() instanceof AllowedMemoryOrder }
}
/* An expression with a constant value that equals a `MemoryOrder` constant */
class MemoryOrderConstantExpr extends Expr {
MemoryOrder ord;
MemoryOrderConstantExpr() {
if this instanceof MemoryOrderConstantAccess
then ord = this.(MemoryOrderConstantAccess).getTarget()
else ord.getIntValue() = getValue().toInt()
}
/* Get the name of the `MemoryOrder` this expression is valued as. */
string getMemoryOrderString() { result = ord.getName() }
}
/**
* A `stdatomic.h` function which accepts a `memory_order` value as a parameter.
*/
class MemoryOrderedStdAtomicFunction extends Function {
int orderParamIdx;
MemoryOrderedStdAtomicFunction() {
exists(int baseParamIdx, int baseParams, string prefix, string regex, string basename |
regex = "__(c11_)?atomic_([a-z_]+)" and
prefix = getName().regexpCapture(regex, 1) and
basename = "atomic_" + getName().regexpCapture(regex, 2) + ["", "_explicit"] and
(
basename in ["atomic_thread_fence", "atomic_signal_fence"] and
baseParamIdx = 0 and
baseParams = 1
or
basename in ["atomic_load", "atomic_flag_clear", "atomic_flag_test_and_set"] and
baseParamIdx = 1 and
baseParams = 2
or
basename in [
"atomic_store", "atomic_fetch_" + ["add", "sub", "or", "xor", "and"], "atomic_exchange"
] and
baseParamIdx = 2 and
baseParams = 3
or
basename in ["atomic_compare_exchange_" + ["strong", "weak"]] and
baseParamIdx = [3, 4] and
baseParams = 5
) and
(
// GCC case, may have one or two inserted parameters, e.g.:
// __atomic_load(8, &repr->a, &desired, order)
// or
// __atomic_load_8(&repr->a, &desired, order)
prefix = "" and
exists(int extraParams |
extraParams = getNumberOfParameters() - baseParams and
extraParams >= 0 and
orderParamIdx = baseParamIdx + extraParams
)
or
// Clang case, no inserted parameters:
// __c11_atomic_load(object, order)
prefix = "c11_" and
orderParamIdx = baseParamIdx
)
)
}
int getOrderParameterIdx() { result = orderParamIdx }
}
module MemoryOrderFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
// Direct usage of memory order constant
exists(MemoryOrderConstantAccess constant |
node.asExpr() = constant and
not constant.isAllowedOrder()
)
or
// A literal with a disallowed constant integer value
exists(Literal literal |
node.asExpr() = literal and
not literal.getValue().toInt() = any(AllowedMemoryOrder a).getValue().toInt()
)
}
predicate isSink(DataFlow::Node node) {
exists(FunctionCall fc |
node.asExpr() =
fc.getArgument(fc.getTarget().(MemoryOrderedStdAtomicFunction).getOrderParameterIdx())
)
}
}
module MemoryOrderFlow = DataFlow::Global<MemoryOrderFlowConfig>;
import MemoryOrderFlow::PathGraph
/**
* If the node is a memory order constant, or shares a value with a memory order constant, then
* return the name of that constant. Otherwise, simply print the node.
*/
string describeMemoryOrderNode(DataFlow::Node node) {
if node.asExpr() instanceof MemoryOrderConstantExpr
then result = node.asExpr().(MemoryOrderConstantExpr).getMemoryOrderString()
else result = node.toString()
}
from
Expr argument, Function function, string value, MemoryOrderFlow::PathNode source,
MemoryOrderFlow::PathNode sink
where
not isExcluded(argument, Concurrency6Package::invalidMemoryOrderArgumentQuery()) and
MemoryOrderFlow::flowPath(source, sink) and
argument = sink.getNode().asExpr() and
value = describeMemoryOrderNode(source.getNode()) and
// Double check that we didn't find flow from something equivalent to the allowed value.
not value = any(AllowedMemoryOrder e).getName() and
function.getACallToThisFunction().getAnArgument() = argument
select argument, source, sink, "Invalid memory order '$@' in call to function '$@'.", value, value,
function, function.getName()

Просмотреть файл

@ -0,0 +1,24 @@
/**
* @id c/misra/thread-previously-joined-or-detached
* @name RULE-22-11: A thread that was previously either joined or detached shall not be subsequently joined nor detached
* @description Joining or detaching a previously joined or detached thread can lead to undefined
* program behavior.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-22-11
* external/misra/c/2012/amendment4
* correctness
* concurrency
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import codingstandards.cpp.rules.joinordetachthreadonlyonce.JoinOrDetachThreadOnlyOnce
class ThreadPreviouslyJoinedOrDetachedQuery extends JoinOrDetachThreadOnlyOnceSharedQuery {
ThreadPreviouslyJoinedOrDetachedQuery() {
this = Concurrency6Package::threadPreviouslyJoinedOrDetachedQuery()
}
}

Просмотреть файл

@ -0,0 +1 @@
c/common/test/rules/preventdeadlockbylockinginpredefinedorder/PreventDeadlockByLockingInPredefinedOrder.ql

Просмотреть файл

@ -0,0 +1,16 @@
| test.c:30:3:30:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:29:6:29:34 | make_threads_called_from_main | make_threads_called_from_main |
| test.c:31:3:31:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:29:6:29:34 | make_threads_called_from_main | make_threads_called_from_main |
| test.c:39:3:39:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:38:6:38:51 | make_threads_called_from_func_called_from_main | make_threads_called_from_func_called_from_main |
| test.c:40:3:40:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:38:6:38:51 | make_threads_called_from_func_called_from_main | make_threads_called_from_func_called_from_main |
| test.c:49:3:49:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:48:7:48:18 | pthread_func | pthread_func |
| test.c:50:3:50:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:48:7:48:18 | pthread_func | pthread_func |
| test.c:58:3:58:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:57:5:57:13 | thrd_func | thrd_func |
| test.c:59:3:59:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:57:5:57:13 | thrd_func | thrd_func |
| test.c:67:3:67:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:66:6:66:39 | make_threads_called_from_thrd_func | make_threads_called_from_thrd_func |
| test.c:68:3:68:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:66:6:66:39 | make_threads_called_from_thrd_func | make_threads_called_from_thrd_func |
| test.c:76:3:76:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:75:6:75:59 | make_threads_called_from_func_called_from_pthread_thrd | make_threads_called_from_func_called_from_pthread_thrd |
| test.c:77:3:77:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:75:6:75:59 | make_threads_called_from_func_called_from_pthread_thrd | make_threads_called_from_func_called_from_pthread_thrd |
| test.c:81:3:81:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:80:6:80:47 | make_threads_called_from_main_pthread_thrd | make_threads_called_from_main_pthread_thrd |
| test.c:82:3:82:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:80:6:80:47 | make_threads_called_from_main_pthread_thrd | make_threads_called_from_main_pthread_thrd |
| test.c:86:3:86:13 | call to thrd_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:85:6:85:38 | make_threads_not_called_by_anyone | make_threads_not_called_by_anyone |
| test.c:87:3:87:16 | call to pthread_create | Possible dynamic creation of thread outside initialization in function '$@'. | test.c:85:6:85:38 | make_threads_not_called_by_anyone | make_threads_not_called_by_anyone |

Просмотреть файл

@ -0,0 +1 @@
rules/DIR-5-3/BannedDynamicThreadCreation.ql

Просмотреть файл

@ -0,0 +1,14 @@
| test.c:49:3:49:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:50:3:50:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:58:3:58:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:59:3:59:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:67:3:67:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:68:3:68:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:76:3:76:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:76:3:76:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:77:3:77:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:77:3:77:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:81:3:81:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:81:3:81:13 | call to thrd_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |
| test.c:82:3:82:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:48:7:48:18 | pthread_func | pthread_func | test.c:19:3:19:16 | call to pthread_create | started as a thread |
| test.c:82:3:82:16 | call to pthread_create | Thread creation call reachable from function '$@', which may also be $@. | test.c:57:5:57:13 | thrd_func | thrd_func | test.c:18:3:18:13 | call to thrd_create | started as a thread |

Просмотреть файл

@ -0,0 +1 @@
rules/DIR-5-3/ThreadCreatedByThread.ql

Просмотреть файл

@ -0,0 +1,88 @@
#include "pthread.h"
#include "threads.h"
thrd_t g1; // COMPLIANT
pthread_t g2; // COMPLIANT
void *pthread_func(void *arg);
void *pthread_func_inner(void *arg);
int thrd_func(void *arg);
int thrd_func_inner(void *arg);
void make_threads_called_from_main(void);
void func_called_from_main(void);
void make_threads_called_from_func_called_from_main(void);
void make_threads_called_from_main_pthread_thrd(void);
void main() {
thrd_create(&g1, &thrd_func, NULL); // COMPLIANT
pthread_create(&g2, NULL, &pthread_func, NULL); // COMPLIANT
thrd_create(&g1, &thrd_func_inner, NULL); // COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // COMPLIANT
make_threads_called_from_main();
func_called_from_main();
make_threads_called_from_main_pthread_thrd();
}
void make_threads_called_from_main() {
thrd_create(&g1, &thrd_func_inner, NULL); // COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // COMPLIANT
}
void func_called_from_main() {
make_threads_called_from_func_called_from_main();
}
void make_threads_called_from_func_called_from_main() {
thrd_create(&g1, &thrd_func_inner, NULL); // COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // COMPLIANT
}
void make_threads_called_from_pthread_func(void);
void make_threads_called_from_thrd_func(void);
void func_called_from_pthread_thrd(void);
void make_threads_called_from_func_called_from_pthread_thrd(void);
void *pthread_func(void *arg) {
thrd_create(&g1, &thrd_func_inner, NULL); // NON-COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // NON-COMPLIANT
make_threads_called_from_pthread_func();
func_called_from_pthread_thrd();
make_threads_called_from_main_pthread_thrd();
}
int thrd_func(void *arg) {
thrd_create(&g1, &thrd_func_inner, NULL); // NON-COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // NON-COMPLIANT
make_threads_called_from_thrd_func();
func_called_from_pthread_thrd();
make_threads_called_from_main_pthread_thrd();
}
void make_threads_called_from_thrd_func(void) {
thrd_create(&g1, &thrd_func_inner, NULL); // NON-COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // NON-COMPLIANT
}
void func_called_from_pthread_thrd(void) {
make_threads_called_from_func_called_from_pthread_thrd();
}
void make_threads_called_from_func_called_from_pthread_thrd(void) {
thrd_create(&g1, &thrd_func_inner, NULL); // NON-COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // NON-COMPLIANT
}
void make_threads_called_from_main_pthread_thrd() {
thrd_create(&g1, &thrd_func_inner, NULL); // NON-COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // NON-COMPLIANT
}
void make_threads_not_called_by_anyone() {
thrd_create(&g1, &thrd_func_inner, NULL); // COMPLIANT
pthread_create(&g2, NULL, &pthread_func_inner, NULL); // COMPLIANT
}

Просмотреть файл

@ -0,0 +1,13 @@
| test.c:43:13:43:13 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:44:18:44:18 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:45:13:45:13 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:46:18:46:18 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:65:6:65:6 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:71:9:71:9 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:82:18:82:18 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:83:3:83:31 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:84:3:84:39 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:85:3:85:19 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:86:3:86:23 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:87:3:87:19 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |
| test.c:88:3:88:23 | x | Invalid access to member '$@' on atomic struct or union. | test.c:5:7:5:7 | x | x |

Просмотреть файл

@ -0,0 +1 @@
rules/RULE-12-6/AtomicAggregateObjectDirectlyAccessed.ql

Просмотреть файл

@ -0,0 +1,89 @@
#include "stdatomic.h"
#include "string.h"
typedef struct s1 {
int x;
} s1;
_Atomic s1 atomic_s1;
// A non-atomic pointer to an atomic s1
_Atomic s1 *ptr_atomic_s1;
// An atomic pointer to a non-atomic s1
s1 *_Atomic s1_atomic_ptr;
_Atomic int g3;
void takeCopy(s1 p1);
void f1() {
s1 l1;
s1 *l2;
l1 = atomic_load(&atomic_s1); // COMPLIANT
l1 = atomic_load(ptr_atomic_s1); // COMPLIANT
l2 = atomic_load(&s1_atomic_ptr); // COMPLIANT
l1.x = 4; // COMPLIANT
l2->x = 4; // COMPLIANT
atomic_store(&atomic_s1, l1); // COMPLIANT
atomic_store(ptr_atomic_s1, l1); // COMPLIANT
atomic_store(&s1_atomic_ptr, l2); // COMPLIANT
// Undefined behavior, but not banned by this rule.
memset(&atomic_s1, sizeof(atomic_s1), 0); // COMPLIANT
memset(ptr_atomic_s1, sizeof(*ptr_atomic_s1), 0); // COMPLIANT
// OK: whole loads and stores are protected from data-races.
takeCopy(atomic_s1); // COMPLIANT
takeCopy(*ptr_atomic_s1); // COMPLIANT
atomic_s1 = (s1){0}; // COMPLIANT
*ptr_atomic_s1 = (s1){0}; // COMPLIANT
atomic_s1 = *l2; // COMPLIANT
ptr_atomic_s1 = l2; // COMPLIANT
// Banned: circumvents data-race protection, results in UB.
atomic_s1.x; // NON-COMPLIANT
ptr_atomic_s1->x; // NON-COMPLIANT
atomic_s1.x = 0; // NON-COMPLIANT
ptr_atomic_s1->x = 0; // NON-COMPLIANT
// OK: not evaluated.
sizeof(atomic_s1); // COMPLIANT
sizeof(ptr_atomic_s1); // COMPLIANT
sizeof(atomic_s1.x); // COMPLIANT
sizeof(ptr_atomic_s1->x); // COMPLIANT
// All OK: not an atomic struct, but rather an atomic pointer to non-atomic
// struct.
memset(s1_atomic_ptr, sizeof(*s1_atomic_ptr), 0); // COMPLIANT
takeCopy(*s1_atomic_ptr); // COMPLIANT
*s1_atomic_ptr = (s1){0}; // COMPLIANT
s1_atomic_ptr = l2; // COMPLIANT
s1_atomic_ptr->x; // COMPLIANT
// Atomic specifier hidden behind a typedef, still atomic:
typedef _Atomic s1 atomic_s1;
atomic_s1 l3;
l3.x; // NON_COMPLIANT
// Worst case scenario: a typedef of a volatile const pointer to an atomic
// typedef type.
typedef atomic_s1 *volatile const atomic_s1_specified_ptr;
atomic_s1_specified_ptr l4;
(l4)->x; // NON_COMPLIANT
}
#define NOOP(x) (x)
#define DOT_FIELD_ACCESS_X(v) (v).x
#define POINTER_FIELD_ACCESS_X(v) (v)->x
#define GET_X_ATOMIC_S1() atomic_s1.x
#define GET_X_PTR_ATOMIC_S1() atomic_s1.x
void f2() {
// Banned UB with user macros:
NOOP(atomic_s1.x); // NON-COMPLIANT
DOT_FIELD_ACCESS_X(atomic_s1); // NON-COMPLIANT
POINTER_FIELD_ACCESS_X(ptr_atomic_s1); // NON-COMPLIANT
GET_X_ATOMIC_S1(); // NON-COMPLIANT
GET_X_PTR_ATOMIC_S1(); // NON-COMPLIANT
GET_X_ATOMIC_S1() = 0; // NON-COMPLIANT
GET_X_PTR_ATOMIC_S1() = 0; // NON-COMPLIANT
}

Просмотреть файл

@ -0,0 +1,106 @@
edges
| test.c:4:5:4:6 | *g2 | test.c:53:33:53:34 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:54:29:54:30 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:55:42:55:43 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:56:35:56:36 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:57:36:57:37 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:58:54:58:55 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:59:58:59:59 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:60:52:60:53 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:61:56:61:57 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:62:37:62:38 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:63:37:63:38 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:64:36:64:37 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:65:37:65:38 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:66:37:66:38 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:67:23:67:24 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:68:23:68:24 | g2 | provenance | |
| test.c:4:5:4:6 | *g2 | test.c:71:23:71:24 | g2 | provenance | |
| test.c:4:10:4:29 | memory_order_relaxed | test.c:4:5:4:6 | *g2 | provenance | |
| test.c:4:10:4:29 | memory_order_relaxed | test.c:4:10:4:29 | memory_order_relaxed | provenance | |
| test.c:5:5:5:6 | *g3 | test.c:72:23:72:24 | g3 | provenance | |
| test.c:5:10:5:29 | memory_order_acquire | test.c:5:5:5:6 | *g3 | provenance | |
| test.c:5:10:5:29 | memory_order_acquire | test.c:5:10:5:29 | memory_order_acquire | provenance | |
| test.c:6:5:6:6 | *g4 | test.c:73:23:73:24 | g4 | provenance | |
| test.c:6:10:6:29 | memory_order_consume | test.c:6:5:6:6 | *g4 | provenance | |
| test.c:6:10:6:29 | memory_order_consume | test.c:6:10:6:29 | memory_order_consume | provenance | |
| test.c:7:5:7:6 | *g5 | test.c:74:23:74:24 | g5 | provenance | |
| test.c:7:10:7:29 | memory_order_acq_rel | test.c:7:5:7:6 | *g5 | provenance | |
| test.c:7:10:7:29 | memory_order_acq_rel | test.c:7:10:7:29 | memory_order_acq_rel | provenance | |
| test.c:8:5:8:6 | *g6 | test.c:75:23:75:24 | g6 | provenance | |
| test.c:8:10:8:29 | memory_order_release | test.c:8:5:8:6 | *g6 | provenance | |
| test.c:8:10:8:29 | memory_order_release | test.c:8:10:8:29 | memory_order_release | provenance | |
nodes
| test.c:4:5:4:6 | *g2 | semmle.label | *g2 |
| test.c:4:10:4:29 | memory_order_relaxed | semmle.label | memory_order_relaxed |
| test.c:4:10:4:29 | memory_order_relaxed | semmle.label | memory_order_relaxed |
| test.c:5:5:5:6 | *g3 | semmle.label | *g3 |
| test.c:5:10:5:29 | memory_order_acquire | semmle.label | memory_order_acquire |
| test.c:5:10:5:29 | memory_order_acquire | semmle.label | memory_order_acquire |
| test.c:6:5:6:6 | *g4 | semmle.label | *g4 |
| test.c:6:10:6:29 | memory_order_consume | semmle.label | memory_order_consume |
| test.c:6:10:6:29 | memory_order_consume | semmle.label | memory_order_consume |
| test.c:7:5:7:6 | *g5 | semmle.label | *g5 |
| test.c:7:10:7:29 | memory_order_acq_rel | semmle.label | memory_order_acq_rel |
| test.c:7:10:7:29 | memory_order_acq_rel | semmle.label | memory_order_acq_rel |
| test.c:8:5:8:6 | *g6 | semmle.label | *g6 |
| test.c:8:10:8:29 | memory_order_release | semmle.label | memory_order_release |
| test.c:8:10:8:29 | memory_order_release | semmle.label | memory_order_release |
| test.c:16:29:16:48 | memory_order_relaxed | semmle.label | memory_order_relaxed |
| test.c:17:29:17:48 | memory_order_acquire | semmle.label | memory_order_acquire |
| test.c:18:29:18:48 | memory_order_consume | semmle.label | memory_order_consume |
| test.c:19:29:19:48 | memory_order_acq_rel | semmle.label | memory_order_acq_rel |
| test.c:20:29:20:48 | memory_order_release | semmle.label | memory_order_release |
| test.c:53:33:53:34 | g2 | semmle.label | g2 |
| test.c:54:29:54:30 | g2 | semmle.label | g2 |
| test.c:55:42:55:43 | g2 | semmle.label | g2 |
| test.c:56:35:56:36 | g2 | semmle.label | g2 |
| test.c:57:36:57:37 | g2 | semmle.label | g2 |
| test.c:58:54:58:55 | g2 | semmle.label | g2 |
| test.c:59:58:59:59 | g2 | semmle.label | g2 |
| test.c:60:52:60:53 | g2 | semmle.label | g2 |
| test.c:61:56:61:57 | g2 | semmle.label | g2 |
| test.c:62:37:62:38 | g2 | semmle.label | g2 |
| test.c:63:37:63:38 | g2 | semmle.label | g2 |
| test.c:64:36:64:37 | g2 | semmle.label | g2 |
| test.c:65:37:65:38 | g2 | semmle.label | g2 |
| test.c:66:37:66:38 | g2 | semmle.label | g2 |
| test.c:67:23:67:24 | g2 | semmle.label | g2 |
| test.c:68:23:68:24 | g2 | semmle.label | g2 |
| test.c:71:23:71:24 | g2 | semmle.label | g2 |
| test.c:72:23:72:24 | g3 | semmle.label | g3 |
| test.c:73:23:73:24 | g4 | semmle.label | g4 |
| test.c:74:23:74:24 | g5 | semmle.label | g5 |
| test.c:75:23:75:24 | g6 | semmle.label | g6 |
| test.c:79:23:79:23 | 1 | semmle.label | 1 |
| test.c:80:23:80:25 | 100 | semmle.label | 100 |
subpaths
#select
| test.c:16:29:16:48 | memory_order_relaxed | test.c:16:29:16:48 | memory_order_relaxed | test.c:16:29:16:48 | memory_order_relaxed | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:17:29:17:48 | memory_order_acquire | test.c:17:29:17:48 | memory_order_acquire | test.c:17:29:17:48 | memory_order_acquire | Invalid memory order '$@' in call to function '$@'. | memory_order_acquire | memory_order_acquire | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:18:29:18:48 | memory_order_consume | test.c:18:29:18:48 | memory_order_consume | test.c:18:29:18:48 | memory_order_consume | Invalid memory order '$@' in call to function '$@'. | memory_order_consume | memory_order_consume | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:19:29:19:48 | memory_order_acq_rel | test.c:19:29:19:48 | memory_order_acq_rel | test.c:19:29:19:48 | memory_order_acq_rel | Invalid memory order '$@' in call to function '$@'. | memory_order_acq_rel | memory_order_acq_rel | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:20:29:20:48 | memory_order_release | test.c:20:29:20:48 | memory_order_release | test.c:20:29:20:48 | memory_order_release | Invalid memory order '$@' in call to function '$@'. | memory_order_release | memory_order_release | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:53:33:53:34 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:53:33:53:34 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_store | __c11_atomic_store |
| test.c:54:29:54:30 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:54:29:54:30 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_load | __c11_atomic_load |
| test.c:55:42:55:43 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:55:42:55:43 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_exchange | __c11_atomic_exchange |
| test.c:56:35:56:36 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:56:35:56:36 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_store | __c11_atomic_store |
| test.c:57:36:57:37 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:57:36:57:37 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_exchange | __c11_atomic_exchange |
| test.c:58:54:58:55 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:58:54:58:55 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_compare_exchange_strong | __c11_atomic_compare_exchange_strong |
| test.c:59:58:59:59 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:59:58:59:59 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_compare_exchange_strong | __c11_atomic_compare_exchange_strong |
| test.c:60:52:60:53 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:60:52:60:53 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_compare_exchange_weak | __c11_atomic_compare_exchange_weak |
| test.c:61:56:61:57 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:61:56:61:57 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_compare_exchange_weak | __c11_atomic_compare_exchange_weak |
| test.c:62:37:62:38 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:62:37:62:38 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_fetch_add | __c11_atomic_fetch_add |
| test.c:63:37:63:38 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:63:37:63:38 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_fetch_sub | __c11_atomic_fetch_sub |
| test.c:64:36:64:37 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:64:36:64:37 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_fetch_or | __c11_atomic_fetch_or |
| test.c:65:37:65:38 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:65:37:65:38 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_fetch_xor | __c11_atomic_fetch_xor |
| test.c:66:37:66:38 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:66:37:66:38 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_fetch_and | __c11_atomic_fetch_and |
| test.c:67:23:67:24 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:67:23:67:24 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:68:23:68:24 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:68:23:68:24 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_signal_fence | __c11_atomic_signal_fence |
| test.c:71:23:71:24 | g2 | test.c:4:10:4:29 | memory_order_relaxed | test.c:71:23:71:24 | g2 | Invalid memory order '$@' in call to function '$@'. | memory_order_relaxed | memory_order_relaxed | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:72:23:72:24 | g3 | test.c:5:10:5:29 | memory_order_acquire | test.c:72:23:72:24 | g3 | Invalid memory order '$@' in call to function '$@'. | memory_order_acquire | memory_order_acquire | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:73:23:73:24 | g4 | test.c:6:10:6:29 | memory_order_consume | test.c:73:23:73:24 | g4 | Invalid memory order '$@' in call to function '$@'. | memory_order_consume | memory_order_consume | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:74:23:74:24 | g5 | test.c:7:10:7:29 | memory_order_acq_rel | test.c:74:23:74:24 | g5 | Invalid memory order '$@' in call to function '$@'. | memory_order_acq_rel | memory_order_acq_rel | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:75:23:75:24 | g6 | test.c:8:10:8:29 | memory_order_release | test.c:75:23:75:24 | g6 | Invalid memory order '$@' in call to function '$@'. | memory_order_release | memory_order_release | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:79:23:79:23 | 1 | test.c:79:23:79:23 | 1 | test.c:79:23:79:23 | 1 | Invalid memory order '$@' in call to function '$@'. | memory_order_consume | memory_order_consume | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |
| test.c:80:23:80:25 | 100 | test.c:80:23:80:25 | 100 | test.c:80:23:80:25 | 100 | Invalid memory order '$@' in call to function '$@'. | 100 | 100 | file://:0:0:0:0 | __c11_atomic_thread_fence | __c11_atomic_thread_fence |

Просмотреть файл

@ -0,0 +1 @@
rules/RULE-21-25/InvalidMemoryOrderArgument.ql

Просмотреть файл

@ -0,0 +1,85 @@
#include "stdatomic.h"
int g1 = memory_order_seq_cst;
int g2 = memory_order_relaxed;
int g3 = memory_order_acquire;
int g4 = memory_order_consume;
int g5 = memory_order_acq_rel;
int g6 = memory_order_release;
void f(int p) {
_Atomic int l1;
atomic_flag l2;
// Directly specified values:
atomic_load_explicit(&l1, memory_order_seq_cst); // COMPLIANT
atomic_load_explicit(&l1, memory_order_relaxed); // NON-COMPLIANT
atomic_load_explicit(&l1, memory_order_acquire); // NON-COMPLIANT
atomic_load_explicit(&l1, memory_order_consume); // NON-COMPLIANT
atomic_load_explicit(&l1, memory_order_acq_rel); // NON-COMPLIANT
atomic_load_explicit(&l1, memory_order_release); // NON-COMPLIANT
// Implicit values:
atomic_store(&l1, 0); // COMPLIANT
atomic_load(&l1); // COMPLIANT
atomic_flag_test_and_set(&l2); // COMPLIANT
atomic_flag_clear(&l2); // COMPLIANT
atomic_exchange(&l1, 0); // COMPLIANT
atomic_compare_exchange_strong(&l1, 0, 1); // COMPLIANT
atomic_compare_exchange_weak(&l1, 0, 1); // COMPLIANT
atomic_fetch_add(&l1, 0); // COMPLIANT
atomic_fetch_sub(&l1, 0); // COMPLIANT
atomic_fetch_or(&l1, 0); // COMPLIANT
atomic_fetch_xor(&l1, 0); // COMPLIANT
atomic_fetch_and(&l1, 0); // COMPLIANT
// Compliant flowed values (one test per sink):
atomic_store_explicit(&l1, 0, g1); // COMPLIANT
atomic_load_explicit(&l1, g1); // COMPLIANT
atomic_flag_test_and_set_explicit(&l2, g1); // COMPLIANT
atomic_flag_clear_explicit(&l2, g1); // COMPLIANT
atomic_exchange_explicit(&l1, 0, g1); // COMPLIANT
atomic_compare_exchange_strong_explicit(&l1, 0, 1, g1, g1); // COMPLIANT
atomic_compare_exchange_weak_explicit(&l1, 0, 1, g1, g1); // COMPLIANT
atomic_fetch_add_explicit(&l1, 0, g1); // COMPLIANT
atomic_fetch_sub_explicit(&l1, 0, g1); // COMPLIANT
atomic_fetch_or_explicit(&l1, 0, g1); // COMPLIANT
atomic_fetch_xor_explicit(&l1, 0, g1); // COMPLIANT
atomic_fetch_and_explicit(&l1, 0, g1); // COMPLIANT
atomic_thread_fence(g1); // COMPLIANT
atomic_signal_fence(g1); // COMPLIANT
// Non-compliant flowed values (one test per sink):
atomic_store_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_load_explicit(&l1, g2); // NON-COMPLIANT
atomic_flag_test_and_set_explicit(&l2, g2); // NON-COMPLIANT
atomic_flag_clear_explicit(&l2, g2); // NON-COMPLIANT
atomic_exchange_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_compare_exchange_strong_explicit(&l1, 0, 1, g2, g1); // NON-COMPLIANT
atomic_compare_exchange_strong_explicit(&l1, 0, 1, g1, g2); // NON-COMPLIANT
atomic_compare_exchange_weak_explicit(&l1, 0, 1, g2, g1); // NON-COMPLIANT
atomic_compare_exchange_weak_explicit(&l1, 0, 1, g1, g2); // NON-COMPLIANT
atomic_fetch_add_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_fetch_sub_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_fetch_or_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_fetch_xor_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_fetch_and_explicit(&l1, 0, g2); // NON-COMPLIANT
atomic_thread_fence(g2); // NON-COMPLIANT
atomic_signal_fence(g2); // NON-COMPLIANT
// Non-compliant flowed values (one test per source):
atomic_thread_fence(g2); // NON-COMPLIANT
atomic_thread_fence(g3); // NON-COMPLIANT
atomic_thread_fence(g4); // NON-COMPLIANT
atomic_thread_fence(g5); // NON-COMPLIANT
atomic_thread_fence(g6); // NON-COMPLIANT
// Computed flow sources:
atomic_thread_fence(memory_order_seq_cst * 1); // COMPLIANT
atomic_thread_fence(1); // NON-COMPLIANT
atomic_thread_fence(100); // NON-COMPLIANT
atomic_thread_fence(g1 + 1); // NON_COMPLIANT[FALSE_NEGATIVE]
// No unsafe flow, currently accepted:
atomic_thread_fence(p); // COMPLIANT
}

Просмотреть файл

@ -0,0 +1 @@
c/common/test/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.ql

Просмотреть файл

@ -0,0 +1 @@
c/common/test/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.ql

Просмотреть файл

@ -48,19 +48,38 @@ class ThreadConstructorCall extends ConstructorCall, ThreadCreationFunction {
}
/**
* Models a call to a thread constructor via `thrd_create`.
* Models a call to a thread creation via `thrd_create` or `pthread_create`.
*/
class C11ThreadCreateCall extends ThreadCreationFunction {
class CThreadCreateCall extends FunctionCall {
Function f;
int fArgIdx;
C11ThreadCreateCall() {
getTarget().getName() = "thrd_create" and
CThreadCreateCall() {
(
f = getArgument(1).(FunctionAccess).getTarget() or
f = getArgument(1).(AddressOfExpr).getOperand().(FunctionAccess).getTarget()
getTarget().getName() = "thrd_create" and
fArgIdx = 1
or
getTarget().getName() = "pthread_create" and
fArgIdx = 2
) and
(
f = getArgument(fArgIdx).(FunctionAccess).getTarget() or
f = getArgument(fArgIdx).(AddressOfExpr).getOperand().(FunctionAccess).getTarget()
)
}
/**
* Returns the function that will be invoked by this thread.
*/
Function getFunction() { result = f }
}
/**
* Models a call to a thread constructor via `thrd_create`.
*/
class C11ThreadCreateCall extends ThreadCreationFunction, CThreadCreateCall {
C11ThreadCreateCall() { getTarget().getName() = "thrd_create" }
/**
* Returns the function that will be invoked by this thread.
*/

Просмотреть файл

@ -0,0 +1,112 @@
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
import cpp
import RuleMetadata
import codingstandards.cpp.exclusions.RuleMetadata
newtype Concurrency6Query =
TNotNoDeadlocksBetweenThreadsQuery() or
TThreadCreatedByThreadQuery() or
TBannedDynamicThreadCreationQuery() or
TAtomicAggregateObjectDirectlyAccessedQuery() or
TInvalidMemoryOrderArgumentQuery() or
TThreadPreviouslyJoinedOrDetachedQuery()
predicate isConcurrency6QueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
// `Query` instance for the `notNoDeadlocksBetweenThreads` query
Concurrency6Package::notNoDeadlocksBetweenThreadsQuery() and
queryId =
// `@id` for the `notNoDeadlocksBetweenThreads` query
"c/misra/not-no-deadlocks-between-threads" and
ruleId = "DIR-5-2" and
category = "required"
or
query =
// `Query` instance for the `threadCreatedByThread` query
Concurrency6Package::threadCreatedByThreadQuery() and
queryId =
// `@id` for the `threadCreatedByThread` query
"c/misra/thread-created-by-thread" and
ruleId = "DIR-5-3" and
category = "required"
or
query =
// `Query` instance for the `bannedDynamicThreadCreation` query
Concurrency6Package::bannedDynamicThreadCreationQuery() and
queryId =
// `@id` for the `bannedDynamicThreadCreation` query
"c/misra/banned-dynamic-thread-creation" and
ruleId = "DIR-5-3" and
category = "required"
or
query =
// `Query` instance for the `atomicAggregateObjectDirectlyAccessed` query
Concurrency6Package::atomicAggregateObjectDirectlyAccessedQuery() and
queryId =
// `@id` for the `atomicAggregateObjectDirectlyAccessed` query
"c/misra/atomic-aggregate-object-directly-accessed" and
ruleId = "RULE-12-6" and
category = "required"
or
query =
// `Query` instance for the `invalidMemoryOrderArgument` query
Concurrency6Package::invalidMemoryOrderArgumentQuery() and
queryId =
// `@id` for the `invalidMemoryOrderArgument` query
"c/misra/invalid-memory-order-argument" and
ruleId = "RULE-21-25" and
category = "required"
or
query =
// `Query` instance for the `threadPreviouslyJoinedOrDetached` query
Concurrency6Package::threadPreviouslyJoinedOrDetachedQuery() and
queryId =
// `@id` for the `threadPreviouslyJoinedOrDetached` query
"c/misra/thread-previously-joined-or-detached" and
ruleId = "RULE-22-11" and
category = "required"
}
module Concurrency6Package {
Query notNoDeadlocksBetweenThreadsQuery() {
//autogenerate `Query` type
result =
// `Query` type for `notNoDeadlocksBetweenThreads` query
TQueryC(TConcurrency6PackageQuery(TNotNoDeadlocksBetweenThreadsQuery()))
}
Query threadCreatedByThreadQuery() {
//autogenerate `Query` type
result =
// `Query` type for `threadCreatedByThread` query
TQueryC(TConcurrency6PackageQuery(TThreadCreatedByThreadQuery()))
}
Query bannedDynamicThreadCreationQuery() {
//autogenerate `Query` type
result =
// `Query` type for `bannedDynamicThreadCreation` query
TQueryC(TConcurrency6PackageQuery(TBannedDynamicThreadCreationQuery()))
}
Query atomicAggregateObjectDirectlyAccessedQuery() {
//autogenerate `Query` type
result =
// `Query` type for `atomicAggregateObjectDirectlyAccessed` query
TQueryC(TConcurrency6PackageQuery(TAtomicAggregateObjectDirectlyAccessedQuery()))
}
Query invalidMemoryOrderArgumentQuery() {
//autogenerate `Query` type
result =
// `Query` type for `invalidMemoryOrderArgument` query
TQueryC(TConcurrency6PackageQuery(TInvalidMemoryOrderArgumentQuery()))
}
Query threadPreviouslyJoinedOrDetachedQuery() {
//autogenerate `Query` type
result =
// `Query` type for `threadPreviouslyJoinedOrDetached` query
TQueryC(TConcurrency6PackageQuery(TThreadPreviouslyJoinedOrDetachedQuery()))
}
}

Просмотреть файл

@ -12,6 +12,7 @@ import Concurrency2
import Concurrency3
import Concurrency4
import Concurrency5
import Concurrency6
import Contracts
import Contracts1
import Contracts2
@ -93,6 +94,7 @@ newtype TCQuery =
TConcurrency3PackageQuery(Concurrency3Query q) or
TConcurrency4PackageQuery(Concurrency4Query q) or
TConcurrency5PackageQuery(Concurrency5Query q) or
TConcurrency6PackageQuery(Concurrency6Query q) or
TContractsPackageQuery(ContractsQuery q) or
TContracts1PackageQuery(Contracts1Query q) or
TContracts2PackageQuery(Contracts2Query q) or
@ -174,6 +176,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isConcurrency3QueryMetadata(query, queryId, ruleId, category) or
isConcurrency4QueryMetadata(query, queryId, ruleId, category) or
isConcurrency5QueryMetadata(query, queryId, ruleId, category) or
isConcurrency6QueryMetadata(query, queryId, ruleId, category) or
isContractsQueryMetadata(query, queryId, ruleId, category) or
isContracts1QueryMetadata(query, queryId, ruleId, category) or
isContracts2QueryMetadata(query, queryId, ruleId, category) or

Просмотреть файл

@ -0,0 +1,49 @@
/**
* Provides a library with a `problems` predicate for the following issue:
* Joining or detaching a previously joined or detached thread can lead to undefined
* program behavior.
*/
import cpp
import codingstandards.cpp.Customizations
import codingstandards.cpp.Exclusions
import codingstandards.cpp.Concurrency
abstract class JoinOrDetachThreadOnlyOnceSharedQuery extends Query { }
Query getQuery() { result instanceof JoinOrDetachThreadOnlyOnceSharedQuery }
// OK
// 1) Thread calls detach parent DOES NOT call join
// 2) Parent calls join, thread does NOT call detach()
// NOT OK
// 1) Thread calls detach, parent calls join
// 2) Thread calls detach twice, parent does not call join
// 3) Parent calls join twice, thread does not call detach
query predicate problems(C11ThreadCreateCall tcc, string message) {
not isExcluded(tcc, getQuery()) and
message = "Thread may call join or detach after the thread is joined or detached." and
(
// Note: These cases can be simplified but they are presented like this for clarity
// case 1 - calls to `thrd_join` and `thrd_detach` within the parent or
// within the parent / child CFG.
exists(C11ThreadWait tw, C11ThreadDetach dt |
tw = getAThreadContextAwareSuccessor(tcc) and
dt = getAThreadContextAwareSuccessor(tcc)
)
or
// case 2 - multiple calls to `thrd_detach` within the threaded CFG.
exists(C11ThreadDetach dt1, C11ThreadDetach dt2 |
dt1 = getAThreadContextAwareSuccessor(tcc) and
dt2 = getAThreadContextAwareSuccessor(tcc) and
not dt1 = dt2
)
or
// case 3 - multiple calls to `thrd_join` within the threaded CFG.
exists(C11ThreadWait tw1, C11ThreadWait tw2 |
tw1 = getAThreadContextAwareSuccessor(tcc) and
tw2 = getAThreadContextAwareSuccessor(tcc) and
not tw1 = tw2
)
)
}

Просмотреть файл

@ -12,6 +12,7 @@
"precision": "high",
"severity": "error",
"short_name": "ThreadWasPreviouslyJoinedOrDetached",
"shared_implementation_short_name": "JoinOrDetachThreadOnlyOnce",
"tags": [
"correctness",
"concurrency"

Просмотреть файл

@ -0,0 +1,132 @@
{
"MISRA-C-2012": {
"DIR-5-2": {
"properties": {
"obligation": "required"
},
"queries": [
{
"description": "Circular waits leading to thread deadlocks may be avoided by locking in a predefined order.",
"kind": "problem",
"name": "There shall be no deadlocks between threads",
"precision": "very-high",
"severity": "error",
"short_name": "NotNoDeadlocksBetweenThreads",
"shared_implementation_short_name": "PreventDeadlockByLockingInPredefinedOrder",
"tags": [
"external/misra/c/2012/amendment4",
"correctness",
"concurrency"
]
}
],
"title": "There shall be no deadlocks between threads"
},
"DIR-5-3": {
"properties": {
"obligation": "required"
},
"queries": [
{
"description": "Creating threads within threads creates uncertainty in program behavior and concurrency overhead costs.",
"kind": "problem",
"name": "Threads shall not be created by other threads",
"precision": "high",
"severity": "error",
"short_name": "ThreadCreatedByThread",
"tags": [
"external/misra/c/2012/amendment4",
"correctness",
"maintainability",
"concurrency",
"performance"
]
},
{
"description": "Creating threads outside of a well-defined program start-up phase creates uncertainty in program behavior and concurrency overhead costs.",
"kind": "problem",
"name": "There shall be no dynamic thread creation",
"precision": "low",
"severity": "error",
"short_name": "BannedDynamicThreadCreation",
"tags": [
"external/misra/c/2012/amendment4",
"external/misra/c/audit",
"correctness",
"maintainability",
"concurrency",
"performance"
]
}
],
"title": "There shall be no dynamic thread creation"
},
"RULE-12-6": {
"properties": {
"obligation": "required"
},
"queries": [
{
"description": "Accessing a member of an atomic structure or union results in undefined behavior.",
"kind": "problem",
"name": "Structure and union members of atomic objects shall not be directly accessed",
"precision": "very-high",
"severity": "error",
"short_name": "AtomicAggregateObjectDirectlyAccessed",
"tags": [
"external/misra/c/2012/amendment4",
"correctness",
"concurrency"
]
}
],
"title": "Structure and union members of atomic objects shall not be directly accessed"
},
"RULE-21-25": {
"properties": {
"obligation": "required"
},
"queries": [
{
"description": "Only the memory ordering of 'memory_order_seq_cst' is fully portable and consistent.",
"kind": "path-problem",
"name": "All memory synchronization operations shall be executed in sequentially consistent order",
"precision": "very-high",
"severity": "error",
"short_name": "InvalidMemoryOrderArgument",
"tags": [
"external/misra/c/2012/amendment4",
"correctness",
"concurrency"
]
}
],
"title": "All memory synchronization operations shall be executed in sequentially consistent order"
},
"RULE-22-11": {
"properties": {
"obligation": "required"
},
"queries": [
{
"description": "Joining or detaching a previously joined or detached thread can lead to undefined program behavior.",
"kind": "problem",
"name": "A thread that was previously either joined or detached shall not be subsequently joined nor detached",
"precision": "high",
"severity": "error",
"short_name": "ThreadPreviouslyJoinedOrDetached",
"shared_implementation_short_name": "JoinOrDetachThreadOnlyOnce",
"tags": [
"external/misra/c/2012/amendment4",
"correctness",
"concurrency"
],
"implementation_scope": {
"description": "This query considers problematic usages of join and detach irrespective of the execution of the program and other synchronization and interprocess communication mechanisms that may be used."
}
}
],
"title": "A thread that was previously either joined or detached shall not be subsequently joined nor detached"
}
}
}

Просмотреть файл

@ -617,7 +617,7 @@ c,MISRA-C-2012,DIR-4-12,Yes,Required,,,Dynamic memory allocation shall not be us
c,MISRA-C-2012,DIR-4-13,No,Advisory,,,Functions which are designed to provide operations on a resource should be called in an appropriate sequence,,,,"Rule 22.1, 22.2 and 22.6 cover aspects of this rule. In other cases this is a design issue and needs to be checked manually."
c,MISRA-C-2012,DIR-4-14,Yes,Required,,,The validity of values received from external sources shall be checked,,Contracts8,Hard,This is supported by CodeQLs default C security queries.
c,MISRA-C-2012,DIR-4-15,Yes,Required,,,Evaluation of floating-point expressions shall not lead to the undetected generation of infinities and NaNs,FLP32-C and FLP04-C,FloatingTypes2,Medium,
c,MISRA-C-2012,DIR-5-1,Yes,Required,,,There shall be no data races between threads,CON43-C and CON32-C,Concurrency6,Very Hard,
c,MISRA-C-2012,DIR-5-1,Yes,Required,,,There shall be no data races between threads,CON43-C and CON32-C,Concurrency7,Very Hard,
c,MISRA-C-2012,DIR-5-2,Yes,Required,,,There shall be no deadlocks between threads,CON35-C,Concurrency6,Import,
c,MISRA-C-2012,DIR-5-3,Yes,Required,,,There shall be no dynamic thread creation,,Concurrency6,Easy,
c,MISRA-C-2012,RULE-1-1,No,Required,,,"The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits",,,Easy,"This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps."
@ -678,7 +678,7 @@ c,MISRA-C-2012,RULE-9-3,Yes,Required,,,Arrays shall not be partially initialized
c,MISRA-C-2012,RULE-9-4,Yes,Required,,,An element of an object shall not be initialized more than once,,Memory1,Medium,
c,MISRA-C-2012,RULE-9-5,No,Required,,,Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly,,,Medium,
c,MISRA-C-2012,RULE-9-6,Yes,Required,,,An initializer using chained designators shall not contain initializers without designators,,Declarations9,Hard,
c,MISRA-C-2012,RULE-9-7,Yes,Mandatory,,,Atomic objects shall be appropriately initialized before being accessed,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-9-7,Yes,Mandatory,,,Atomic objects shall be appropriately initialized before being accessed,,Concurrency7,Hard,
c,MISRA-C-2012,RULE-10-1,Yes,Required,,,Operands shall not be of an inappropriate essential type,,EssentialTypes,Hard,
c,MISRA-C-2012,RULE-10-2,Yes,Required,,,Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations,,EssentialTypes,Medium,
c,MISRA-C-2012,RULE-10-3,Yes,Required,,,The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category,,EssentialTypes,Hard,
@ -791,7 +791,7 @@ c,MISRA-C-2012,RULE-21-22,Yes,Mandatory,,,All operand arguments to any type-gene
c,MISRA-C-2012,RULE-21-23,Yes,Required,,,All operand arguments to any multi-argument type-generic macros in <tgmath.h> shall have the same standard type,Rule-21-22,EssentialTypes2,Easy,
c,MISRA-C-2012,RULE-21-24,Yes,Required,,,The random number generator functions of <stdlib.h> shall not be used,MSC30-C,Banned2,Easy,
c,MISRA-C-2012,RULE-21-25,Yes,Required,,,All memory synchronization operations shall be executed in sequentially consistent order,,Concurrency6,Medium,
c,MISRA-C-2012,RULE-21-26,Yes,Required,,,The Standard Library function mtx_timedlock() shall only be invoked on mutex objects of appropriate mutex type,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-21-26,Yes,Required,,,The Standard Library function mtx_timedlock() shall only be invoked on mutex objects of appropriate mutex type,,Concurrency7,Hard,
c,MISRA-C-2012,RULE-22-1,Yes,Required,,,All resources obtained dynamically by means of Standard Library functions shall be explicitly released,,Memory2,Hard,
c,MISRA-C-2012,RULE-22-2,Yes,Mandatory,,,A block of memory shall only be freed if it was allocated by means of a Standard Library function,,Memory2,Hard,
c,MISRA-C-2012,RULE-22-3,Yes,Required,,,The same file shall not be open for read and write access at the same time on different streams,,IO3,Hard,
@ -803,15 +803,15 @@ c,MISRA-C-2012,RULE-22-8,Yes,Required,,,The value of errno shall be set to zero
c,MISRA-C-2012,RULE-22-9,Yes,Required,,,The value of errno shall be tested against zero after calling an errno-setting-function,,Contracts3,Medium,
c,MISRA-C-2012,RULE-22-10,Yes,Required,,,The value of errno shall only be tested when the last function to be called was an errno-setting-function,,Contracts3,Medium,
c,MISRA-C-2012,RULE-22-11,Yes,Required,,,A thread that was previously either joined or detached shall not be subsequently joined nor detached,CON39-C,Concurrency6,Import,
c,MISRA-C-2012,RULE-22-12,Yes,Mandatory,,,"Thread objects, thread synchronization objects, and thread-specific storage pointers shall only be accessed by the appropriate Standard Library functions",,Concurrency6,Medium,
c,MISRA-C-2012,RULE-22-13,Yes,Required,,,"Thread objects, thread synchronization objects, and thread specific storage pointers shall have appropriate storage duration",EXP54-CPP and CON34-C,Concurrency6,Medium,
c,MISRA-C-2012,RULE-22-14,Yes,Mandatory,,,Thread synchronization objects shall be initialized before being accessed,EXP53-CPP,Concurrency6,Hard,
c,MISRA-C-2012,RULE-22-15,Yes,Required,,,Thread synchronization objects and thread-specific storage pointers shall not be destroyed until after all threads accessing them have terminated,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-22-16,Yes,Required,,,All mutex objects locked by a thread shall be explicitly unlocked by the same thread,MEM51-CPP,Concurrency6,Hard,
c,MISRA-C-2012,RULE-22-17,Yes,Required,,,No thread shall unlock a mutex or call cnd_wait() or cnd_timedwait() for a mutex it has not locked before,Rule 22.2,Concurrency6,Medium,
c,MISRA-C-2012,RULE-22-18,Yes,Required,,,Non-recursive mutexes shall not be recursively locked,CON56-CPP,Concurrency6,Medium,
c,MISRA-C-2012,RULE-22-19,Yes,Required,,,A condition variable shall be associated with at most one mutex object,,Concurrency6,Medium,
c,MISRA-C-2012,RULE-22-20,Yes,Mandatory,,,Thread-specific storage pointers shall be created before being accessed,,Concurrency6,Hard,
c,MISRA-C-2012,RULE-22-12,Yes,Mandatory,,,"Thread objects, thread synchronization objects, and thread-specific storage pointers shall only be accessed by the appropriate Standard Library functions",,Concurrency7,Medium,
c,MISRA-C-2012,RULE-22-13,Yes,Required,,,"Thread objects, thread synchronization objects, and thread specific storage pointers shall have appropriate storage duration",EXP54-CPP and CON34-C,Concurrency7,Medium,
c,MISRA-C-2012,RULE-22-14,Yes,Mandatory,,,Thread synchronization objects shall be initialized before being accessed,EXP53-CPP,Concurrency7,Hard,
c,MISRA-C-2012,RULE-22-15,Yes,Required,,,Thread synchronization objects and thread-specific storage pointers shall not be destroyed until after all threads accessing them have terminated,,Concurrency7,Hard,
c,MISRA-C-2012,RULE-22-16,Yes,Required,,,All mutex objects locked by a thread shall be explicitly unlocked by the same thread,MEM51-CPP,Concurrency7,Hard,
c,MISRA-C-2012,RULE-22-17,Yes,Required,,,No thread shall unlock a mutex or call cnd_wait() or cnd_timedwait() for a mutex it has not locked before,Rule 22.2,Concurrency7,Medium,
c,MISRA-C-2012,RULE-22-18,Yes,Required,,,Non-recursive mutexes shall not be recursively locked,CON56-CPP,Concurrency7,Medium,
c,MISRA-C-2012,RULE-22-19,Yes,Required,,,A condition variable shall be associated with at most one mutex object,,Concurrency7,Medium,
c,MISRA-C-2012,RULE-22-20,Yes,Mandatory,,,Thread-specific storage pointers shall be created before being accessed,,Concurrency7,Hard,
c,MISRA-C-2012,RULE-23-1,Yes,Advisory,,,A generic selection should only be expanded from a macro,,Generics,Medium,
c,MISRA-C-2012,RULE-23-2,Yes,Required,,,A generic selection that is not expanded from a macro shall not contain potential side effects in the controlling expression,,Generics,Hard,
c,MISRA-C-2012,RULE-23-3,Yes,Advisory,,,A generic selection should contain at least one non-default association,,Generics,Easy,

1 Language Standard ID Supportable Obligation level Enforcement level Allocated target Description Similar Package Difficulty Justification for querability level
617 c MISRA-C-2012 DIR-4-13 No Advisory Functions which are designed to provide operations on a resource should be called in an appropriate sequence Rule 22.1, 22.2 and 22.6 cover aspects of this rule. In other cases this is a design issue and needs to be checked manually.
618 c MISRA-C-2012 DIR-4-14 Yes Required The validity of values received from external sources shall be checked Contracts8 Hard This is supported by CodeQLs default C security queries.
619 c MISRA-C-2012 DIR-4-15 Yes Required Evaluation of floating-point expressions shall not lead to the undetected generation of infinities and NaNs FLP32-C and FLP04-C FloatingTypes2 Medium
620 c MISRA-C-2012 DIR-5-1 Yes Required There shall be no data races between threads CON43-C and CON32-C Concurrency6 Concurrency7 Very Hard
621 c MISRA-C-2012 DIR-5-2 Yes Required There shall be no deadlocks between threads CON35-C Concurrency6 Import
622 c MISRA-C-2012 DIR-5-3 Yes Required There shall be no dynamic thread creation Concurrency6 Easy
623 c MISRA-C-2012 RULE-1-1 No Required The program shall contain no violations of the standard C syntax and constraints, and shall not exceed the implementation's translation limits Easy This should be checked via the compiler output, rather than CodeQL, which adds unnecessary steps.
678 c MISRA-C-2012 RULE-9-4 Yes Required An element of an object shall not be initialized more than once Memory1 Medium
679 c MISRA-C-2012 RULE-9-5 No Required Where designated initializers are used to initialize an array object the size of the array shall be specified explicitly Medium
680 c MISRA-C-2012 RULE-9-6 Yes Required An initializer using chained designators shall not contain initializers without designators Declarations9 Hard
681 c MISRA-C-2012 RULE-9-7 Yes Mandatory Atomic objects shall be appropriately initialized before being accessed Concurrency6 Concurrency7 Hard
682 c MISRA-C-2012 RULE-10-1 Yes Required Operands shall not be of an inappropriate essential type EssentialTypes Hard
683 c MISRA-C-2012 RULE-10-2 Yes Required Expressions of essentially character type shall not be used inappropriately in addition and subtraction operations EssentialTypes Medium
684 c MISRA-C-2012 RULE-10-3 Yes Required The value of an expression shall not be assigned to an object with a narrower essential type or of a different essential type category EssentialTypes Hard
791 c MISRA-C-2012 RULE-21-23 Yes Required All operand arguments to any multi-argument type-generic macros in <tgmath.h> shall have the same standard type Rule-21-22 EssentialTypes2 Easy
792 c MISRA-C-2012 RULE-21-24 Yes Required The random number generator functions of <stdlib.h> shall not be used MSC30-C Banned2 Easy
793 c MISRA-C-2012 RULE-21-25 Yes Required All memory synchronization operations shall be executed in sequentially consistent order Concurrency6 Medium
794 c MISRA-C-2012 RULE-21-26 Yes Required The Standard Library function mtx_timedlock() shall only be invoked on mutex objects of appropriate mutex type Concurrency6 Concurrency7 Hard
795 c MISRA-C-2012 RULE-22-1 Yes Required All resources obtained dynamically by means of Standard Library functions shall be explicitly released Memory2 Hard
796 c MISRA-C-2012 RULE-22-2 Yes Mandatory A block of memory shall only be freed if it was allocated by means of a Standard Library function Memory2 Hard
797 c MISRA-C-2012 RULE-22-3 Yes Required The same file shall not be open for read and write access at the same time on different streams IO3 Hard
803 c MISRA-C-2012 RULE-22-9 Yes Required The value of errno shall be tested against zero after calling an errno-setting-function Contracts3 Medium
804 c MISRA-C-2012 RULE-22-10 Yes Required The value of errno shall only be tested when the last function to be called was an errno-setting-function Contracts3 Medium
805 c MISRA-C-2012 RULE-22-11 Yes Required A thread that was previously either joined or detached shall not be subsequently joined nor detached CON39-C Concurrency6 Import
806 c MISRA-C-2012 RULE-22-12 Yes Mandatory Thread objects, thread synchronization objects, and thread-specific storage pointers shall only be accessed by the appropriate Standard Library functions Concurrency6 Concurrency7 Medium
807 c MISRA-C-2012 RULE-22-13 Yes Required Thread objects, thread synchronization objects, and thread specific storage pointers shall have appropriate storage duration EXP54-CPP and CON34-C Concurrency6 Concurrency7 Medium
808 c MISRA-C-2012 RULE-22-14 Yes Mandatory Thread synchronization objects shall be initialized before being accessed EXP53-CPP Concurrency6 Concurrency7 Hard
809 c MISRA-C-2012 RULE-22-15 Yes Required Thread synchronization objects and thread-specific storage pointers shall not be destroyed until after all threads accessing them have terminated Concurrency6 Concurrency7 Hard
810 c MISRA-C-2012 RULE-22-16 Yes Required All mutex objects locked by a thread shall be explicitly unlocked by the same thread MEM51-CPP Concurrency6 Concurrency7 Hard
811 c MISRA-C-2012 RULE-22-17 Yes Required No thread shall unlock a mutex or call cnd_wait() or cnd_timedwait() for a mutex it has not locked before Rule 22.2 Concurrency6 Concurrency7 Medium
812 c MISRA-C-2012 RULE-22-18 Yes Required Non-recursive mutexes shall not be recursively locked CON56-CPP Concurrency6 Concurrency7 Medium
813 c MISRA-C-2012 RULE-22-19 Yes Required A condition variable shall be associated with at most one mutex object Concurrency6 Concurrency7 Medium
814 c MISRA-C-2012 RULE-22-20 Yes Mandatory Thread-specific storage pointers shall be created before being accessed Concurrency6 Concurrency7 Hard
815 c MISRA-C-2012 RULE-23-1 Yes Advisory A generic selection should only be expanded from a macro Generics Medium
816 c MISRA-C-2012 RULE-23-2 Yes Required A generic selection that is not expanded from a macro shall not contain potential side effects in the controlling expression Generics Hard
817 c MISRA-C-2012 RULE-23-3 Yes Advisory A generic selection should contain at least one non-default association Generics Easy