From 012ac3d82d39d4474102ecccc94d1ab33312227c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 7 Jul 2025 16:48:05 +0200 Subject: [PATCH 01/13] Create temporary copies of parts of the concurrency library These use the new dataflow library --- .../codingstandards/cpp/ConcurrencyNew.qll | 15 ++ .../cpp/concurrency/LockingOperationNew.qll | 235 +++++++++++++++++ .../concurrency/ThreadDependentMutexNew.qll | 246 ++++++++++++++++++ .../concurrency/ThreadSpecificStorageNew.qll | 59 +++++ 4 files changed, 555 insertions(+) create mode 100644 cpp/common/src/codingstandards/cpp/ConcurrencyNew.qll create mode 100644 cpp/common/src/codingstandards/cpp/concurrency/LockingOperationNew.qll create mode 100644 cpp/common/src/codingstandards/cpp/concurrency/ThreadDependentMutexNew.qll create mode 100644 cpp/common/src/codingstandards/cpp/concurrency/ThreadSpecificStorageNew.qll diff --git a/cpp/common/src/codingstandards/cpp/ConcurrencyNew.qll b/cpp/common/src/codingstandards/cpp/ConcurrencyNew.qll new file mode 100644 index 000000000..37aea0188 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/ConcurrencyNew.qll @@ -0,0 +1,15 @@ +import cpp +import semmle.code.cpp.dataflow.new.TaintTracking +import codingstandards.cpp.concurrency.Atomic +import codingstandards.cpp.concurrency.CConditionOperation +import codingstandards.cpp.concurrency.ControlFlow +import codingstandards.cpp.concurrency.ConditionalWait +import codingstandards.cpp.concurrency.LockingOperationNew +import codingstandards.cpp.concurrency.LockProtectedControlFlow +import codingstandards.cpp.concurrency.MutexDestroyer +import codingstandards.cpp.concurrency.ThreadCreation +import codingstandards.cpp.concurrency.ThreadedFunction +import codingstandards.cpp.concurrency.ThreadDependentMutexNew +import codingstandards.cpp.concurrency.ThreadSpecificStorageNew +import codingstandards.cpp.concurrency.ThreadWaitDetach +import codingstandards.cpp.concurrency.Types diff --git a/cpp/common/src/codingstandards/cpp/concurrency/LockingOperationNew.qll b/cpp/common/src/codingstandards/cpp/concurrency/LockingOperationNew.qll new file mode 100644 index 000000000..114b56920 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/concurrency/LockingOperationNew.qll @@ -0,0 +1,235 @@ +import cpp +import semmle.code.cpp.dataflow.new.TaintTracking + +abstract class LockingOperation extends FunctionCall { + /** + * Returns the target of the lock underlying this RAII-style lock. + */ + abstract Variable getLock(); + + /** + * Returns the lock underlying this RAII-style lock. + */ + abstract Expr getLockExpr(); + + /** + * Holds if this is a lock operation + */ + abstract predicate isLock(); + + /** + * Holds if this is an unlock operation + */ + abstract predicate isUnlock(); + + /** + * Holds if this locking operation is really a locking operation within a + * designated locking operation. This library assumes the underlying locking + * operations are implemented correctly in that calling a `LockingOperation` + * results in the creation of a singular lock. + */ + predicate isLockingOperationWithinLockingOperation(LockingOperation inner) { + exists(LockingOperation outer | outer.getTarget() = inner.getEnclosingFunction()) + } +} + +/** + * Common base class providing an interface into function call + * based mutex locks. + */ +abstract class MutexFunctionCall extends LockingOperation { + abstract predicate isRecursive(); + + abstract predicate isSpeculativeLock(); + + abstract predicate unlocks(MutexFunctionCall fc); +} + +/** + * Models calls to various mutex types found in CPP. + */ +class CPPMutexFunctionCall extends MutexFunctionCall { + VariableAccess var; + + CPPMutexFunctionCall() { + getTarget() + .(MemberFunction) + .getDeclaringType() + .hasQualifiedName("std", + ["mutex", "timed_mutex", "shared_timed_mutex", "recursive_mutex", "recursive_timed_mutex"]) and + var = getQualifier() + } + + /** + * Holds if this mutex is a recursive mutex. + */ + override predicate isRecursive() { + getTarget() + .(MemberFunction) + .getDeclaringType() + .hasQualifiedName("std", ["recursive_mutex", "recursive_timed_mutex"]) + } + + /** + * Holds if this `CPPMutexFunctionCall` is a lock. + */ + override predicate isLock() { + not isLockingOperationWithinLockingOperation(this) and + getTarget().getName() = "lock" + } + + /** + * Holds if this `CPPMutexFunctionCall` is a speculative lock, defined as calling + * one of the speculative locking functions such as `try_lock`. + */ + override predicate isSpeculativeLock() { + getTarget().getName() in [ + "try_lock", "try_lock_for", "try_lock_until", "try_lock_shared_for", "try_lock_shared_until" + ] + } + + /** + * Returns the lock to which this `CPPMutexFunctionCall` refers to. + */ + override Variable getLock() { result = getQualifier().(VariableAccess).getTarget() } + + /** + * Returns the qualifier for this `CPPMutexFunctionCall`. + */ + override Expr getLockExpr() { result = var } + + /** + * Holds if this is a `unlock` and *may* unlock the previously locked `MutexFunctionCall`. + * This predicate does not check that the mutex is currently locked. + */ + override predicate unlocks(MutexFunctionCall fc) { + isUnlock() and + fc.getQualifier().(VariableAccess).getTarget() = getQualifier().(VariableAccess).getTarget() + } + + /** + * Holds if this is an unlock call. + */ + override predicate isUnlock() { getTarget().getName() = "unlock" } +} + +/** + * Models calls to various mutex types specialized to C code. + */ +class CMutexFunctionCall extends MutexFunctionCall { + Expr arg; + + CMutexFunctionCall() { + // the non recursive kinds + getTarget().getName() = ["mtx_lock", "mtx_unlock", "mtx_timedlock", "mtx_trylock"] and + arg = getArgument(0) + } + + /** + * Holds if this mutex is a recursive mutex. + */ + override predicate isRecursive() { none() } + + /** + * Holds if this `CMutexFunctionCall` is a lock. + */ + override predicate isLock() { + not isLockingOperationWithinLockingOperation(this) and + getTarget().getName() = ["mtx_lock", "mtx_timedlock", "mtx_trylock"] + } + + /** + * Holds if this `CMutexFunctionCall` is a speculative lock, defined as calling + * one of the speculative locking functions such as `try_lock`. + */ + override predicate isSpeculativeLock() { + getTarget().getName() in ["mtx_timedlock", "mtx_trylock"] + } + + /** + * Returns the `Variable` to which this `CMutexFunctionCall` refers to. For this + * style of lock it can reference a number of different variables. + */ + override Variable getLock() { + exists(VariableAccess va | + TaintTracking::localTaint(DataFlow::exprNode(va), DataFlow::exprNode(getLockExpr())) and + result = va.getTarget() + ) + } + + /** + * Returns the expression for this `CMutexFunctionCall`. + */ + override Expr getLockExpr() { result = arg } + + /** + * Holds if this is a `unlock` and *may* unlock the previously locked `CMutexFunctionCall`. + * This predicate does not check that the mutex is currently locked. + */ + override predicate unlocks(MutexFunctionCall fc) { + isUnlock() and + fc.getLock() = getLock() + } + + /** + * Holds if this is an unlock call. + */ + override predicate isUnlock() { getTarget().getName() = "mtx_unlock" } +} + +/** + * Models a RAII-Style lock. + */ +class RAIIStyleLock extends LockingOperation { + VariableAccess lock; + + RAIIStyleLock() { + ( + getTarget().getDeclaringType().hasQualifiedName("std", "lock_guard") or + getTarget().getDeclaringType().hasQualifiedName("std", "unique_lock") or + getTarget().getDeclaringType().hasQualifiedName("std", "scoped_lock") + ) and + ( + lock = getArgument(0).getAChild*() + or + this instanceof DestructorCall and + exists(RAIIStyleLock constructor | + constructor = getQualifier().(VariableAccess).getTarget().getInitializer().getExpr() and + lock = constructor.getArgument(0).getAChild*() + ) + ) + } + + /** + * Holds if this is a lock operation + */ + override predicate isLock() { + not isLockingOperationWithinLockingOperation(this) and + this instanceof ConstructorCall and + lock = getArgument(0).getAChild*() and + // defer_locks don't cause a lock + not exists(Expr exp | + exp = getArgument(1) and + exp.(VariableAccess) + .getTarget() + .getUnderlyingType() + .(Class) + .hasQualifiedName("std", "defer_lock_t") + ) + } + + /** + * Holds if this is an unlock operation + */ + override predicate isUnlock() { this instanceof DestructorCall } + + /** + * Returns the target of the lock underlying this RAII-style lock. + */ + override Variable getLock() { result = lock.getTarget() } + + /** + * Returns the lock underlying this RAII-style lock. + */ + override Expr getLockExpr() { result = lock } +} diff --git a/cpp/common/src/codingstandards/cpp/concurrency/ThreadDependentMutexNew.qll b/cpp/common/src/codingstandards/cpp/concurrency/ThreadDependentMutexNew.qll new file mode 100644 index 000000000..c761e2b1b --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/concurrency/ThreadDependentMutexNew.qll @@ -0,0 +1,246 @@ +import cpp +import semmle.code.cpp.dataflow.new.TaintTracking +private import codingstandards.cpp.concurrency.ControlFlow +private import codingstandards.cpp.concurrency.ThreadedFunction + +abstract class MutexSource extends FunctionCall { } + +/** + * Models a C++ style mutex. + */ +class CPPMutexSource extends MutexSource, ConstructorCall { + CPPMutexSource() { getTarget().getDeclaringType().hasQualifiedName("std", "mutex") } +} + +/** + * Models a C11 style mutex. + */ +class C11MutexSource extends MutexSource, FunctionCall { + C11MutexSource() { getTarget().hasName("mtx_init") } + + Expr getMutexExpr() { result = getArgument(0) } + + Expr getMutexTypeExpr() { result = getArgument(1) } + + predicate isRecursive() { + exists(EnumConstantAccess recursive | + recursive = getMutexTypeExpr().getAChild*() and + recursive.getTarget().hasName("mtx_recursive") + ) + } +} + +/** + * Models a thread dependent mutex. A thread dependent mutex is a mutex + * that is used by a thread. This dependency is established either by directly + * passing in a mutex or by referencing a mutex that is in the local scope. The utility + * of this class is it captures the `DataFlow::Node` source at which the mutex + * came from. For example, if it is passed in from a local function to a thread. + * This functionality is critical, since it allows one to inspect how the thread + * behaves with respect to the owner of a resource. + * + * To model the myriad ways this can happen, the subclasses of this class are + * responsible for implementing the various usage patterns. + */ +abstract class ThreadDependentMutex extends DataFlow::Node { + DataFlow::Node sink; + + DataFlow::Node getASource() { + // the source is either the thing that declared + // the mutex + result = this + or + // or the thread we are using it in + result = getAThreadSource() + } + + /** + * Gets the dataflow nodes corresponding to thread local usages of the + * dependent mutex. + */ + DataFlow::Node getAThreadSource() { + // here we line up the actual parameter at the thread creation + // site with the formal parameter in the target thread. + // Note that there are differences between the C and C++ versions + // of the argument ordering in the thread creation function. However, + // since the C version only takes one parameter (as opposed to multiple) + // we can simplify this search by considering only the first argument. + exists(FunctionCall fc, Function f, int n | + // Get the argument to which the mutex flowed. + fc.getArgument(n) = sink.asExpr() and + // Get the thread function we are calling. + f = fc.getArgument(0).(FunctionAccess).getTarget() and + // in C++, there is an extra argument to the `std::thread` call + // so we must subtract 1 since this is not passed to the thread. + ( + result = DataFlow::exprNode(f.getParameter(n - 1).getAnAccess()) + or + // In C, only one argument is allowed. Thus IF the flow predicate holds, + // it will be to the first argument + result = DataFlow::exprNode(f.getParameter(0).getAnAccess()) + ) + ) + } + + /** + * Produces the set of dataflow nodes to thread creation for threads + * that are dependent on this mutex. + */ + DataFlow::Node getADependentThreadCreationExpr() { + exists(FunctionCall fc | + fc.getAnArgument() = sink.asExpr() and + result = DataFlow::exprNode(fc) + ) + } + + /** + * Gets a set of usages of this mutex in both the local and thread scope. + * In the case of scoped usage, this also captures typical accesses of variables. + */ + DataFlow::Node getAUsage() { TaintTracking::localTaint(getASource(), result) } +} + +/** + * This class models the type of thread/mutex dependency that is established + * through the typical parameter passing mechanisms found in C++. + */ +class FlowBasedThreadDependentMutex extends ThreadDependentMutex { + FlowBasedThreadDependentMutex() { + // some sort of dataflow, likely through parameter passing. + ThreadDependentMutexFlow::flow(this, sink) + } +} + +/** + * This class models the type of thread/mutex dependency that is established by + * either scope based accesses (e.g., global variables) or block scope differences. + */ +class AccessBasedThreadDependentMutex extends ThreadDependentMutex { + Variable variableSource; + + AccessBasedThreadDependentMutex() { + // encapsulates usages from outside scopes not directly expressed + // in dataflow. + exists(MutexSource mutexSrc, ThreadedFunction f | + DataFlow::exprNode(mutexSrc) = this and + // find a variable that was assigned the mutex + TaintTracking::localTaint(DataFlow::exprNode(mutexSrc), + DataFlow::exprNode(variableSource.getAnAssignedValue())) and + // find all subsequent accesses of that variable that are within a + // function and set those to the sink + exists(VariableAccess va | + va = variableSource.getAnAccess() and + va.getEnclosingFunction() = f and + sink = DataFlow::exprNode(va) + ) + ) + } + + override DataFlow::Node getAUsage() { DataFlow::exprNode(variableSource.getAnAccess()) = result } +} + +/** + * In the typical C thread model, a mutex is a created by a function that is not responsible + * for creating the variable. Thus this class encodes a slightly different semantics + * wherein the usage pattern is that of variables that have been both initialized + * and then subsequently passed into a thread directly. + */ +class DeclarationInitBasedThreadDependentMutex extends ThreadDependentMutex { + Variable variableSource; + + DeclarationInitBasedThreadDependentMutex() { + exists(MutexSource ms, ThreadCreationFunction tcf | + this = DataFlow::exprNode(ms) and + // accessed as a mutex source + TaintTracking::localTaint(DataFlow::exprNode(variableSource.getAnAccess()), + DataFlow::exprNode(ms.getAnArgument())) and + // subsequently passed to a thread creation function (order not strictly + // enforced for performance reasons) + sink = DataFlow::exprNode(tcf.getAnArgument()) and + TaintTracking::localTaint(DataFlow::exprNode(variableSource.getAnAccess()), sink) + ) + } + + override DataFlow::Node getAUsage() { + TaintTracking::localTaint(getASource(), result) or + DataFlow::exprNode(variableSource.getAnAccess()) = result + } + + override DataFlow::Node getASource() { + // the source is either the thing that declared + // the mutex + result = this + or + // or the thread we are using it in + result = getAThreadSource() + } + + DataFlow::Node getSink() { result = sink } + + /** + * Gets the dataflow nodes corresponding to thread local usages of the + * dependent mutex. + */ + override DataFlow::Node getAThreadSource() { + // here we line up the actual parameter at the thread creation + // site with the formal parameter in the target thread. + // Note that there are differences between the C and C++ versions + // of the argument ordering in the thread creation function. However, + // since the C version only takes one parameter (as opposed to multiple) + // we can simplify this search by considering only the first argument. + exists( + FunctionCall fc, Function f, int n // CPP Version + | + fc.getArgument(n) = sink.asExpr() and + f = fc.getArgument(0).(FunctionAccess).getTarget() and + // in C++, there is an extra argument to the `std::thread` call + // so we must subtract 1 since this is not passed to the thread. + result = DataFlow::exprNode(f.getParameter(n - 1).getAnAccess()) + ) + or + exists( + FunctionCall fc, Function f // C Version + | + fc.getAnArgument() = sink.asExpr() and + // in C, the second argument is the function + f = fc.getArgument(1).(FunctionAccess).getTarget() and + // in C, the passed argument is always the zeroth argument + result = DataFlow::exprNode(f.getParameter(0).getAnAccess()) + ) + } +} + +/** + * In the typical C model, another way to use mutexes is to work with global variables + * that can be initialized at various points -- one of which must be inside a thread. + * This class encapsulates this pattern. + */ +class DeclarationInitAccessBasedThreadDependentMutex extends ThreadDependentMutex { + Variable variableSource; + + DeclarationInitAccessBasedThreadDependentMutex() { + exists(MutexSource ms, ThreadedFunction tf, VariableAccess va | + this = DataFlow::exprNode(ms) and + // accessed as a mutex source + TaintTracking::localTaint(DataFlow::exprNode(variableSource.getAnAccess()), + DataFlow::exprNode(ms.getAnArgument())) and + // is accessed somewhere else + va = variableSource.getAnAccess() and + sink = DataFlow::exprNode(va) and + // one of which must be a thread + va.getEnclosingFunction() = tf + ) + } + + override DataFlow::Node getAUsage() { result = DataFlow::exprNode(variableSource.getAnAccess()) } +} + +module ThreadDependentMutexConfig implements DataFlow::ConfigSig { + predicate isSource(DataFlow::Node node) { node.asExpr() instanceof MutexSource } + + predicate isSink(DataFlow::Node node) { + exists(ThreadCreationFunction f | f.getAnArgument() = node.asExpr()) + } +} + +module ThreadDependentMutexFlow = TaintTracking::Global; diff --git a/cpp/common/src/codingstandards/cpp/concurrency/ThreadSpecificStorageNew.qll b/cpp/common/src/codingstandards/cpp/concurrency/ThreadSpecificStorageNew.qll new file mode 100644 index 000000000..6dcb16925 --- /dev/null +++ b/cpp/common/src/codingstandards/cpp/concurrency/ThreadSpecificStorageNew.qll @@ -0,0 +1,59 @@ +import cpp +private import semmle.code.cpp.dataflow.new.DataFlow +private import codingstandards.cpp.concurrency.ThreadCreation + +/** + * Models calls to thread specific storage function calls. + */ +abstract class ThreadSpecificStorageFunctionCall extends FunctionCall { + /** + * Gets the key to which this call references. + */ + Expr getKey() { getArgument(0) = result } +} + +/** + * Models calls to `tss_get`. + */ +class TSSGetFunctionCall extends ThreadSpecificStorageFunctionCall { + TSSGetFunctionCall() { getTarget().getName() = "tss_get" } +} + +/** + * Models calls to `tss_set`. + */ +class TSSSetFunctionCall extends ThreadSpecificStorageFunctionCall { + TSSSetFunctionCall() { getTarget().getName() = "tss_set" } +} + +/** + * Models calls to `tss_create` + */ +class TSSCreateFunctionCall extends ThreadSpecificStorageFunctionCall { + TSSCreateFunctionCall() { getTarget().getName() = "tss_create" } + + predicate hasDeallocator() { + not exists(MacroInvocation mi, NullMacro nm | + getArgument(1) = mi.getExpr() and + mi = nm.getAnInvocation() + ) + } +} + +/** + * Models calls to `tss_delete` + */ +class TSSDeleteFunctionCall extends ThreadSpecificStorageFunctionCall { + TSSDeleteFunctionCall() { getTarget().getName() = "tss_delete" } +} + +/** + * Gets a call to `DeallocationExpr` that deallocates memory owned by thread specific + * storage. + */ +predicate getAThreadSpecificStorageDeallocationCall(C11ThreadCreateCall tcc, DeallocationExpr dexp) { + exists(TSSGetFunctionCall tsg | + tcc.getFunction().getEntryPoint().getASuccessor*() = tsg and + DataFlow::localFlow(DataFlow::exprNode(tsg), DataFlow::exprNode(dexp.getFreedExpr())) + ) +} From 22b886028fb359b59d1ea5713356dfef0d5f5dbd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Mon, 7 Jul 2025 16:50:27 +0200 Subject: [PATCH 02/13] Convert CON30-C to use the new dataflow library --- c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql | 4 ++-- .../rules/CON30-C/CleanUpThreadSpecificStorage.expected | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql index 1e03c089e..afa664448 100644 --- a/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql +++ b/c/cert/src/rules/CON30-C/CleanUpThreadSpecificStorage.ql @@ -19,8 +19,8 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency -import semmle.code.cpp.dataflow.DataFlow +import codingstandards.cpp.ConcurrencyNew +import semmle.code.cpp.dataflow.new.DataFlow module TssCreateToTssDeleteConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node node) { diff --git a/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected b/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected index f3ea87136..e03b665a1 100644 --- a/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected +++ b/c/cert/test/rules/CON30-C/CleanUpThreadSpecificStorage.expected @@ -1,9 +1,3 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:25,46-54) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:26,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:35,20-28) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:45,35-43) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:53,36-44) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (CleanUpThreadSpecificStorage.ql:55,36-44) | test.c:27:3:27:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. | | test.c:49:3:49:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. | | test.c:71:3:71:12 | call to tss_create | Resources used by thread specific storage may not be cleaned up. | From 0a846c71cbc0cdebd3f891dc65a76a70702d0f5d Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 11:17:40 +0200 Subject: [PATCH 03/13] Convert CON34-C to the new dataflow library Since the new dataflow library uses use-use dataflow and not def-use dataflow, we now need to check for definitions. Note that these queries can probably be improved by using a dataflow configuration - possibly limited to the local context of a function by including `DataFlow::FeatureEqualSourceSinkCallContext` --- .../AppropriateThreadObjectStorageDurations.ql | 5 +++-- .../ThreadObjectStorageDurationsNotInitialized.ql | 7 ++++--- ...AppropriateThreadObjectStorageDurations.expected | 13 ------------- ...eadObjectStorageDurationsNotInitialized.expected | 5 ----- 4 files changed, 7 insertions(+), 23 deletions(-) diff --git a/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql b/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql index 4fb034406..10cdec5c7 100644 --- a/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql +++ b/c/cert/src/rules/CON34-C/AppropriateThreadObjectStorageDurations.ql @@ -20,8 +20,8 @@ import cpp import codingstandards.c.cert import codingstandards.c.Objects -import codingstandards.cpp.Concurrency -import semmle.code.cpp.dataflow.DataFlow +import codingstandards.cpp.ConcurrencyNew +import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.commons.Alloc from C11ThreadCreateCall tcc, Expr arg @@ -53,6 +53,7 @@ where not exists(TSSSetFunctionCall tss, DataFlow::Node src | // there should be dataflow from somewhere (the same somewhere) // into each of the first arguments + exists(Expr e | e = src.asDefinition() or e = src.asDefiningArgument()) and DataFlow::localFlow(src, DataFlow::exprNode(tsg.getArgument(0))) and DataFlow::localFlow(src, DataFlow::exprNode(tss.getArgument(0))) ) diff --git a/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql b/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql index 07b114d6c..40acc1e3e 100644 --- a/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql +++ b/c/cert/src/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.ql @@ -20,8 +20,8 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency -import semmle.code.cpp.dataflow.DataFlow +import codingstandards.cpp.ConcurrencyNew +import semmle.code.cpp.dataflow.new.DataFlow from TSSGetFunctionCall tsg, ThreadedFunction tf where @@ -31,7 +31,8 @@ where // however, there does not exist a proper sequencing. not exists(TSSSetFunctionCall tss, DataFlow::Node src | // there should be dataflow from somewhere (the same somewhere) - // into each of the first arguments + // into each of the first argument + exists(Expr e | e = src.asDefinition() or e = src.asDefiningArgument()) and DataFlow::localFlow(src, DataFlow::exprNode(tsg.getArgument(0))) and DataFlow::localFlow(src, DataFlow::exprNode(tss.getArgument(0))) ) diff --git a/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected b/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected index 2cd844f81..c3cdc8bd7 100644 --- a/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected +++ b/c/cert/test/rules/CON34-C/AppropriateThreadObjectStorageDurations.expected @@ -1,16 +1,3 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:35,14-22) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:37,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:39,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:42,45-53) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:52,33-41) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:52,58-66) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:53,42-50) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:56,9-17) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:56,34-42) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:57,9-17) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:57,34-42) -WARNING: module 'TaintTracking' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:42,9-22) -WARNING: module 'TaintTracking' has been deprecated and may be removed in future (AppropriateThreadObjectStorageDurations.ql:52,7-20) | test.c:23:3:23:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:23:24:23:29 | & ... | Shared object | | test.c:74:3:74:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:74:24:74:24 | p | Shared object | | test.c:85:3:85:13 | call to thrd_create | $@ not declared with appropriate storage duration | test.c:85:24:85:24 | p | Shared object | diff --git a/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected b/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected index b2ac853fb..95d0a2004 100644 --- a/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected +++ b/c/cert/test/rules/CON34-C/ThreadObjectStorageDurationsNotInitialized.expected @@ -1,6 +1 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:32,38-46) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:35,5-13) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:35,30-38) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:36,5-13) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ThreadObjectStorageDurationsNotInitialized.ql:36,30-38) | test.c:14:7:14:13 | call to tss_get | Call to a thread specific storage function from within a threaded context on an object that may not be owned by this thread. | From 1c1f3fb8f07bf8bb2b78212d8c4b08a3852c240c Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 12:46:28 +0200 Subject: [PATCH 04/13] Move queries not depending on dataflow over to `ConcurrencyNew` --- .../rules/CON33-C/RaceConditionsWhenUsingLibraryFunctions.ql | 2 +- .../src/rules/CON37-C/DoNotCallSignalInMultithreadedProgram.ql | 2 +- c/cert/src/rules/CON40-C/AtomicVariableTwiceInExpression.ql | 2 +- .../rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.ql | 2 +- .../c/initialization/GlobalInitializationAnalysis.qll | 2 +- c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql | 2 +- c/misra/src/rules/DIR-5-3/BannedDynamicThreadCreation.ql | 2 +- c/misra/src/rules/DIR-5-3/ThreadCreatedByThread.ql | 2 +- .../RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.ql | 2 +- .../src/rules/RULE-22-12/NonstandardUseOfThreadingObject.ql | 2 +- .../RULE-22-13/ThreadingObjectWithInvalidStorageDuration.ql | 2 +- c/misra/src/rules/RULE-22-14/MutexInitWithInvalidMutexType.ql | 2 +- c/misra/src/rules/RULE-22-14/MutexInitializedInsideThread.ql | 2 +- c/misra/src/rules/RULE-22-14/MutexNotInitializedBeforeUse.ql | 2 +- .../RULE-22-15/ThreadResourceDisposedBeforeThreadsJoined.ql | 2 +- .../src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql | 3 +-- .../src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLocked.ql | 2 +- .../RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql | 2 +- .../RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql | 2 +- .../rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql | 2 +- .../RULE-22-20/ThreadStoragePointerInitializedInsideThread.ql | 2 +- .../DoNotSpeculativelyLockALockedNonRecursiveMutex.ql | 2 +- .../src/rules/CON56-CPP/LockedALockedNonRecursiveMutexAudit.ql | 2 +- .../rules/guardaccesstobitfields/GuardAccessToBitFields.qll | 2 +- .../joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.qll | 2 +- .../PreserveSafetyWhenUsingConditionVariables.qll | 2 +- .../PreventDeadlockByLockingInPredefinedOrder.qll | 2 +- .../wrapspuriousfunctioninloop/WrapSpuriousFunctionInLoop.qll | 2 +- 28 files changed, 28 insertions(+), 29 deletions(-) diff --git a/c/cert/src/rules/CON33-C/RaceConditionsWhenUsingLibraryFunctions.ql b/c/cert/src/rules/CON33-C/RaceConditionsWhenUsingLibraryFunctions.ql index c9bcaa6bd..dadb21985 100644 --- a/c/cert/src/rules/CON33-C/RaceConditionsWhenUsingLibraryFunctions.ql +++ b/c/cert/src/rules/CON33-C/RaceConditionsWhenUsingLibraryFunctions.ql @@ -18,7 +18,7 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from ThreadedCFN node where diff --git a/c/cert/src/rules/CON37-C/DoNotCallSignalInMultithreadedProgram.ql b/c/cert/src/rules/CON37-C/DoNotCallSignalInMultithreadedProgram.ql index 17691f24d..72fe5b592 100644 --- a/c/cert/src/rules/CON37-C/DoNotCallSignalInMultithreadedProgram.ql +++ b/c/cert/src/rules/CON37-C/DoNotCallSignalInMultithreadedProgram.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from FunctionCall fc // This should only be applied in the context of a multi-threaded program (since diff --git a/c/cert/src/rules/CON40-C/AtomicVariableTwiceInExpression.ql b/c/cert/src/rules/CON40-C/AtomicVariableTwiceInExpression.ql index 0ec195868..cc85cd9d1 100644 --- a/c/cert/src/rules/CON40-C/AtomicVariableTwiceInExpression.ql +++ b/c/cert/src/rules/CON40-C/AtomicVariableTwiceInExpression.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from MacroInvocation mi, Variable v, Locatable whereFound where diff --git a/c/cert/src/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.ql b/c/cert/src/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.ql index 57be1bc48..d7754973f 100644 --- a/c/cert/src/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.ql +++ b/c/cert/src/rules/CON41-C/WrapFunctionsThatCanFailSpuriouslyInLoop.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.c.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from AtomicCompareExchange ace where diff --git a/c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll b/c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll index 2906883ae..cf32f9bdc 100644 --- a/c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll +++ b/c/common/src/codingstandards/c/initialization/GlobalInitializationAnalysis.qll @@ -1,6 +1,6 @@ import cpp import codingstandards.c.Objects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type signature module GlobalInitializationAnalysisConfigSig { diff --git a/c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql b/c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql index edf3705a9..768a2b1ae 100644 --- a/c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql +++ b/c/misra/src/rules/DIR-5-1/PossibleDataRaceBetweenThreads.ql @@ -17,7 +17,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.Objects import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew newtype TNonReentrantOperation = TReadWrite(SubObject object) { diff --git a/c/misra/src/rules/DIR-5-3/BannedDynamicThreadCreation.ql b/c/misra/src/rules/DIR-5-3/BannedDynamicThreadCreation.ql index 4bb526306..cb12a8156 100644 --- a/c/misra/src/rules/DIR-5-3/BannedDynamicThreadCreation.ql +++ b/c/misra/src/rules/DIR-5-3/BannedDynamicThreadCreation.ql @@ -18,7 +18,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from CThreadCreateCall tc, Function enclosingFunction where diff --git a/c/misra/src/rules/DIR-5-3/ThreadCreatedByThread.ql b/c/misra/src/rules/DIR-5-3/ThreadCreatedByThread.ql index 207e763fa..11f76de7a 100644 --- a/c/misra/src/rules/DIR-5-3/ThreadCreatedByThread.ql +++ b/c/misra/src/rules/DIR-5-3/ThreadCreatedByThread.ql @@ -17,7 +17,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew class CThreadRoot extends Function { CThreadCreateCall threadCreate; diff --git a/c/misra/src/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.ql b/c/misra/src/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.ql index 6a520447d..a8fea9558 100644 --- a/c/misra/src/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.ql +++ b/c/misra/src/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.Objects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from AssignExpr assignment, Element threadLocal, ObjectIdentity static where diff --git a/c/misra/src/rules/RULE-22-12/NonstandardUseOfThreadingObject.ql b/c/misra/src/rules/RULE-22-12/NonstandardUseOfThreadingObject.ql index d92b4ccea..15a437e7e 100644 --- a/c/misra/src/rules/RULE-22-12/NonstandardUseOfThreadingObject.ql +++ b/c/misra/src/rules/RULE-22-12/NonstandardUseOfThreadingObject.ql @@ -15,7 +15,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type predicate isThreadingObject(Type t) { t instanceof PossiblySpecified::Type } diff --git a/c/misra/src/rules/RULE-22-13/ThreadingObjectWithInvalidStorageDuration.ql b/c/misra/src/rules/RULE-22-13/ThreadingObjectWithInvalidStorageDuration.ql index 066cf3c29..18f367120 100644 --- a/c/misra/src/rules/RULE-22-13/ThreadingObjectWithInvalidStorageDuration.ql +++ b/c/misra/src/rules/RULE-22-13/ThreadingObjectWithInvalidStorageDuration.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.Objects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type from ObjectIdentity obj, StorageDuration storageDuration, Type type diff --git a/c/misra/src/rules/RULE-22-14/MutexInitWithInvalidMutexType.ql b/c/misra/src/rules/RULE-22-14/MutexInitWithInvalidMutexType.ql index a122a0bec..cda50fbf7 100644 --- a/c/misra/src/rules/RULE-22-14/MutexInitWithInvalidMutexType.ql +++ b/c/misra/src/rules/RULE-22-14/MutexInitWithInvalidMutexType.ql @@ -14,7 +14,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew predicate isBaseMutexType(EnumConstantAccess access) { access.getTarget().hasName(["mtx_plain", "mtx_timed"]) diff --git a/c/misra/src/rules/RULE-22-14/MutexInitializedInsideThread.ql b/c/misra/src/rules/RULE-22-14/MutexInitializedInsideThread.ql index 497fdaf14..4b6afe9f5 100644 --- a/c/misra/src/rules/RULE-22-14/MutexInitializedInsideThread.ql +++ b/c/misra/src/rules/RULE-22-14/MutexInitializedInsideThread.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from C11MutexSource mutexCreate, ThreadedFunction thread where diff --git a/c/misra/src/rules/RULE-22-14/MutexNotInitializedBeforeUse.ql b/c/misra/src/rules/RULE-22-14/MutexNotInitializedBeforeUse.ql index f78c25f98..7df3a2dc4 100644 --- a/c/misra/src/rules/RULE-22-14/MutexNotInitializedBeforeUse.ql +++ b/c/misra/src/rules/RULE-22-14/MutexNotInitializedBeforeUse.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.Objects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type import codingstandards.c.initialization.GlobalInitializationAnalysis diff --git a/c/misra/src/rules/RULE-22-15/ThreadResourceDisposedBeforeThreadsJoined.ql b/c/misra/src/rules/RULE-22-15/ThreadResourceDisposedBeforeThreadsJoined.ql index ec4631ef1..9f06f441d 100644 --- a/c/misra/src/rules/RULE-22-15/ThreadResourceDisposedBeforeThreadsJoined.ql +++ b/c/misra/src/rules/RULE-22-15/ThreadResourceDisposedBeforeThreadsJoined.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew newtype TThreadKind = TSpawned(C11ThreadCreateCall tcc) or diff --git a/c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql b/c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql index 252b4a7d9..f2bb0a519 100644 --- a/c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql +++ b/c/misra/src/rules/RULE-22-17/InvalidOperationOnUnlockedMutex.ql @@ -16,9 +16,8 @@ import cpp import codingstandards.c.misra import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.dominance.BehavioralSet -import semmle.code.cpp.dataflow.new.DataFlow::DataFlow as NewDF /* A call to mtx_unlock() or cnd_wait() or cnd_timedwait(), which require a locked mutex */ class RequiresLockOperation extends FunctionCall { diff --git a/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLocked.ql b/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLocked.ql index 17762b3ee..c1ace4489 100644 --- a/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLocked.ql +++ b/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLocked.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type from diff --git a/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql b/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql index 7e002585b..1df7c0382 100644 --- a/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql +++ b/c/misra/src/rules/RULE-22-18/NonRecursiveMutexRecursivelyLockedAudit.ql @@ -18,7 +18,7 @@ import cpp import codeql.util.Boolean import codingstandards.c.misra import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type predicate isTrackableMutex(CMutexFunctionCall lockCall, Boolean recursive) { diff --git a/c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql b/c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql index 0d5aa5399..ce05c2dc7 100644 --- a/c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql +++ b/c/misra/src/rules/RULE-22-19/ConditionVariableUsedWithMultipleMutexes.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.SubObjects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew bindingset[cond, mutex] int countMutexesForConditionVariable(SubObject cond, SubObject mutex) { diff --git a/c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql b/c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql index 1edf4aa9c..9a9d92424 100644 --- a/c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql +++ b/c/misra/src/rules/RULE-22-20/ThreadStorageNotInitializedBeforeUse.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra import codingstandards.c.Objects -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import codingstandards.cpp.Type import codingstandards.c.initialization.GlobalInitializationAnalysis diff --git a/c/misra/src/rules/RULE-22-20/ThreadStoragePointerInitializedInsideThread.ql b/c/misra/src/rules/RULE-22-20/ThreadStoragePointerInitializedInsideThread.ql index 3c40ea711..4b7c64d91 100644 --- a/c/misra/src/rules/RULE-22-20/ThreadStoragePointerInitializedInsideThread.ql +++ b/c/misra/src/rules/RULE-22-20/ThreadStoragePointerInitializedInsideThread.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.c.misra -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from TSSCreateFunctionCall tssCreate, ThreadedFunction thread where diff --git a/cpp/cert/src/rules/CON56-CPP/DoNotSpeculativelyLockALockedNonRecursiveMutex.ql b/cpp/cert/src/rules/CON56-CPP/DoNotSpeculativelyLockALockedNonRecursiveMutex.ql index 67edf2fc2..a462e60ed 100644 --- a/cpp/cert/src/rules/CON56-CPP/DoNotSpeculativelyLockALockedNonRecursiveMutex.ql +++ b/cpp/cert/src/rules/CON56-CPP/DoNotSpeculativelyLockALockedNonRecursiveMutex.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.cpp.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from LockProtectedControlFlowNode n where diff --git a/cpp/cert/src/rules/CON56-CPP/LockedALockedNonRecursiveMutexAudit.ql b/cpp/cert/src/rules/CON56-CPP/LockedALockedNonRecursiveMutexAudit.ql index 09ec2fa3d..99ad966ef 100644 --- a/cpp/cert/src/rules/CON56-CPP/LockedALockedNonRecursiveMutexAudit.ql +++ b/cpp/cert/src/rules/CON56-CPP/LockedALockedNonRecursiveMutexAudit.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.cpp.cert -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew from LockProtectedControlFlowNode n where diff --git a/cpp/common/src/codingstandards/cpp/rules/guardaccesstobitfields/GuardAccessToBitFields.qll b/cpp/common/src/codingstandards/cpp/rules/guardaccesstobitfields/GuardAccessToBitFields.qll index 5b03a4f8b..8bac7e15e 100644 --- a/cpp/common/src/codingstandards/cpp/rules/guardaccesstobitfields/GuardAccessToBitFields.qll +++ b/cpp/common/src/codingstandards/cpp/rules/guardaccesstobitfields/GuardAccessToBitFields.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew abstract class GuardAccessToBitFieldsSharedQuery extends Query { } diff --git a/cpp/common/src/codingstandards/cpp/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.qll b/cpp/common/src/codingstandards/cpp/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.qll index 5ccbe83c7..4b09e8587 100644 --- a/cpp/common/src/codingstandards/cpp/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.qll +++ b/cpp/common/src/codingstandards/cpp/rules/joinordetachthreadonlyonce/JoinOrDetachThreadOnlyOnce.qll @@ -7,7 +7,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew abstract class JoinOrDetachThreadOnlyOnceSharedQuery extends Query { } diff --git a/cpp/common/src/codingstandards/cpp/rules/preservesafetywhenusingconditionvariables/PreserveSafetyWhenUsingConditionVariables.qll b/cpp/common/src/codingstandards/cpp/rules/preservesafetywhenusingconditionvariables/PreserveSafetyWhenUsingConditionVariables.qll index 94d9d201c..0851fe980 100644 --- a/cpp/common/src/codingstandards/cpp/rules/preservesafetywhenusingconditionvariables/PreserveSafetyWhenUsingConditionVariables.qll +++ b/cpp/common/src/codingstandards/cpp/rules/preservesafetywhenusingconditionvariables/PreserveSafetyWhenUsingConditionVariables.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew abstract class PreserveSafetyWhenUsingConditionVariablesSharedQuery extends Query { } diff --git a/cpp/common/src/codingstandards/cpp/rules/preventdeadlockbylockinginpredefinedorder/PreventDeadlockByLockingInPredefinedOrder.qll b/cpp/common/src/codingstandards/cpp/rules/preventdeadlockbylockinginpredefinedorder/PreventDeadlockByLockingInPredefinedOrder.qll index db755293c..25e169b13 100644 --- a/cpp/common/src/codingstandards/cpp/rules/preventdeadlockbylockinginpredefinedorder/PreventDeadlockByLockingInPredefinedOrder.qll +++ b/cpp/common/src/codingstandards/cpp/rules/preventdeadlockbylockinginpredefinedorder/PreventDeadlockByLockingInPredefinedOrder.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew import semmle.code.cpp.controlflow.Dominance abstract class PreventDeadlockByLockingInPredefinedOrderSharedQuery extends Query { } diff --git a/cpp/common/src/codingstandards/cpp/rules/wrapspuriousfunctioninloop/WrapSpuriousFunctionInLoop.qll b/cpp/common/src/codingstandards/cpp/rules/wrapspuriousfunctioninloop/WrapSpuriousFunctionInLoop.qll index 99bdbeee5..382cda1ae 100644 --- a/cpp/common/src/codingstandards/cpp/rules/wrapspuriousfunctioninloop/WrapSpuriousFunctionInLoop.qll +++ b/cpp/common/src/codingstandards/cpp/rules/wrapspuriousfunctioninloop/WrapSpuriousFunctionInLoop.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import codingstandards.cpp.Concurrency +import codingstandards.cpp.ConcurrencyNew abstract class WrapSpuriousFunctionInLoopSharedQuery extends Query { } From 3ba33c076a69ae7bcc373d65111f07e35565cb11 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 16:01:51 +0200 Subject: [PATCH 05/13] Convert UseOnlyArrayIndexingForPointerArithmetic to use the new dataflow library --- .../UseOnlyArrayIndexingForPointerArithmetic.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll b/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll index 3b0abbad0..f9ffb4fc9 100644 --- a/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll +++ b/cpp/common/src/codingstandards/cpp/rules/useonlyarrayindexingforpointerarithmetic/UseOnlyArrayIndexingForPointerArithmetic.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow abstract class UseOnlyArrayIndexingForPointerArithmeticSharedQuery extends Query { } From e2d44a680b90b0aa424a00239628e8622349af66 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 16:02:57 +0200 Subject: [PATCH 06/13] Convert StringNumberConversionMissingErrorCheck to use the new dataflow library --- .../StringNumberConversionMissingErrorCheck.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll b/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll index fd56f5d89..cb0bc765e 100644 --- a/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll +++ b/cpp/common/src/codingstandards/cpp/rules/stringnumberconversionmissingerrorcheck/StringNumberConversionMissingErrorCheck.qll @@ -7,7 +7,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions import semmle.code.cpp.valuenumbering.GlobalValueNumbering -import semmle.code.cpp.dataflow.TaintTracking +import semmle.code.cpp.dataflow.new.TaintTracking import codingstandards.cpp.standardlibrary.CharStreams abstract class StringNumberConversionMissingErrorCheckSharedQuery extends Query { } From 5ee401ccc85c44732b3a74c317279339779c5d5a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 16:03:30 +0200 Subject: [PATCH 07/13] Convert FgetsErrorManagement to use the new dataflow library --- .../FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql | 2 +- .../rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected | 3 --- cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll | 2 +- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql b/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql index ad3a2c819..d9b96d3c8 100644 --- a/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql +++ b/c/cert/src/rules/FIO37-C/SuccessfulFgetsOrFgetwsMayReturnAnEmptyString.ql @@ -19,7 +19,7 @@ import cpp import codingstandards.c.cert import codingstandards.cpp.FgetsErrorManagement import codingstandards.cpp.Dereferenced -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow /* * CFG nodes that follows a successful call to `fgets` diff --git a/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected b/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected index 7d3cbe355..20c108cfa 100644 --- a/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected +++ b/c/cert/test/rules/FIO40-C/ResetStringsOnFgetsOrFgetwsFailure.expected @@ -1,6 +1,3 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:47,11-19) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:47,31-39) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (ResetStringsOnFgetsOrFgetwsFailure.ql:48,13-21) | test.c:20:10:20:12 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:15:7:15:11 | call to fgets | call to fgets | | test.c:57:10:57:12 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:52:7:52:11 | call to fgets | call to fgets | | test.c:66:18:66:20 | buf | The buffer is not reset before being referenced following a failed $@. | test.c:61:7:61:11 | call to fgets | call to fgets | diff --git a/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll b/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll index 4f99b02e2..7342b92f3 100644 --- a/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll +++ b/cpp/common/src/codingstandards/cpp/FgetsErrorManagement.qll @@ -4,7 +4,7 @@ */ import cpp -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.controlflow.Guards /* From 96b3137d3d741ccd6fcca849682a2a995bb967d7 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 17:05:19 +0200 Subject: [PATCH 08/13] Convert RULE-22-3 to use the new dataflow library --- .../RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql | 2 +- .../FileOpenForReadAndWriteOnDifferentStreams.expected | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql b/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql index 642813bba..581439c62 100644 --- a/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql +++ b/c/misra/src/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.ql @@ -15,7 +15,7 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.standardlibrary.FileAccess -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.valuenumbering.GlobalValueNumbering import semmle.code.cpp.controlflow.SubBasicBlocks diff --git a/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected b/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected index 0365f4980..6111072ba 100644 --- a/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected +++ b/c/misra/test/rules/RULE-22-3/FileOpenForReadAndWriteOnDifferentStreams.expected @@ -1,4 +1,3 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (FileOpenForReadAndWriteOnDifferentStreams.ql:39,9-17) | test.c:6:14:6:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:5:14:5:18 | call to fopen | here | | test.c:17:14:17:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:16:14:16:18 | call to fopen | here | | test.c:33:14:33:18 | call to fopen | The same file was already opened $@. Files should not be read and written at the same time using different streams. | test.c:32:14:32:18 | call to fopen | here | From 0170b58005819901894f22de68d71e60638a20dd Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 17:07:11 +0200 Subject: [PATCH 09/13] Convert RULE-22-4 to use the new dataflow library --- .../src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql | 2 +- .../RULE-22-4/AttemptToWriteToAReadOnlyStream.expected | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql index 2439d4ca4..2468caa61 100644 --- a/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql +++ b/c/misra/src/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.ql @@ -14,7 +14,7 @@ import cpp import codingstandards.c.misra import codingstandards.cpp.standardlibrary.FileAccess -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow module FileDFConfig implements DataFlow::ConfigSig { predicate isSource(DataFlow::Node source) { diff --git a/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected b/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected index dbf08e3d3..0bfce133c 100644 --- a/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected +++ b/c/misra/test/rules/RULE-22-4/AttemptToWriteToAReadOnlyStream.expected @@ -1,8 +1,2 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:19,32-40) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:20,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:25,20-28) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:31,21-29) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:33,6-14) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (AttemptToWriteToAReadOnlyStream.ql:36,28-36) | test.c:10:3:10:9 | call to fprintf | Attempt to write to a $@ opened as read-only. | test.c:9:14:9:18 | call to fopen | stream | | test.c:15:3:15:9 | call to fprintf | Attempt to write to a $@ opened as read-only. | test.c:18:14:18:18 | call to fopen | stream | From 80809521790c44c5f6097150e1639ec2618d190a Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 17:38:05 +0200 Subject: [PATCH 10/13] Convert A7-5-1 to use the new dataflow library --- cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql | 2 +- .../test/rules/A7-5-1/InvalidFunctionReturnType.expected | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql b/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql index c36bda6cd..6b94c68cf 100644 --- a/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql +++ b/cpp/autosar/src/rules/A7-5-1/InvalidFunctionReturnType.ql @@ -16,7 +16,7 @@ import cpp import codingstandards.cpp.autosar -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow from Parameter p, ReturnStmt ret where diff --git a/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected b/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected index 3287ba88d..b6d949080 100644 --- a/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected +++ b/cpp/autosar/test/rules/A7-5-1/InvalidFunctionReturnType.expected @@ -1,5 +1,2 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,3-11) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,23-31) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (InvalidFunctionReturnType.ql:27,51-59) | test.cpp:5:3:5:11 | return ... | Function test_refconst_return returns a reference or a pointer to $@ that is passed by reference to const. | test.cpp:4:44:4:44 | x | parameter | | test.cpp:8:3:8:14 | return ... | Function test_ptrconst_return returns a reference or a pointer to $@ that is passed by reference to const. | test.cpp:7:44:7:44 | x | parameter | From c962dbef17937a7ada9d70103469c40ed8f86190 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 17:54:03 +0200 Subject: [PATCH 11/13] Convert DoNotSubtractPointersAddressingDifferentArrays to use new dataflow library --- ...PointersAddressingDifferentArrays.expected | 28 ++++++++++++------- .../PointerSubtractionOnDifferentArrays.ql | 4 ++- ...tractPointersAddressingDifferentArrays.qll | 4 ++- ...PointersAddressingDifferentArrays.expected | 28 ++++++++++++------- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected b/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected index 75866b850..f9fe72c2a 100644 --- a/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected +++ b/c/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected @@ -4,19 +4,27 @@ problems | test.c:13:10:13:11 | p4 | test.c:5:14:5:15 | l2 | test.c:13:10:13:11 | p4 | Subtraction between left operand pointing to array $@ and other operand pointing to array $@. | test.c:3:7:3:8 | l2 | l2 | test.c:2:7:2:8 | l1 | l1 | | test.c:13:15:13:16 | l1 | test.c:13:15:13:16 | l1 | test.c:13:15:13:16 | l1 | Subtraction between right operand pointing to array $@ and other operand pointing to array $@. | test.c:2:7:2:8 | l1 | l1 | test.c:3:7:3:8 | l2 | l2 | edges -| test.c:4:14:4:15 | l1 | test.c:4:14:4:18 | access to array | provenance | Config | -| test.c:4:14:4:18 | access to array | test.c:10:10:10:11 | p1 | provenance | | -| test.c:4:14:4:18 | access to array | test.c:12:10:12:11 | p1 | provenance | | -| test.c:5:14:5:15 | l2 | test.c:5:14:5:19 | access to array | provenance | Config | -| test.c:5:14:5:19 | access to array | test.c:11:10:11:11 | p2 | provenance | | -| test.c:5:14:5:19 | access to array | test.c:12:15:12:16 | p2 | provenance | | -| test.c:5:14:5:19 | access to array | test.c:13:10:13:11 | p4 | provenance | | -| test.c:5:14:5:19 | access to array | test.c:14:10:14:11 | p4 | provenance | | +| test.c:4:13:4:18 | & ... | test.c:4:13:4:18 | & ... | provenance | | +| test.c:4:13:4:18 | & ... | test.c:10:10:10:11 | p1 | provenance | | +| test.c:4:13:4:18 | & ... | test.c:12:10:12:11 | p1 | provenance | | +| test.c:4:14:4:15 | l1 | test.c:4:13:4:18 | & ... | provenance | Config | +| test.c:5:13:5:19 | & ... | test.c:5:13:5:19 | & ... | provenance | | +| test.c:5:13:5:19 | & ... | test.c:6:13:6:14 | p2 | provenance | | +| test.c:5:13:5:19 | & ... | test.c:11:10:11:11 | p2 | provenance | | +| test.c:5:13:5:19 | & ... | test.c:12:15:12:16 | p2 | provenance | | +| test.c:5:14:5:15 | l2 | test.c:5:13:5:19 | & ... | provenance | Config | +| test.c:6:13:6:14 | p2 | test.c:7:13:7:14 | p3 | provenance | | +| test.c:7:13:7:14 | p3 | test.c:13:10:13:11 | p4 | provenance | | +| test.c:7:13:7:14 | p3 | test.c:14:10:14:11 | p4 | provenance | | nodes +| test.c:4:13:4:18 | & ... | semmle.label | & ... | +| test.c:4:13:4:18 | & ... | semmle.label | & ... | | test.c:4:14:4:15 | l1 | semmle.label | l1 | -| test.c:4:14:4:18 | access to array | semmle.label | access to array | +| test.c:5:13:5:19 | & ... | semmle.label | & ... | +| test.c:5:13:5:19 | & ... | semmle.label | & ... | | test.c:5:14:5:15 | l2 | semmle.label | l2 | -| test.c:5:14:5:19 | access to array | semmle.label | access to array | +| test.c:6:13:6:14 | p2 | semmle.label | p2 | +| test.c:7:13:7:14 | p3 | semmle.label | p3 | | test.c:10:10:10:11 | p1 | semmle.label | p1 | | test.c:10:15:10:16 | l1 | semmle.label | l1 | | test.c:11:10:11:11 | p2 | semmle.label | p2 | diff --git a/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql b/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql index d6d4f6130..29feaa22d 100644 --- a/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql +++ b/cpp/autosar/src/rules/M5-0-17/PointerSubtractionOnDifferentArrays.ql @@ -15,7 +15,7 @@ import cpp import codingstandards.cpp.autosar -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import ArrayToPointerDiffOperandFlow::PathGraph module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig { @@ -34,6 +34,8 @@ module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig { // Add a flow step from the base to the array expression to track pointers to elements of the array. exists(ArrayExpr e | e.getArrayBase() = pred.asExpr() and e = succ.asExpr()) } + + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } module ArrayToPointerDiffOperandFlow = DataFlow::Global; diff --git a/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll b/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll index adb978581..16f963829 100644 --- a/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll +++ b/cpp/common/src/codingstandards/cpp/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.qll @@ -6,7 +6,7 @@ import cpp import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import ArrayToPointerDiffOperandFlow::PathGraph module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig { @@ -25,6 +25,8 @@ module ArrayToPointerDiffOperandConfig implements DataFlow::ConfigSig { // Add a flow step from the base to the array expression to track pointers to elements of the array. exists(ArrayExpr e | e.getArrayBase() = pred.asExpr() and e = succ.asExpr()) } + + predicate isBarrierIn(DataFlow::Node node) { isSource(node) } } module ArrayToPointerDiffOperandFlow = DataFlow::Global; diff --git a/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected b/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected index 2d293e692..89f6cec56 100644 --- a/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected +++ b/cpp/common/test/rules/donotsubtractpointersaddressingdifferentarrays/DoNotSubtractPointersAddressingDifferentArrays.expected @@ -4,19 +4,27 @@ problems | test.cpp:13:10:13:11 | p4 | test.cpp:5:14:5:15 | l2 | test.cpp:13:10:13:11 | p4 | Subtraction between left operand pointing to array $@ and other operand pointing to array $@. | test.cpp:3:7:3:8 | l2 | l2 | test.cpp:2:7:2:8 | l1 | l1 | | test.cpp:13:15:13:16 | l1 | test.cpp:13:15:13:16 | l1 | test.cpp:13:15:13:16 | l1 | Subtraction between right operand pointing to array $@ and other operand pointing to array $@. | test.cpp:2:7:2:8 | l1 | l1 | test.cpp:3:7:3:8 | l2 | l2 | edges -| test.cpp:4:14:4:15 | l1 | test.cpp:4:14:4:18 | access to array | provenance | Config | -| test.cpp:4:14:4:18 | access to array | test.cpp:10:10:10:11 | p1 | provenance | | -| test.cpp:4:14:4:18 | access to array | test.cpp:12:10:12:11 | p1 | provenance | | -| test.cpp:5:14:5:15 | l2 | test.cpp:5:14:5:19 | access to array | provenance | Config | -| test.cpp:5:14:5:19 | access to array | test.cpp:11:10:11:11 | p2 | provenance | | -| test.cpp:5:14:5:19 | access to array | test.cpp:12:15:12:16 | p2 | provenance | | -| test.cpp:5:14:5:19 | access to array | test.cpp:13:10:13:11 | p4 | provenance | | -| test.cpp:5:14:5:19 | access to array | test.cpp:14:10:14:11 | p4 | provenance | | +| test.cpp:4:13:4:18 | & ... | test.cpp:4:13:4:18 | & ... | provenance | | +| test.cpp:4:13:4:18 | & ... | test.cpp:10:10:10:11 | p1 | provenance | | +| test.cpp:4:13:4:18 | & ... | test.cpp:12:10:12:11 | p1 | provenance | | +| test.cpp:4:14:4:15 | l1 | test.cpp:4:13:4:18 | & ... | provenance | Config | +| test.cpp:5:13:5:19 | & ... | test.cpp:5:13:5:19 | & ... | provenance | | +| test.cpp:5:13:5:19 | & ... | test.cpp:6:13:6:14 | p2 | provenance | | +| test.cpp:5:13:5:19 | & ... | test.cpp:11:10:11:11 | p2 | provenance | | +| test.cpp:5:13:5:19 | & ... | test.cpp:12:15:12:16 | p2 | provenance | | +| test.cpp:5:14:5:15 | l2 | test.cpp:5:13:5:19 | & ... | provenance | Config | +| test.cpp:6:13:6:14 | p2 | test.cpp:7:13:7:14 | p3 | provenance | | +| test.cpp:7:13:7:14 | p3 | test.cpp:13:10:13:11 | p4 | provenance | | +| test.cpp:7:13:7:14 | p3 | test.cpp:14:10:14:11 | p4 | provenance | | nodes +| test.cpp:4:13:4:18 | & ... | semmle.label | & ... | +| test.cpp:4:13:4:18 | & ... | semmle.label | & ... | | test.cpp:4:14:4:15 | l1 | semmle.label | l1 | -| test.cpp:4:14:4:18 | access to array | semmle.label | access to array | +| test.cpp:5:13:5:19 | & ... | semmle.label | & ... | +| test.cpp:5:13:5:19 | & ... | semmle.label | & ... | | test.cpp:5:14:5:15 | l2 | semmle.label | l2 | -| test.cpp:5:14:5:19 | access to array | semmle.label | access to array | +| test.cpp:6:13:6:14 | p2 | semmle.label | p2 | +| test.cpp:7:13:7:14 | p3 | semmle.label | p3 | | test.cpp:10:10:10:11 | p1 | semmle.label | p1 | | test.cpp:10:15:10:16 | l1 | semmle.label | l1 | | test.cpp:11:10:11:11 | p2 | semmle.label | p2 | From 8c05d42195930b82a22eed136fcbbc6e09dd15cb Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 17:55:39 +0200 Subject: [PATCH 12/13] Remove unused dataflow import from IOFstreamMissingPositioning --- .../iofstreammissingpositioning/IOFstreamMissingPositioning.qll | 1 - 1 file changed, 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll b/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll index b26421c72..b11050e49 100644 --- a/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll +++ b/cpp/common/src/codingstandards/cpp/rules/iofstreammissingpositioning/IOFstreamMissingPositioning.qll @@ -5,7 +5,6 @@ */ import cpp -import semmle.code.cpp.dataflow.TaintTracking import codingstandards.cpp.Exclusions import codingstandards.cpp.standardlibrary.FileStreams import codingstandards.cpp.standardlibrary.FileAccess From b18c7b4625d35af8e4411b3d5a3531eee81b4f90 Mon Sep 17 00:00:00 2001 From: Jeroen Ketema Date: Tue, 8 Jul 2025 18:01:38 +0200 Subject: [PATCH 13/13] Convert DanglingCaptureWhenReturningLambdaObject to use new dataflow library --- .../DanglingCaptureWhenReturningLambdaObject.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll index 4ab01520f..412a571fe 100644 --- a/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll +++ b/cpp/common/src/codingstandards/cpp/rules/danglingcapturewhenreturninglambdaobject/DanglingCaptureWhenReturningLambdaObject.qll @@ -5,7 +5,7 @@ */ import cpp -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import codingstandards.cpp.Customizations import codingstandards.cpp.Exclusions