Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
478a024
Add and fix stubs
jeongsoolee09 Apr 7, 2026
e91aca0
Add stubs
jeongsoolee09 Apr 7, 2026
ffb3e06
Fix wthe stubs
jeongsoolee09 Apr 7, 2026
997cb7a
Add package files
jeongsoolee09 Apr 7, 2026
dce0e80
Finalize draft of 21-6-1 and factor out duplicated code
jeongsoolee09 Apr 9, 2026
cd9a841
Fix formatting
jeongsoolee09 Apr 9, 2026
568daa7
Merge branch 'main' into jeongsoolee09/MISRA-C++-2023-Banned7
jeongsoolee09 Apr 10, 2026
6bbd610
Rename to `PlacementNewOperator`, move it, and add some docstrings
jeongsoolee09 Apr 17, 2026
b4187f0
Add more docstrings
jeongsoolee09 Apr 17, 2026
5a9a245
Add more cases where the `std::allocator` is explicitly passed
jeongsoolee09 Apr 18, 2026
fa83b3d
Add more template parameters to the stubs to match the spec
jeongsoolee09 Apr 20, 2026
3089c6f
Add two small models
jeongsoolee09 Apr 20, 2026
81d9829
Finalize draft and update expected results of the query
jeongsoolee09 Apr 20, 2026
0217eac
Add missing destructors to stubs
jeongsoolee09 Apr 24, 2026
3a7739f
Add explicit destructor calls to the test suite
jeongsoolee09 Apr 24, 2026
8e15608
Add explanatory comment block
jeongsoolee09 Apr 24, 2026
234ca96
Checkpoint
jeongsoolee09 Apr 24, 2026
508020e
Add explicit destructor calls and exclude RAII calls
jeongsoolee09 Apr 24, 2026
2496490
Update expected results
jeongsoolee09 Apr 24, 2026
411ae63
Merge branch 'main' into jeongsoolee09/MISRA-C++-2023-Banned7
jeongsoolee09 Apr 24, 2026
9cf4fbb
Merge branch 'main' into jeongsoolee09/MISRA-C++-2023-Banned7
jeongsoolee09 Apr 24, 2026
f89068c
Fix formatting
jeongsoolee09 Apr 24, 2026
0e85f55
Roll back destructor detection
jeongsoolee09 Apr 24, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions cpp/common/src/codingstandards/cpp/DynamicMemory.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/** Provides classes for modeling dynamic memory allocation and deallocation functions. */

import cpp

/**
* A function that has namespace `std` and has name `allocate` or `deallocate`, including but
* not limited to:
* - `std::allocator<T>::allocate(std::size_t)`
* - `std::allocator<T>::deallocate(T*, std::size_t)`
* - `std::pmr::memory_resource::allocate(std::size_t, std::size_t)`
* - `std::pmr::memory_resource::deallocate(void*, std::size_t, std::size_t)`
*/
class AllocateOrDeallocateStdlibMemberFunction extends MemberFunction {
AllocateOrDeallocateStdlibMemberFunction() {
this.getName() in ["allocate", "deallocate"] and
this.getNamespace().getParentNamespace*() instanceof StdNamespace
}
}

class StdAllocator extends Class {
StdAllocator() { this.hasGlobalOrStdName("allocator") }
}

class StdPmrMemoryResource extends Class {
StdPmrMemoryResource() { this.hasQualifiedName("std::pmr", "memory_resource") }
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
/**
* Provides classes to help reasoning about `operator new`, `operator new[]`,
* `operator delete`, and `operator delete[]`.
*
* These are described in section [support.dynamic] of the C++ standard.
*/

import cpp
import codingstandards.cpp.Handlers

Expand All @@ -21,6 +28,13 @@ abstract class OperatorNewOrDelete extends Operator {
}
}

/**
* An `operator new` and `operator new[]` function described in [new.delete.single]
* and [new.delete.array], respectively.
*
* Note that these do not include [new.delete.placement]. These are captured in
* `PlacementOperatorNew`.
*/
class ReplaceableOperatorNew extends OperatorNewOrDelete {
ReplaceableOperatorNew() {
this.getName().regexpMatch("operator new(\\[\\])?") and
Expand All @@ -34,6 +48,12 @@ class ReplaceableOperatorNew extends OperatorNewOrDelete {
}
}

/**
* `operator new`, `operator new[]`, `operator delete`, or `operator delete[]` functions
* that are very likely provided by the user.
*
* Note that this captures _any_ function that has one of the above four names.
*/
class CustomOperatorNewOrDelete extends OperatorNewOrDelete {
CustomOperatorNewOrDelete() {
this.hasDefinition() and
Expand All @@ -60,8 +80,18 @@ class CustomOperatorNewOrDelete extends OperatorNewOrDelete {
}
}

/**
* The replaceable `operator new` or `operator new[]` functions that have custom
* definitions provided by the user.
*
* Also see `CustomReplaceableOperatorDelete`.
*/
class CustomReplaceableOperatorNew extends CustomOperatorNewOrDelete, ReplaceableOperatorNew { }

/**
* An `operator delete` or `operator delete[]` deallocation function described in
* [new.delete.single] and [new.delete.array], respectively.
*/
class ReplaceableOperatorDelete extends OperatorNewOrDelete {
ReplaceableOperatorDelete() {
this.getName().regexpMatch("operator delete(\\[\\])?") and
Expand All @@ -85,6 +115,12 @@ class ReplaceableOperatorDelete extends OperatorNewOrDelete {
}
}

/**
* The replaceable `operator new` or `operator new[]` functions that have custom
* definitions provided by the user.
*
* Also see `CustomReplaceableOperatorNew`.
*/
class CustomReplaceableOperatorDelete extends CustomOperatorNewOrDelete, ReplaceableOperatorDelete {
CustomReplaceableOperatorDelete getPartner() {
if this.getAParameter().getType() instanceof Size_t
Expand All @@ -95,3 +131,18 @@ class CustomReplaceableOperatorDelete extends CustomOperatorNewOrDelete, Replace
else result.getPartner() = this
}
}

/**
* An `operator new` or `operator new[]` allocation function called by a placement-new expression,
* as described in [new.delete.placement].
*
* The operator functions have a `std::size_t` as their first parameter and a
* `void*` parameter somewhere in the rest of the parameter list.
*/
class PlacementOperatorNew extends AllocationFunction {
PlacementOperatorNew() {
this.getName() in ["operator new", "operator new[]"] and
this.getParameter(0).getType().resolveTypedefs*() instanceof Size_t and
this.getAParameter().getUnderlyingType() instanceof VoidPointerType
}
}
26 changes: 26 additions & 0 deletions cpp/common/src/codingstandards/cpp/exclusions/cpp/Banned7.qll
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//** THIS FILE IS AUTOGENERATED, DO NOT MODIFY DIRECTLY. **/
import cpp
import RuleMetadata
import codingstandards.cpp.exclusions.RuleMetadata

newtype Banned7Query = TDynamicMemoryShouldNotBeUsedQuery()

predicate isBanned7QueryMetadata(Query query, string queryId, string ruleId, string category) {
query =
// `Query` instance for the `dynamicMemoryShouldNotBeUsed` query
Banned7Package::dynamicMemoryShouldNotBeUsedQuery() and
queryId =
// `@id` for the `dynamicMemoryShouldNotBeUsed` query
"cpp/misra/dynamic-memory-should-not-be-used" and
ruleId = "RULE-21-6-1" and
category = "advisory"
}

module Banned7Package {
Query dynamicMemoryShouldNotBeUsedQuery() {
//autogenerate `Query` type
result =
// `Query` type for `dynamicMemoryShouldNotBeUsed` query
TQueryCPP(TBanned7PackageQuery(TDynamicMemoryShouldNotBeUsedQuery()))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Banned3
import Banned4
import Banned5
import Banned6
import Banned7
import Banned8
import BannedAPIs
import BannedFunctions
Expand Down Expand Up @@ -115,6 +116,7 @@ newtype TCPPQuery =
TBanned4PackageQuery(Banned4Query q) or
TBanned5PackageQuery(Banned5Query q) or
TBanned6PackageQuery(Banned6Query q) or
TBanned7PackageQuery(Banned7Query q) or
TBanned8PackageQuery(Banned8Query q) or
TBannedAPIsPackageQuery(BannedAPIsQuery q) or
TBannedFunctionsPackageQuery(BannedFunctionsQuery q) or
Expand Down Expand Up @@ -221,6 +223,7 @@ predicate isQueryMetadata(Query query, string queryId, string ruleId, string cat
isBanned4QueryMetadata(query, queryId, ruleId, category) or
isBanned5QueryMetadata(query, queryId, ruleId, category) or
isBanned6QueryMetadata(query, queryId, ruleId, category) or
isBanned7QueryMetadata(query, queryId, ruleId, category) or
isBanned8QueryMetadata(query, queryId, ruleId, category) or
isBannedAPIsQueryMetadata(query, queryId, ruleId, category) or
isBannedFunctionsQueryMetadata(query, queryId, ruleId, category) or
Expand Down
1 change: 1 addition & 0 deletions cpp/common/test/includes/standard-library/any
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <any.h>
16 changes: 16 additions & 0 deletions cpp/common/test/includes/standard-library/any.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef _GHLIBCPP_ANY
#define _GHLIBCPP_ANY
namespace std {

class any {
public:
any();
any(const any &);
any(any &&);
~any();
template <typename T> any(T &&);
};

} // namespace std

#endif // _GHLIBCPP_ANY
1 change: 1 addition & 0 deletions cpp/common/test/includes/standard-library/bitset
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <bitset.h>
18 changes: 18 additions & 0 deletions cpp/common/test/includes/standard-library/bitset.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// stubs/bitset

#ifndef _GHLIBCPP_BITSET
#define _GHLIBCPP_BITSET

#include <cstddef>

namespace std {

template <std::size_t N> class bitset {
public:
bitset();
bitset(unsigned long long);
};

} // namespace std

#endif // _GHLIBCPP_BITSET
13 changes: 8 additions & 5 deletions cpp/common/test/includes/standard-library/deque.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#ifndef _GHLIBCPP_DEQUE
#define _GHLIBCPP_DEQUE
#include <iterator>
#include <string>
#include "memory.h"
#include <initializer_list>
#include <empty.h>
#include <initializer_list>
#include <iterator>
#include <string>

namespace std {
template <class T, class Allocator = std::allocator<T>> class deque {
Expand All @@ -14,8 +14,11 @@ template <class T, class Allocator = std::allocator<T>> class deque {
typedef value_type &reference;
typedef const value_type &const_reference;

deque() = default;
deque();
deque(const deque &);
deque(deque &&);
deque(std::initializer_list<T>, const Allocator & = Allocator());
~deque();

typedef __iterator<T> iterator;
typedef __iterator<T> const_iterator;
Expand All @@ -40,4 +43,4 @@ template <class T, class Allocator = std::allocator<T>> class deque {
};
} // namespace std

#endif // _GHLIBCPP_DEQUE
#endif // _GHLIBCPP_DEQUE
1 change: 1 addition & 0 deletions cpp/common/test/includes/standard-library/filesystem
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <filesystem.h>
20 changes: 20 additions & 0 deletions cpp/common/test/includes/standard-library/filesystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _GHLIBCPP_FILESYSTEM
#define _GHLIBCPP_FILESYSTEM

namespace std {
namespace filesystem {

class path {
public:
path();
path(const path&);
path(path&&);
path(const char*);

path operator/(const path&) const;
};

} // namespace filesystem
} // namespace std

#endif // _GHLIBCPP_FILESYSTEM
1 change: 1 addition & 0 deletions cpp/common/test/includes/standard-library/forward_list
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <forward_list.h>
20 changes: 20 additions & 0 deletions cpp/common/test/includes/standard-library/forward_list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#ifndef _GHLIBCPP_FORWARD_LIST
#define _GHLIBCPP_FORWARD_LIST

#include <initializer_list>
#include <memory>

namespace std {

template <typename T, typename Alloc = std::allocator<T>> class forward_list {
public:
forward_list();
forward_list(const forward_list &);
forward_list(forward_list &&);
forward_list(std::initializer_list<T>);
~forward_list();
};

} // namespace std

#endif // _GHLIBCPP_FORWARD_LIST
27 changes: 26 additions & 1 deletion cpp/common/test/includes/standard-library/fstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,37 @@ class basic_fstream : public std::basic_iostream<CharT, Traits> {
// constructors
basic_fstream();
explicit basic_fstream(const char *s);
basic_fstream(const basic_fstream &);
basic_fstream(basic_fstream &&);
virtual ~basic_fstream();
// members
bool is_open() const;
void open(const string &s);
void close();
};

template <typename CharT, class Traits> class basic_ifstream {
public:
basic_ifstream();
basic_ifstream(const basic_ifstream &);
basic_ifstream(basic_ifstream &&);
basic_ifstream(const char *);
};

template <typename CharT, class Traits> class basic_ofstream {
public:
basic_ofstream();
basic_ofstream(const basic_ofstream &);
basic_ofstream(basic_ofstream &&);
basic_ofstream(const char *);
};

using fstream = basic_fstream<char>;
using wfstream = basic_fstream<wchar_t>;
using ifstream = basic_ifstream<char>;
using wifstream = basic_ifstream<wchar_t>;
using ofstream = basic_ofstream<char>;
using wofstream = basic_ofstream<wchar_t>;
} // namespace std

#endif // _GHLIBCPP_FSTREAM
#endif // _GHLIBCPP_FSTREAM
6 changes: 5 additions & 1 deletion cpp/common/test/includes/standard-library/functional.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ template <class F, class T> binder1st<F> bind1st(const F &f, const T &x);
template <class F, class T> binder2nd<F> bind2nd(const F &f, const T &x);

template <class T> class reference_wrapper {
public:
reference_wrapper(T &ref) : ref(addressof(ref)) {}
reference_wrapper(const reference_wrapper&);
reference_wrapper(T &&ref) = delete;

operator T &() const { return *ref; }
Expand Down Expand Up @@ -117,7 +119,9 @@ template <class R, class... Args> class function<R(Args...)> {
public:
using result_type = R; // deprecated in C++17
function();
template <class F> function(F&& f);
template <class F> function(F &&f);
~function();

template <class F> function &operator=(F &&);
};

Expand Down
1 change: 1 addition & 0 deletions cpp/common/test/includes/standard-library/future
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include <future.h>
Loading
Loading