mirror of
https://github.com/github/codeql.git
synced 2026-04-27 17:55:19 +02:00
Merge branch 'main' into more-alias-and-side-effect-models
This commit is contained in:
2296
cpp/downgrades/25e365d1e8147df0f759b604f96eb4bffea48271/old.dbscheme
Normal file
2296
cpp/downgrades/25e365d1e8147df0f759b604f96eb4bffea48271/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,4 @@
|
||||
description: Revert support for using-enum declarations.
|
||||
compatibility: partial
|
||||
usings.rel: run usings.qlo
|
||||
using_container.rel: run using_container.qlo
|
||||
@@ -0,0 +1,14 @@
|
||||
class UsingEntry extends @using {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Element extends @element {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from UsingEntry u, Element parent, int kind
|
||||
where
|
||||
usings(u, _, _, kind) and
|
||||
using_container(parent, u) and
|
||||
kind != 3
|
||||
select parent, u
|
||||
@@ -0,0 +1,17 @@
|
||||
class UsingEntry extends @using {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Element extends @element {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_default {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from UsingEntry u, Element target, Location loc, int kind
|
||||
where
|
||||
usings(u, target, loc, kind) and
|
||||
kind != 3
|
||||
select u, target, loc
|
||||
2300
cpp/downgrades/9629fc87dab7dbed0771bf5ce22bce4d7f943b52/old.dbscheme
Normal file
2300
cpp/downgrades/9629fc87dab7dbed0771bf5ce22bce4d7f943b52/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Support destroying deletes
|
||||
compatibility: full
|
||||
@@ -1,3 +1,11 @@
|
||||
## 1.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Models-as-data alert provenance information has been extended to the C/C++ language. Any qltests that include the edges relation in their output (for example, `.qlref`s that reference path-problem queries) will need to be have their expected output updated accordingly.
|
||||
* Added subclasses of `BuiltInOperations` for `__builtin_has_attribute`, `__builtin_is_corresponding_member`, `__builtin_is_pointer_interconvertible_with_class`, `__is_assignable_no_precondition_check`, `__is_bounded_array`, `__is_convertible`, `__is_corresponding_member`, `__is_nothrow_convertible`, `__is_pointer_interconvertible_with_class`, `__is_referenceable`, `__is_same_as`, `__is_trivially_copy_assignable`, `__is_unbounded_array`, `__is_valid_winrt_type`, `_is_win_class`, `__is_win_interface`, `__reference_binds_to_temporary`, `__reference_constructs_from_temporary`, and `__reference_converts_from_temporary`.
|
||||
* The class `NewArrayExpr` adds a predicate `getArraySize()` to allow a more convenient way to access the static size of the array when the extent is missing.
|
||||
|
||||
## 1.2.0
|
||||
|
||||
### New Features
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The class `NewArrayExpr` adds a predicate `getArraySize()` to allow a more convenient way to access the static size of the array when the extent is missing.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Models-as-data alert provenance information has been extended to the C/C++ language. Any qltests that include the edges relation in their output (for example, `.qlref`s that reference path-problem queries) will need to be have their expected output updated accordingly.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* A `isDestroyingDeleteDeallocation` predicate was added to the `NewOrNewArrayExpr` and `DeleteOrDeleteArrayExpr` classes to indicate whether the deallocation function is a destroying delete.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* A `UsingEnumDeclarationEntry` class has been added for C++ `using enum` declarations. As part of this, synthesized `UsingDeclarationEntry`s are no longer emitted for individual enumerators of the referenced enumeration.
|
||||
@@ -1,4 +1,7 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
## 1.3.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Models-as-data alert provenance information has been extended to the C/C++ language. Any qltests that include the edges relation in their output (for example, `.qlref`s that reference path-problem queries) will need to be have their expected output updated accordingly.
|
||||
* Added subclasses of `BuiltInOperations` for `__builtin_has_attribute`, `__builtin_is_corresponding_member`, `__builtin_is_pointer_interconvertible_with_class`, `__is_assignable_no_precondition_check`, `__is_bounded_array`, `__is_convertible`, `__is_corresponding_member`, `__is_nothrow_convertible`, `__is_pointer_interconvertible_with_class`, `__is_referenceable`, `__is_same_as`, `__is_trivially_copy_assignable`, `__is_unbounded_array`, `__is_valid_winrt_type`, `_is_win_class`, `__is_win_interface`, `__reference_binds_to_temporary`, `__reference_constructs_from_temporary`, and `__reference_converts_from_temporary`.
|
||||
* The class `NewArrayExpr` adds a predicate `getArraySize()` to allow a more convenient way to access the static size of the array when the extent is missing.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.2.0
|
||||
lastReleaseVersion: 1.3.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-all
|
||||
version: 1.2.1-dev
|
||||
version: 1.3.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -156,7 +156,7 @@ class NamespaceDeclarationEntry extends Locatable, @namespace_decl {
|
||||
* A C++ `using` directive or `using` declaration.
|
||||
*/
|
||||
class UsingEntry extends Locatable, @using {
|
||||
override Location getLocation() { usings(underlyingElement(this), _, result) }
|
||||
override Location getLocation() { usings(underlyingElement(this), _, result, _) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,15 +166,13 @@ class UsingEntry extends Locatable, @using {
|
||||
* ```
|
||||
*/
|
||||
class UsingDeclarationEntry extends UsingEntry {
|
||||
UsingDeclarationEntry() {
|
||||
not exists(Namespace n | usings(underlyingElement(this), unresolveElement(n), _))
|
||||
}
|
||||
UsingDeclarationEntry() { usings(underlyingElement(this), _, _, 1) }
|
||||
|
||||
/**
|
||||
* Gets the declaration that is referenced by this using declaration. For
|
||||
* example, `std::string` in `using std::string`.
|
||||
*/
|
||||
Declaration getDeclaration() { usings(underlyingElement(this), unresolveElement(result), _) }
|
||||
Declaration getDeclaration() { usings(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
override string toString() { result = "using " + this.getDeclaration().getDescription() }
|
||||
}
|
||||
@@ -186,19 +184,36 @@ class UsingDeclarationEntry extends UsingEntry {
|
||||
* ```
|
||||
*/
|
||||
class UsingDirectiveEntry extends UsingEntry {
|
||||
UsingDirectiveEntry() {
|
||||
exists(Namespace n | usings(underlyingElement(this), unresolveElement(n), _))
|
||||
}
|
||||
UsingDirectiveEntry() { usings(underlyingElement(this), _, _, 2) }
|
||||
|
||||
/**
|
||||
* Gets the namespace that is referenced by this using directive. For
|
||||
* example, `std` in `using namespace std`.
|
||||
*/
|
||||
Namespace getNamespace() { usings(underlyingElement(this), unresolveElement(result), _) }
|
||||
Namespace getNamespace() { usings(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
override string toString() { result = "using namespace " + this.getNamespace().getFriendlyName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A C++ `using enum` declaration. For example:
|
||||
* ```
|
||||
* enum class Foo { a, b };
|
||||
* using enum Foo;
|
||||
* ```
|
||||
*/
|
||||
class UsingEnumDeclarationEntry extends UsingEntry {
|
||||
UsingEnumDeclarationEntry() { usings(underlyingElement(this), _, _, 3) }
|
||||
|
||||
/**
|
||||
* Gets the enumeration that is referenced by this using directive. For
|
||||
* example, `Foo` in `using enum Foo`.
|
||||
*/
|
||||
Enum getEnum() { usings(underlyingElement(this), unresolveElement(result), _, _) }
|
||||
|
||||
override string toString() { result = "using enum " + this.getEnum().getQualifiedName() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `g` is an instance of `GlobalNamespace`. This predicate
|
||||
* is used suppress a warning in `GlobalNamespace.getADeclaration()`
|
||||
|
||||
@@ -855,6 +855,16 @@ class NewOrNewArrayExpr extends Expr, @any_new_expr {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function is a destroying delete.
|
||||
*/
|
||||
predicate isDestroyingDeleteDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(4) != 0 // Bit two is the "destroying delete" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type that is being allocated.
|
||||
*
|
||||
@@ -1025,6 +1035,16 @@ class DeleteOrDeleteArrayExpr extends Expr, TDeleteOrDeleteArrayExpr {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the deallocation function is a destroying delete.
|
||||
*/
|
||||
predicate isDestroyingDeleteDeallocation() {
|
||||
exists(int form |
|
||||
expr_deallocator(underlyingElement(this), _, form) and
|
||||
form.bitAnd(4) != 0 // Bit two is the "destroying delete" bit
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the object or array being deleted.
|
||||
*/
|
||||
|
||||
@@ -485,10 +485,17 @@ namespace_decls(
|
||||
int bodylocation: @location_default ref
|
||||
);
|
||||
|
||||
case @using.kind of
|
||||
1 = @using_declaration
|
||||
| 2 = @using_directive
|
||||
| 3 = @using_enum_declaration
|
||||
;
|
||||
|
||||
usings(
|
||||
unique int id: @using,
|
||||
int element_id: @element ref,
|
||||
int location: @location_default ref
|
||||
int location: @location_default ref,
|
||||
int kind: int ref
|
||||
);
|
||||
|
||||
/** The element which contains the `using` declaration. */
|
||||
@@ -1358,6 +1365,8 @@ funbind(
|
||||
@assign_expr = @assignexpr | @assign_op_expr | @blockassignexpr
|
||||
|
||||
/*
|
||||
Binary encoding of the allocator form.
|
||||
|
||||
case @allocator.form of
|
||||
0 = plain
|
||||
| 1 = alignment
|
||||
@@ -1376,11 +1385,13 @@ expr_allocator(
|
||||
);
|
||||
|
||||
/*
|
||||
Binary encoding of the deallocator form.
|
||||
|
||||
case @deallocator.form of
|
||||
0 = plain
|
||||
| 1 = size
|
||||
| 2 = alignment
|
||||
| 3 = size_and_alignment
|
||||
| 4 = destroying_delete
|
||||
;
|
||||
*/
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Support destroying deletes
|
||||
compatibility: partial
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Support using-enum declarations.
|
||||
compatibility: partial
|
||||
usings.rel: run usings.qlo
|
||||
@@ -0,0 +1,17 @@
|
||||
class UsingEntry extends @using {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Element extends @element {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_default {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from UsingEntry u, Element target, Location loc, int kind
|
||||
where
|
||||
usings(u, target, loc) and
|
||||
if target instanceof @namespace then kind = 2 else kind = 1
|
||||
select u, target, loc, kind
|
||||
@@ -1,3 +1,14 @@
|
||||
## 1.1.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The precision of `cpp/iterator-to-expired-container` ("Iterator to expired container") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
* The precision of `cpp/unsafe-strncat` ("Potentially unsafe call to strncat") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/unsigned-difference-expression-compared-zero` ("Unsigned difference expression compared to zero") query now produces fewer false positives.
|
||||
|
||||
## 1.0.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -38,11 +38,18 @@ private string getEofValue() {
|
||||
private predicate checkedForEof(ScanfFunctionCall call) {
|
||||
exists(IRGuardCondition gc |
|
||||
exists(Instruction i | i.getUnconvertedResultExpression() = call |
|
||||
// call == EOF
|
||||
gc.comparesEq(valueNumber(i).getAUse(), getEofValue().toInt(), _, _)
|
||||
exists(int val | gc.comparesEq(valueNumber(i).getAUse(), val, _, _) |
|
||||
// call == EOF
|
||||
val = getEofValue().toInt()
|
||||
or
|
||||
// call == [any positive number]
|
||||
val > 0
|
||||
)
|
||||
or
|
||||
// call < 0 (EOF is guaranteed to be negative)
|
||||
gc.comparesLt(valueNumber(i).getAUse(), 0, true, _)
|
||||
exists(int val | gc.comparesLt(valueNumber(i).getAUse(), val, true, _) |
|
||||
// call < [any non-negative number] (EOF is guaranteed to be negative)
|
||||
val >= 0
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.models.Models
|
||||
import semmle.code.cpp.commons.Buffer
|
||||
|
||||
predicate baseType(AllocationExpr alloc, Type base) {
|
||||
exists(PointerType pointer |
|
||||
@@ -30,7 +31,8 @@ predicate baseType(AllocationExpr alloc, Type base) {
|
||||
}
|
||||
|
||||
predicate decideOnSize(Type t, int size) {
|
||||
// If the codebase has more than one type with the same name, it can have more than one size.
|
||||
// If the codebase has more than one type with the same name, it can have more than one size. For
|
||||
// most purposes in this query, we use the smallest.
|
||||
size = min(t.getSize())
|
||||
}
|
||||
|
||||
@@ -45,7 +47,8 @@ where
|
||||
size = 0 or
|
||||
(allocated / size) * size = allocated
|
||||
) and
|
||||
not basesize > allocated // covered by SizeCheck.ql
|
||||
not basesize > allocated and // covered by SizeCheck.ql
|
||||
not memberMayBeVarSize(base.getUnspecifiedType(), _) // exclude variable size types
|
||||
select alloc,
|
||||
"Allocated memory (" + allocated.toString() + " bytes) is not a multiple of the size of '" +
|
||||
base.getName() + "' (" + basesize.toString() + " bytes)."
|
||||
|
||||
@@ -232,6 +232,7 @@ predicate nullCheckInThrowingNew(NewOrNewArrayExpr newExpr, GuardCondition guard
|
||||
from NewOrNewArrayExpr newExpr, Element element, string msg, string elementString
|
||||
where
|
||||
not newExpr.isFromUninstantiatedTemplate(_) and
|
||||
not newExpr.isFromTemplateInstantiation(_) and
|
||||
(
|
||||
noThrowInTryBlock(newExpr, element) and
|
||||
msg = "This allocation cannot throw. $@ is unnecessary." and
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The precision of `cpp/unsafe-strncat` ("Potentially unsafe call to strncat") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: queryMetadata
|
||||
---
|
||||
* The precision of `cpp/iterator-to-expired-container` ("Iterator to expired container") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/unsigned-difference-expression-compared-zero` ("Unsigned difference expression compared to zero") query now produces fewer false positives.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/incorrect-allocation-error-handling` ("Incorrect allocation-error handling") query no longer produces occasional false positive results inside template instantiations.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/suspicious-allocation-size` ("Not enough memory allocated for array of pointer type") query no longer produces false positives on "variable size" `struct`s.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The `cpp/incorrectly-checked-scanf` ("Incorrect return-value check for a 'scanf'-like function") query now produces fewer false positive results.
|
||||
10
cpp/ql/src/change-notes/released/1.1.0.md
Normal file
10
cpp/ql/src/change-notes/released/1.1.0.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 1.1.0
|
||||
|
||||
### Query Metadata Changes
|
||||
|
||||
* The precision of `cpp/iterator-to-expired-container` ("Iterator to expired container") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
* The precision of `cpp/unsafe-strncat` ("Potentially unsafe call to strncat") has been increased to `high`. As a result, it will be run by default as part of the Code Scanning suite.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/unsigned-difference-expression-compared-zero` ("Unsigned difference expression compared to zero") query now produces fewer false positives.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 1.0.3
|
||||
lastReleaseVersion: 1.1.0
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 1.0.4-dev
|
||||
version: 1.1.1-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
// semmle-extractor-options: -std=c++17
|
||||
// semmle-extractor-options: -std=c++20
|
||||
typedef unsigned long size_t;
|
||||
namespace std {
|
||||
enum class align_val_t : size_t {};
|
||||
|
||||
struct destroying_delete_t {
|
||||
explicit destroying_delete_t() = default;
|
||||
};
|
||||
inline constexpr destroying_delete_t destroying_delete{};
|
||||
}
|
||||
|
||||
void* operator new(size_t, float);
|
||||
@@ -37,6 +42,11 @@ struct SizedDealloc {
|
||||
void operator delete[](void*, size_t);
|
||||
};
|
||||
|
||||
struct DestroyingDealloc {
|
||||
void* operator new(size_t);
|
||||
void operator delete(DestroyingDealloc*, std::destroying_delete_t);
|
||||
};
|
||||
|
||||
struct alignas(128) Overaligned {
|
||||
char a[256];
|
||||
};
|
||||
@@ -59,6 +69,7 @@ void OperatorDelete() {
|
||||
delete static_cast<int*>(nullptr); // No destructor
|
||||
delete static_cast<String*>(nullptr); // Non-virtual destructor, with size.
|
||||
delete static_cast<SizedDealloc*>(nullptr); // No destructor, with size.
|
||||
delete static_cast<DestroyingDealloc*>(nullptr); // No destructor, with destroying delete.
|
||||
delete static_cast<Overaligned*>(nullptr); // No destructor, with size and alignment.
|
||||
delete static_cast<PolymorphicBase*>(nullptr); // Virtual destructor
|
||||
delete static_cast<const String*>(nullptr); // Pointer to const
|
||||
@@ -103,11 +114,20 @@ struct alignas(128) FailedInitOveraligned {
|
||||
void operator delete[](void*, std::align_val_t, float); // Aligned placement
|
||||
};
|
||||
|
||||
struct alignas(128) FailedInitDestroyingDelete {
|
||||
FailedInitDestroyingDelete();
|
||||
~FailedInitDestroyingDelete();
|
||||
|
||||
void* operator new(size_t); // Non-placement
|
||||
void operator delete(FailedInitDestroyingDelete*, std::destroying_delete_t); // Destroying delete
|
||||
};
|
||||
|
||||
void TestFailedInit(int n) {
|
||||
new FailedInit();
|
||||
new FailedInit[n];
|
||||
new(1.0f) FailedInitOveraligned();
|
||||
new(1.0f) FailedInitOveraligned[10];
|
||||
new FailedInitDestroyingDelete();
|
||||
}
|
||||
|
||||
// --- non-allocating placement new ---
|
||||
|
||||
@@ -1,118 +1,123 @@
|
||||
newExprs
|
||||
| allocators.cpp:49:3:49:9 | new | int | void* operator new(unsigned long) | 4 | 4 | | |
|
||||
| allocators.cpp:50:3:50:15 | new | int | void* operator new(size_t, float) | 4 | 4 | | |
|
||||
| allocators.cpp:51:3:51:11 | new | int | void* operator new(unsigned long) | 4 | 4 | | |
|
||||
| allocators.cpp:52:3:52:14 | new | String | void* operator new(unsigned long) | 8 | 8 | | |
|
||||
| allocators.cpp:53:3:53:27 | new | String | void* operator new(size_t, float) | 8 | 8 | | |
|
||||
| allocators.cpp:54:3:54:17 | new | Overaligned | void* operator new(unsigned long, std::align_val_t) | 256 | 128 | aligned | |
|
||||
| allocators.cpp:55:3:55:25 | new | Overaligned | void* operator new(size_t, std::align_val_t, float) | 256 | 128 | aligned | |
|
||||
| allocators.cpp:107:3:107:18 | new | FailedInit | void* FailedInit::operator new(size_t) | 1 | 1 | | |
|
||||
| allocators.cpp:109:3:109:35 | new | FailedInitOveraligned | void* FailedInitOveraligned::operator new(size_t, std::align_val_t, float) | 128 | 128 | aligned | |
|
||||
| allocators.cpp:129:3:129:21 | new | int | void* operator new(std::size_t, void*) | 4 | 4 | | & ... |
|
||||
| allocators.cpp:135:3:135:26 | new | int | void* operator new(std::size_t, std::nothrow_t const&) | 4 | 4 | | |
|
||||
| allocators.cpp:59:3:59:9 | new | int | void* operator new(unsigned long) | 4 | 4 | | |
|
||||
| allocators.cpp:60:3:60:15 | new | int | void* operator new(size_t, float) | 4 | 4 | | |
|
||||
| allocators.cpp:61:3:61:11 | new | int | void* operator new(unsigned long) | 4 | 4 | | |
|
||||
| allocators.cpp:62:3:62:14 | new | String | void* operator new(unsigned long) | 8 | 8 | | |
|
||||
| allocators.cpp:63:3:63:27 | new | String | void* operator new(size_t, float) | 8 | 8 | | |
|
||||
| allocators.cpp:64:3:64:17 | new | Overaligned | void* operator new(unsigned long, std::align_val_t) | 256 | 128 | aligned | |
|
||||
| allocators.cpp:65:3:65:25 | new | Overaligned | void* operator new(size_t, std::align_val_t, float) | 256 | 128 | aligned | |
|
||||
| allocators.cpp:126:3:126:18 | new | FailedInit | void* FailedInit::operator new(size_t) | 1 | 1 | | |
|
||||
| allocators.cpp:128:3:128:35 | new | FailedInitOveraligned | void* FailedInitOveraligned::operator new(size_t, std::align_val_t, float) | 128 | 128 | aligned | |
|
||||
| allocators.cpp:130:3:130:34 | new | FailedInitDestroyingDelete | void* FailedInitDestroyingDelete::operator new(size_t) | 128 | 128 | | |
|
||||
| allocators.cpp:149:3:149:21 | new | int | void* operator new(std::size_t, void*) | 4 | 4 | | & ... |
|
||||
| allocators.cpp:155:3:155:26 | new | int | void* operator new(std::size_t, std::nothrow_t const&) | 4 | 4 | | |
|
||||
newArrayExprs
|
||||
| allocators.cpp:68:3:68:12 | new[] | int[] | int | void* operator new[](unsigned long) | 4 | 4 | | n | |
|
||||
| allocators.cpp:69:3:69:18 | new[] | int[] | int | void* operator new[](size_t, float) | 4 | 4 | | n | |
|
||||
| allocators.cpp:70:3:70:15 | new[] | String[] | String | void* operator new[](unsigned long) | 8 | 8 | | n | |
|
||||
| allocators.cpp:71:3:71:20 | new[] | Overaligned[] | Overaligned | void* operator new[](unsigned long, std::align_val_t) | 256 | 128 | aligned | n | |
|
||||
| allocators.cpp:72:3:72:16 | new[] | String[10] | String | void* operator new[](unsigned long) | 8 | 8 | | | |
|
||||
| allocators.cpp:108:3:108:19 | new[] | FailedInit[] | FailedInit | void* FailedInit::operator new[](size_t) | 1 | 1 | | n | |
|
||||
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned[10] | FailedInitOveraligned | void* FailedInitOveraligned::operator new[](size_t, std::align_val_t, float) | 128 | 128 | aligned | | |
|
||||
| allocators.cpp:132:3:132:17 | new[] | int[1] | int | void* operator new[](std::size_t, void*) | 4 | 4 | | | buf |
|
||||
| allocators.cpp:136:3:136:26 | new[] | int[2] | int | void* operator new[](std::size_t, std::nothrow_t const&) | 4 | 4 | | | |
|
||||
| allocators.cpp:142:13:142:27 | new[] | char[][10] | char[10] | void* operator new[](unsigned long) | 10 | 1 | | x | |
|
||||
| allocators.cpp:143:13:143:28 | new[] | char[20][20] | char[20] | void* operator new[](unsigned long) | 20 | 1 | | | |
|
||||
| allocators.cpp:144:13:144:31 | new[] | char[][30][30] | char[30][30] | void* operator new[](unsigned long) | 900 | 1 | | x | |
|
||||
| allocators.cpp:79:3:79:12 | new[] | int[] | int | void* operator new[](unsigned long) | 4 | 4 | | n | |
|
||||
| allocators.cpp:80:3:80:18 | new[] | int[] | int | void* operator new[](size_t, float) | 4 | 4 | | n | |
|
||||
| allocators.cpp:81:3:81:15 | new[] | String[] | String | void* operator new[](unsigned long) | 8 | 8 | | n | |
|
||||
| allocators.cpp:82:3:82:20 | new[] | Overaligned[] | Overaligned | void* operator new[](unsigned long, std::align_val_t) | 256 | 128 | aligned | n | |
|
||||
| allocators.cpp:83:3:83:16 | new[] | String[10] | String | void* operator new[](unsigned long) | 8 | 8 | | | |
|
||||
| allocators.cpp:127:3:127:19 | new[] | FailedInit[] | FailedInit | void* FailedInit::operator new[](size_t) | 1 | 1 | | n | |
|
||||
| allocators.cpp:129:3:129:37 | new[] | FailedInitOveraligned[10] | FailedInitOveraligned | void* FailedInitOveraligned::operator new[](size_t, std::align_val_t, float) | 128 | 128 | aligned | | |
|
||||
| allocators.cpp:152:3:152:17 | new[] | int[1] | int | void* operator new[](std::size_t, void*) | 4 | 4 | | | buf |
|
||||
| allocators.cpp:156:3:156:26 | new[] | int[2] | int | void* operator new[](std::size_t, std::nothrow_t const&) | 4 | 4 | | | |
|
||||
| allocators.cpp:162:13:162:27 | new[] | char[][10] | char[10] | void* operator new[](unsigned long) | 10 | 1 | | x | |
|
||||
| allocators.cpp:163:13:163:28 | new[] | char[20][20] | char[20] | void* operator new[](unsigned long) | 20 | 1 | | | |
|
||||
| allocators.cpp:164:13:164:31 | new[] | char[][30][30] | char[30][30] | void* operator new[](unsigned long) | 900 | 1 | | x | |
|
||||
newExprDeallocators
|
||||
| allocators.cpp:52:3:52:14 | new | String | void operator delete(void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:53:3:53:27 | new | String | void operator delete(void*, float) | 8 | 8 | |
|
||||
| allocators.cpp:107:3:107:18 | new | FailedInit | void FailedInit::operator delete(void*, size_t) | 1 | 1 | sized |
|
||||
| allocators.cpp:109:3:109:35 | new | FailedInitOveraligned | void FailedInitOveraligned::operator delete(void*, std::align_val_t, float) | 128 | 128 | aligned |
|
||||
| allocators.cpp:62:3:62:14 | new | String | void operator delete(void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:63:3:63:27 | new | String | void operator delete(void*, float) | 8 | 8 | |
|
||||
| allocators.cpp:126:3:126:18 | new | FailedInit | void FailedInit::operator delete(void*, size_t) | 1 | 1 | sized |
|
||||
| allocators.cpp:128:3:128:35 | new | FailedInitOveraligned | void FailedInitOveraligned::operator delete(void*, std::align_val_t, float) | 128 | 128 | aligned |
|
||||
| allocators.cpp:130:3:130:34 | new | FailedInitDestroyingDelete | void FailedInitDestroyingDelete::operator delete(FailedInitDestroyingDelete*, std::destroying_delete_t) | 128 | 128 | destroying |
|
||||
newArrayExprDeallocators
|
||||
| allocators.cpp:70:3:70:15 | new[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:72:3:72:16 | new[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:108:3:108:19 | new[] | FailedInit | void FailedInit::operator delete[](void*, size_t) | 1 | 1 | sized |
|
||||
| allocators.cpp:110:3:110:37 | new[] | FailedInitOveraligned | void FailedInitOveraligned::operator delete[](void*, std::align_val_t, float) | 128 | 128 | aligned |
|
||||
| allocators.cpp:81:3:81:15 | new[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:83:3:83:16 | new[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:127:3:127:19 | new[] | FailedInit | void FailedInit::operator delete[](void*, size_t) | 1 | 1 | sized |
|
||||
| allocators.cpp:129:3:129:37 | new[] | FailedInitOveraligned | void FailedInitOveraligned::operator delete[](void*, std::align_val_t, float) | 128 | 128 | aligned |
|
||||
deleteExprs
|
||||
| allocators.cpp:59:3:59:35 | delete | int | void operator delete(void*, unsigned long) | 4 | 4 | sized | false |
|
||||
| allocators.cpp:60:3:60:38 | delete | String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
| allocators.cpp:61:3:61:44 | delete | SizedDealloc | void SizedDealloc::operator delete(void*, size_t) | 32 | 1 | sized | true |
|
||||
| allocators.cpp:62:3:62:43 | delete | Overaligned | void operator delete(void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned | false |
|
||||
| allocators.cpp:64:3:64:44 | delete | const String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
| allocators.cpp:69:3:69:35 | delete | int | void operator delete(void*, unsigned long) | 4 | 4 | sized | false |
|
||||
| allocators.cpp:70:3:70:38 | delete | String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
| allocators.cpp:71:3:71:44 | delete | SizedDealloc | void SizedDealloc::operator delete(void*, size_t) | 32 | 1 | sized | true |
|
||||
| allocators.cpp:72:3:72:49 | delete | DestroyingDealloc | void DestroyingDealloc::operator delete(DestroyingDealloc*, std::destroying_delete_t) | 1 | 1 | destroying | true |
|
||||
| allocators.cpp:73:3:73:43 | delete | Overaligned | void operator delete(void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned | false |
|
||||
| allocators.cpp:75:3:75:44 | delete | const String | void operator delete(void*, unsigned long) | 8 | 8 | sized | false |
|
||||
deleteArrayExprs
|
||||
| allocators.cpp:78:3:78:37 | delete[] | int | void operator delete[](void*, unsigned long) | 4 | 4 | sized |
|
||||
| allocators.cpp:79:3:79:40 | delete[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:80:3:80:46 | delete[] | SizedDealloc | void SizedDealloc::operator delete[](void*, size_t) | 32 | 1 | sized |
|
||||
| allocators.cpp:81:3:81:45 | delete[] | Overaligned | void operator delete[](void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned |
|
||||
| allocators.cpp:82:3:82:49 | delete[] | PolymorphicBase | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:83:3:83:23 | delete[] | int | void operator delete[](void*, unsigned long) | 4 | 4 | sized |
|
||||
| allocators.cpp:89:3:89:37 | delete[] | int | void operator delete[](void*, unsigned long) | 4 | 4 | sized |
|
||||
| allocators.cpp:90:3:90:40 | delete[] | String | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:91:3:91:46 | delete[] | SizedDealloc | void SizedDealloc::operator delete[](void*, size_t) | 32 | 1 | sized |
|
||||
| allocators.cpp:92:3:92:45 | delete[] | Overaligned | void operator delete[](void*, unsigned long, std::align_val_t) | 256 | 128 | sized aligned |
|
||||
| allocators.cpp:93:3:93:49 | delete[] | PolymorphicBase | void operator delete[](void*, unsigned long) | 8 | 8 | sized |
|
||||
| allocators.cpp:94:3:94:23 | delete[] | int | void operator delete[](void*, unsigned long) | 4 | 4 | sized |
|
||||
allocationFunctions
|
||||
| allocators.cpp:7:7:7:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:8:7:8:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:9:7:9:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:10:7:10:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:121:7:121:18 | operator new | getPlacementArgument = 1, getSizeArg = 0 |
|
||||
| allocators.cpp:122:7:122:20 | operator new[] | getPlacementArgument = 1, getSizeArg = 0 |
|
||||
| allocators.cpp:123:7:123:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:124:7:124:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:153:7:153:12 | malloc | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:12:7:12:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:13:7:13:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:14:7:14:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:15:7:15:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:141:7:141:18 | operator new | getPlacementArgument = 1, getSizeArg = 0 |
|
||||
| allocators.cpp:142:7:142:20 | operator new[] | getPlacementArgument = 1, getSizeArg = 0 |
|
||||
| allocators.cpp:143:7:143:18 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:144:7:144:20 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| allocators.cpp:173:7:173:12 | malloc | getSizeArg = 0, requiresDealloc |
|
||||
| file://:0:0:0:0 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| file://:0:0:0:0 | operator new | getSizeArg = 0, requiresDealloc |
|
||||
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
| file://:0:0:0:0 | operator new[] | getSizeArg = 0, requiresDealloc |
|
||||
allocationExprs
|
||||
| allocators.cpp:49:3:49:9 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:50:3:50:15 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:51:3:51:11 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:52:3:52:14 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:53:3:53:27 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:54:3:54:17 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||
| allocators.cpp:55:3:55:25 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||
| allocators.cpp:68:3:68:12 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:69:3:69:18 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:70:3:70:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
|
||||
| allocators.cpp:71:3:71:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
|
||||
| allocators.cpp:72:3:72:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
|
||||
| allocators.cpp:107:3:107:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
|
||||
| allocators.cpp:108:3:108:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:109:3:109:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
|
||||
| allocators.cpp:110:3:110:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
|
||||
| allocators.cpp:129:3:129:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||
| allocators.cpp:132:3:132:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||
| allocators.cpp:135:3:135:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:136:3:136:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:142:13:142:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
|
||||
| allocators.cpp:143:13:143:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
|
||||
| allocators.cpp:144:13:144:31 | new[] | getAllocatedElementType = char[30][30], getSizeExpr = x, getSizeMult = 900, requiresDealloc |
|
||||
| allocators.cpp:149:8:149:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:157:50:157:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:158:26:158:31 | call to malloc | getAllocatedElementType = int, getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:159:31:159:36 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:160:16:160:21 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:161:34:161:39 | call to malloc | getAllocatedElementType = const char, getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:162:23:162:28 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
|
||||
| allocators.cpp:163:3:163:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:59:3:59:9 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:60:3:60:15 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:61:3:61:11 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:62:3:62:14 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:63:3:63:27 | new | getAllocatedElementType = String, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:64:3:64:17 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||
| allocators.cpp:65:3:65:25 | new | getAllocatedElementType = Overaligned, getSizeBytes = 256, requiresDealloc |
|
||||
| allocators.cpp:79:3:79:12 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:80:3:80:18 | new[] | getAllocatedElementType = int, getSizeExpr = n, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:81:3:81:15 | new[] | getAllocatedElementType = String, getSizeExpr = n, getSizeMult = 8, requiresDealloc |
|
||||
| allocators.cpp:82:3:82:20 | new[] | getAllocatedElementType = Overaligned, getSizeExpr = n, getSizeMult = 256, requiresDealloc |
|
||||
| allocators.cpp:83:3:83:16 | new[] | getAllocatedElementType = String, getSizeBytes = 80, requiresDealloc |
|
||||
| allocators.cpp:126:3:126:18 | new | getAllocatedElementType = FailedInit, getSizeBytes = 1, requiresDealloc |
|
||||
| allocators.cpp:127:3:127:19 | new[] | getAllocatedElementType = FailedInit, getSizeExpr = n, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:128:3:128:35 | new | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 128, requiresDealloc |
|
||||
| allocators.cpp:129:3:129:37 | new[] | getAllocatedElementType = FailedInitOveraligned, getSizeBytes = 1280, requiresDealloc |
|
||||
| allocators.cpp:130:3:130:34 | new | getAllocatedElementType = FailedInitDestroyingDelete, getSizeBytes = 128, requiresDealloc |
|
||||
| allocators.cpp:149:3:149:21 | new | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||
| allocators.cpp:152:3:152:17 | new[] | getAllocatedElementType = int, getSizeBytes = 4 |
|
||||
| allocators.cpp:155:3:155:26 | new | getAllocatedElementType = int, getSizeBytes = 4, requiresDealloc |
|
||||
| allocators.cpp:156:3:156:26 | new[] | getAllocatedElementType = int, getSizeBytes = 8, requiresDealloc |
|
||||
| allocators.cpp:162:13:162:27 | new[] | getAllocatedElementType = char[10], getSizeExpr = x, getSizeMult = 10, requiresDealloc |
|
||||
| allocators.cpp:163:13:163:28 | new[] | getAllocatedElementType = char[20], getSizeBytes = 400, requiresDealloc |
|
||||
| allocators.cpp:164:13:164:31 | new[] | getAllocatedElementType = char[30][30], getSizeExpr = x, getSizeMult = 900, requiresDealloc |
|
||||
| allocators.cpp:169:8:169:19 | call to operator new | getSizeBytes = 4, getSizeExpr = sizeof(int), getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:177:50:177:55 | call to malloc | getAllocatedElementType = const volatile int, getSizeBytes = 5, getSizeExpr = 5, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:178:26:178:31 | call to malloc | getAllocatedElementType = int, getSizeBytes = 20, getSizeExpr = 5, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:179:31:179:36 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:180:16:180:21 | call to malloc | getAllocatedElementType = volatile long, getSizeExpr = count, getSizeMult = 4, requiresDealloc |
|
||||
| allocators.cpp:181:34:181:39 | call to malloc | getAllocatedElementType = const char, getSizeExpr = ... + ..., getSizeMult = 1, requiresDealloc |
|
||||
| allocators.cpp:182:23:182:28 | call to malloc | getSizeExpr = count, getSizeMult = 8, requiresDealloc |
|
||||
| allocators.cpp:183:3:183:8 | call to malloc | getSizeBytes = 32, getSizeExpr = ... * ..., getSizeMult = 1, requiresDealloc |
|
||||
deallocationFunctions
|
||||
| allocators.cpp:11:6:11:20 | operator delete | getFreedArg = 0 |
|
||||
| allocators.cpp:12:6:12:22 | operator delete[] | getFreedArg = 0 |
|
||||
| allocators.cpp:13:6:13:20 | operator delete | getFreedArg = 0 |
|
||||
| allocators.cpp:14:6:14:22 | operator delete[] | getFreedArg = 0 |
|
||||
| allocators.cpp:16:6:16:20 | operator delete | getFreedArg = 0 |
|
||||
| allocators.cpp:17:6:17:22 | operator delete[] | getFreedArg = 0 |
|
||||
| allocators.cpp:18:6:18:20 | operator delete | getFreedArg = 0 |
|
||||
| allocators.cpp:19:6:19:22 | operator delete[] | getFreedArg = 0 |
|
||||
| file://:0:0:0:0 | operator delete | getFreedArg = 0 |
|
||||
| file://:0:0:0:0 | operator delete | getFreedArg = 0 |
|
||||
| file://:0:0:0:0 | operator delete | getFreedArg = 0 |
|
||||
| file://:0:0:0:0 | operator delete[] | getFreedArg = 0 |
|
||||
| file://:0:0:0:0 | operator delete[] | getFreedArg = 0 |
|
||||
deallocationExprs
|
||||
| allocators.cpp:59:3:59:35 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:60:3:60:38 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:61:3:61:44 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:62:3:62:43 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:63:3:63:47 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:64:3:64:44 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:78:3:78:37 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:79:3:79:40 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:80:3:80:46 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:81:3:81:45 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:82:3:82:49 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:83:3:83:23 | delete[] | getFreedExpr = call to GetPointer |
|
||||
| allocators.cpp:150:2:150:16 | call to operator delete | getFreedExpr = ptr |
|
||||
| allocators.cpp:69:3:69:35 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:70:3:70:38 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:71:3:71:44 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:72:3:72:49 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:73:3:73:43 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:74:3:74:47 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:75:3:75:44 | delete | getFreedExpr = 0 |
|
||||
| allocators.cpp:89:3:89:37 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:90:3:90:40 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:91:3:91:46 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:92:3:92:45 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:93:3:93:49 | delete[] | getFreedExpr = 0 |
|
||||
| allocators.cpp:94:3:94:23 | delete[] | getFreedExpr = call to GetPointer |
|
||||
| allocators.cpp:170:2:170:16 | call to operator delete | getFreedExpr = ptr |
|
||||
|
||||
@@ -50,10 +50,11 @@ query predicate newExprDeallocators(
|
||||
type = allocatedType.toString() and
|
||||
size = allocatedType.getSize() and
|
||||
alignment = allocatedType.getAlignment() and
|
||||
exists(string sized, string aligned |
|
||||
exists(string sized, string aligned, string destroying |
|
||||
(if expr.hasAlignedDeallocation() then aligned = "aligned" else aligned = "") and
|
||||
(if expr.hasSizedDeallocation() then sized = "sized" else sized = "") and
|
||||
form = sized + " " + aligned
|
||||
(if expr.isDestroyingDeleteDeallocation() then destroying = "destroying" else destroying = "") and
|
||||
form = sized + " " + aligned + " " + destroying
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -68,10 +69,11 @@ query predicate newArrayExprDeallocators(
|
||||
type = elementType.toString() and
|
||||
size = elementType.getSize() and
|
||||
alignment = elementType.getAlignment() and
|
||||
exists(string sized, string aligned |
|
||||
exists(string sized, string aligned, string destroying |
|
||||
(if expr.hasAlignedDeallocation() then aligned = "aligned" else aligned = "") and
|
||||
(if expr.hasSizedDeallocation() then sized = "sized" else sized = "") and
|
||||
form = sized + " " + aligned
|
||||
(if expr.isDestroyingDeleteDeallocation() then destroying = "destroying" else destroying = "") and
|
||||
form = sized + " " + aligned + " " + destroying
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -87,10 +89,11 @@ query predicate deleteExprs(
|
||||
type = deletedType.toString() and
|
||||
size = deletedType.getSize() and
|
||||
alignment = deletedType.getAlignment() and
|
||||
exists(string sized, string aligned |
|
||||
exists(string sized, string aligned, string destroying |
|
||||
(if expr.hasAlignedDeallocation() then aligned = "aligned" else aligned = "") and
|
||||
(if expr.hasSizedDeallocation() then sized = "sized" else sized = "") and
|
||||
form = sized + " " + aligned
|
||||
(if expr.isDestroyingDeleteDeallocation() then destroying = "destroying" else destroying = "") and
|
||||
form = sized + " " + aligned + " " + destroying
|
||||
) and
|
||||
if exists(expr.getDeallocatorCall())
|
||||
then hasDeallocatorCall = true
|
||||
@@ -108,10 +111,11 @@ query predicate deleteArrayExprs(
|
||||
type = elementType.toString() and
|
||||
size = elementType.getSize() and
|
||||
alignment = elementType.getAlignment() and
|
||||
exists(string sized, string aligned |
|
||||
exists(string sized, string aligned, string destroying |
|
||||
(if expr.hasAlignedDeallocation() then aligned = "aligned" else aligned = "") and
|
||||
(if expr.hasSizedDeallocation() then sized = "sized" else sized = "") and
|
||||
form = sized + " " + aligned
|
||||
(if expr.isDestroyingDeleteDeallocation() then destroying = "destroying" else destroying = "") and
|
||||
form = sized + " " + aligned + " " + destroying
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -26,8 +26,11 @@
|
||||
| test.cpp:128:15:128:16 | v4 |
|
||||
| test.cpp:185:10:185:12 | cpy |
|
||||
| test.cpp:199:10:199:12 | cpy |
|
||||
| test.cpp:208:7:208:7 | a |
|
||||
| test.cpp:214:7:214:7 | a |
|
||||
| test.cpp:213:7:213:7 | a |
|
||||
| test.cpp:219:7:219:7 | a |
|
||||
| test.cpp:228:14:228:18 | data1 |
|
||||
| test.cpp:236:14:236:18 | data1 |
|
||||
| test.cpp:237:14:237:18 | data2 |
|
||||
| test_free.cpp:11:10:11:10 | a |
|
||||
| test_free.cpp:14:10:14:10 | a |
|
||||
| test_free.cpp:16:10:16:10 | a |
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
edges
|
||||
| test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | provenance | |
|
||||
| test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | provenance | |
|
||||
| test.cpp:213:7:213:7 | pointer to free output argument | test.cpp:214:2:214:2 | a | provenance | |
|
||||
| test.cpp:219:7:219:7 | pointer to free output argument | test.cpp:220:2:220:2 | a | provenance | |
|
||||
| test.cpp:228:12:228:12 | *p [post update] [data1] | test.cpp:229:2:229:2 | *p [data1] | provenance | |
|
||||
| test.cpp:228:14:228:18 | pointer to operator delete[] output argument | test.cpp:228:12:228:12 | *p [post update] [data1] | provenance | |
|
||||
| test.cpp:229:2:229:2 | *p [data1] | test.cpp:229:4:229:8 | data1 | provenance | |
|
||||
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | provenance | |
|
||||
| test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | provenance | |
|
||||
| test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | provenance | |
|
||||
@@ -33,10 +36,14 @@ edges
|
||||
| test_free.cpp:322:12:322:12 | pointer to operator delete output argument | test_free.cpp:324:5:324:6 | * ... | provenance | |
|
||||
| test_free.cpp:331:12:331:12 | pointer to operator delete output argument | test_free.cpp:332:5:332:6 | * ... | provenance | |
|
||||
nodes
|
||||
| test.cpp:208:7:208:7 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test.cpp:209:2:209:2 | a | semmle.label | a |
|
||||
| test.cpp:214:7:214:7 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test.cpp:215:2:215:2 | a | semmle.label | a |
|
||||
| test.cpp:213:7:213:7 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test.cpp:214:2:214:2 | a | semmle.label | a |
|
||||
| test.cpp:219:7:219:7 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test.cpp:220:2:220:2 | a | semmle.label | a |
|
||||
| test.cpp:228:12:228:12 | *p [post update] [data1] | semmle.label | *p [post update] [data1] |
|
||||
| test.cpp:228:14:228:18 | pointer to operator delete[] output argument | semmle.label | pointer to operator delete[] output argument |
|
||||
| test.cpp:229:2:229:2 | *p [data1] | semmle.label | *p [data1] |
|
||||
| test.cpp:229:4:229:8 | data1 | semmle.label | data1 |
|
||||
| test_free.cpp:11:10:11:10 | pointer to free output argument | semmle.label | pointer to free output argument |
|
||||
| test_free.cpp:12:5:12:5 | a | semmle.label | a |
|
||||
| test_free.cpp:13:5:13:6 | * ... | semmle.label | * ... |
|
||||
@@ -88,8 +95,9 @@ nodes
|
||||
| test_free.cpp:332:5:332:6 | * ... | semmle.label | * ... |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:209:2:209:2 | a | test.cpp:208:7:208:7 | pointer to free output argument | test.cpp:209:2:209:2 | a | Memory may have been previously freed by $@. | test.cpp:208:2:208:5 | call to free | call to free |
|
||||
| test.cpp:215:2:215:2 | a | test.cpp:214:7:214:7 | pointer to free output argument | test.cpp:215:2:215:2 | a | Memory may have been previously freed by $@. | test.cpp:214:2:214:5 | call to free | call to free |
|
||||
| test.cpp:214:2:214:2 | a | test.cpp:213:7:213:7 | pointer to free output argument | test.cpp:214:2:214:2 | a | Memory may have been previously freed by $@. | test.cpp:213:2:213:5 | call to free | call to free |
|
||||
| test.cpp:220:2:220:2 | a | test.cpp:219:7:219:7 | pointer to free output argument | test.cpp:220:2:220:2 | a | Memory may have been previously freed by $@. | test.cpp:219:2:219:5 | call to free | call to free |
|
||||
| test.cpp:229:4:229:8 | data1 | test.cpp:228:14:228:18 | pointer to operator delete[] output argument | test.cpp:229:4:229:8 | data1 | Memory may have been previously freed by $@. | test.cpp:228:2:228:18 | delete[] | delete[] |
|
||||
| test_free.cpp:12:5:12:5 | a | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:12:5:12:5 | a | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
| test_free.cpp:13:5:13:6 | * ... | test_free.cpp:11:10:11:10 | pointer to free output argument | test_free.cpp:13:5:13:6 | * ... | Memory may have been previously freed by $@. | test_free.cpp:11:5:11:8 | call to free | call to free |
|
||||
| test_free.cpp:45:5:45:5 | a | test_free.cpp:42:27:42:27 | pointer to free output argument | test_free.cpp:45:5:45:5 | a | Memory may have been previously freed by $@. | test_free.cpp:42:22:42:25 | call to free | call to free |
|
||||
|
||||
@@ -201,6 +201,11 @@ void test_strndupa_dealloc() {
|
||||
|
||||
// ---
|
||||
|
||||
struct DataPair {
|
||||
char *data1;
|
||||
char *data2;
|
||||
};
|
||||
|
||||
void test_reassignment() {
|
||||
char *a = (char *)malloc(128);
|
||||
char *b = (char *)malloc(128);
|
||||
@@ -213,4 +218,21 @@ void test_reassignment() {
|
||||
|
||||
free(a);
|
||||
a[0] = 0; // BAD
|
||||
|
||||
DataPair p;
|
||||
p.data1 = new char[128];
|
||||
p.data2 = new char[128];
|
||||
p.data1[0] = 0; // GOOD
|
||||
p.data2[0] = 0; // GOOD
|
||||
|
||||
delete [] p.data1;
|
||||
p.data1[0] = 0; // BAD
|
||||
p.data2[0] = 0; // GOOD
|
||||
|
||||
p.data1 = new char[128];
|
||||
p.data1[0] = 0; // GOOD
|
||||
p.data2[0] = 0; // GOOD
|
||||
|
||||
delete [] p.data1;
|
||||
delete [] p.data2;
|
||||
}
|
||||
|
||||
@@ -37,6 +37,21 @@ edges
|
||||
| test.cpp:420:19:420:20 | scanf output argument | test.cpp:423:7:423:7 | i | provenance | |
|
||||
| test.cpp:455:41:455:46 | sscanf output argument | test.cpp:460:6:460:10 | value | provenance | |
|
||||
| test.cpp:467:20:467:25 | scanf output argument | test.cpp:474:6:474:10 | value | provenance | |
|
||||
| test.cpp:480:25:480:26 | scanf output argument | test.cpp:484:9:484:9 | i | provenance | |
|
||||
| test.cpp:491:25:491:26 | scanf output argument | test.cpp:495:8:495:8 | i | provenance | |
|
||||
| test.cpp:501:25:501:26 | scanf output argument | test.cpp:505:9:505:9 | i | provenance | |
|
||||
| test.cpp:512:25:512:26 | scanf output argument | test.cpp:516:9:516:9 | i | provenance | |
|
||||
| test.cpp:525:35:525:36 | sscanf output argument | test.cpp:527:8:527:8 | a | provenance | |
|
||||
| test.cpp:525:35:525:36 | sscanf output argument | test.cpp:531:8:531:8 | a | provenance | |
|
||||
| test.cpp:525:39:525:40 | sscanf output argument | test.cpp:528:8:528:8 | b | provenance | |
|
||||
| test.cpp:525:39:525:40 | sscanf output argument | test.cpp:532:8:532:8 | b | provenance | |
|
||||
| test.cpp:525:43:525:44 | sscanf output argument | test.cpp:533:8:533:8 | c | provenance | |
|
||||
| test.cpp:541:35:541:36 | sscanf output argument | test.cpp:543:8:543:8 | d | provenance | |
|
||||
| test.cpp:541:35:541:36 | sscanf output argument | test.cpp:548:8:548:8 | d | provenance | |
|
||||
| test.cpp:541:39:541:40 | sscanf output argument | test.cpp:544:8:544:8 | e | provenance | |
|
||||
| test.cpp:541:39:541:40 | sscanf output argument | test.cpp:549:8:549:8 | e | provenance | |
|
||||
| test.cpp:541:43:541:44 | sscanf output argument | test.cpp:545:8:545:8 | f | provenance | |
|
||||
| test.cpp:541:43:541:44 | sscanf output argument | test.cpp:550:8:550:8 | f | provenance | |
|
||||
nodes
|
||||
| test.cpp:34:15:34:16 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:35:7:35:7 | i | semmle.label | i |
|
||||
@@ -114,6 +129,31 @@ nodes
|
||||
| test.cpp:460:6:460:10 | value | semmle.label | value |
|
||||
| test.cpp:467:20:467:25 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:474:6:474:10 | value | semmle.label | value |
|
||||
| test.cpp:480:25:480:26 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:484:9:484:9 | i | semmle.label | i |
|
||||
| test.cpp:491:25:491:26 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:495:8:495:8 | i | semmle.label | i |
|
||||
| test.cpp:501:25:501:26 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:505:9:505:9 | i | semmle.label | i |
|
||||
| test.cpp:512:25:512:26 | scanf output argument | semmle.label | scanf output argument |
|
||||
| test.cpp:516:9:516:9 | i | semmle.label | i |
|
||||
| test.cpp:525:35:525:36 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:525:39:525:40 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:525:43:525:44 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:527:8:527:8 | a | semmle.label | a |
|
||||
| test.cpp:528:8:528:8 | b | semmle.label | b |
|
||||
| test.cpp:531:8:531:8 | a | semmle.label | a |
|
||||
| test.cpp:532:8:532:8 | b | semmle.label | b |
|
||||
| test.cpp:533:8:533:8 | c | semmle.label | c |
|
||||
| test.cpp:541:35:541:36 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:541:39:541:40 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:541:43:541:44 | sscanf output argument | semmle.label | sscanf output argument |
|
||||
| test.cpp:543:8:543:8 | d | semmle.label | d |
|
||||
| test.cpp:544:8:544:8 | e | semmle.label | e |
|
||||
| test.cpp:545:8:545:8 | f | semmle.label | f |
|
||||
| test.cpp:548:8:548:8 | d | semmle.label | d |
|
||||
| test.cpp:549:8:549:8 | e | semmle.label | e |
|
||||
| test.cpp:550:8:550:8 | f | semmle.label | f |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:35:7:35:7 | i | test.cpp:34:15:34:16 | scanf output argument | test.cpp:35:7:35:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:34:3:34:7 | call to scanf | call to scanf |
|
||||
@@ -134,3 +174,6 @@ subpaths
|
||||
| test.cpp:423:7:423:7 | i | test.cpp:420:19:420:20 | scanf output argument | test.cpp:423:7:423:7 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:420:7:420:11 | call to scanf | call to scanf |
|
||||
| test.cpp:460:6:460:10 | value | test.cpp:455:41:455:46 | sscanf output argument | test.cpp:460:6:460:10 | value | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:455:12:455:17 | call to sscanf | call to sscanf |
|
||||
| test.cpp:474:6:474:10 | value | test.cpp:467:20:467:25 | scanf output argument | test.cpp:474:6:474:10 | value | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:467:8:467:12 | call to scanf | call to scanf |
|
||||
| test.cpp:484:9:484:9 | i | test.cpp:480:25:480:26 | scanf output argument | test.cpp:484:9:484:9 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:480:13:480:17 | call to scanf | call to scanf |
|
||||
| test.cpp:495:8:495:8 | i | test.cpp:491:25:491:26 | scanf output argument | test.cpp:495:8:495:8 | i | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 1. | test.cpp:491:13:491:17 | call to scanf | call to scanf |
|
||||
| test.cpp:545:8:545:8 | f | test.cpp:541:43:541:44 | sscanf output argument | test.cpp:545:8:545:8 | f | This variable is read, but may not have been written. It should be guarded by a check that the $@ returns at least 3. | test.cpp:541:10:541:15 | call to sscanf | call to sscanf |
|
||||
|
||||
@@ -472,4 +472,84 @@ void check_for_negative_test() {
|
||||
return;
|
||||
}
|
||||
use(value);
|
||||
}
|
||||
}
|
||||
|
||||
void multiple_checks() {
|
||||
{
|
||||
int i;
|
||||
int res = scanf("%d", &i);
|
||||
|
||||
if (res >= 0) {
|
||||
if (res != 0) {
|
||||
use(i); // GOOD: checks return value [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int res = scanf("%d", &i);
|
||||
|
||||
if (res < 0) return;
|
||||
if (res != 0) {
|
||||
use(i); // GOOD: checks return value [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int res = scanf("%d", &i);
|
||||
|
||||
if (res >= 1) {
|
||||
if (res != 0) {
|
||||
use(i); // GOOD: checks return value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
int i;
|
||||
int res = scanf("%d", &i);
|
||||
|
||||
if (res == 1) {
|
||||
if (res != 0) {
|
||||
use(i); // GOOD: checks return value
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void switch_cases(const char *data) {
|
||||
float a, b, c;
|
||||
|
||||
switch (sscanf(data, "%f %f %f", &a, &b, &c)) {
|
||||
case 2:
|
||||
use(a); // GOOD
|
||||
use(b); // GOOD
|
||||
break;
|
||||
case 3:
|
||||
use(a); // GOOD
|
||||
use(b); // GOOD
|
||||
use(c); // GOOD
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
float d, e, f;
|
||||
|
||||
switch (sscanf(data, "%f %f %f", &d, &e, &f)) {
|
||||
case 2:
|
||||
use(d); // GOOD
|
||||
use(e); // GOOD
|
||||
use(f); // BAD
|
||||
break;
|
||||
case 3:
|
||||
use(d); // GOOD
|
||||
use(e); // GOOD
|
||||
use(f); // GOOD
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
| test2.c:17:20:17:25 | call to malloc | Allocated memory (33 bytes) is not a multiple of the size of 'double' (8 bytes). |
|
||||
| test2.c:32:23:32:28 | call to malloc | Allocated memory (28 bytes) is not a multiple of the size of 'long long' (8 bytes). |
|
||||
| test2.c:33:20:33:25 | call to malloc | Allocated memory (20 bytes) is not a multiple of the size of 'double' (8 bytes). |
|
||||
| test2.c:85:24:85:29 | call to malloc | Allocated memory (1159 bytes) is not a multiple of the size of 'MyFixedStruct' (1032 bytes). |
|
||||
|
||||
@@ -60,7 +60,7 @@ void test_union() {
|
||||
}
|
||||
|
||||
// --- custom allocators ---
|
||||
|
||||
|
||||
void *MyMalloc1(size_t size) { return malloc(size); }
|
||||
void *MyMalloc2(size_t size);
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ void good1(void) {
|
||||
}
|
||||
|
||||
// --- custom allocators ---
|
||||
|
||||
|
||||
void *MyMalloc1(size_t size) { return malloc(size); }
|
||||
void *MyMalloc2(size_t size);
|
||||
|
||||
@@ -53,3 +53,34 @@ void customAllocatorTests()
|
||||
double *dptr1 = MyMalloc1(33); // BAD -- Not a multiple of sizeof(double) [NOT DETECTED]
|
||||
double *dptr2 = MyMalloc2(33); // BAD -- Not a multiple of sizeof(double) [NOT DETECTED]
|
||||
}
|
||||
|
||||
// --- variable length data structures ---
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
|
||||
typedef struct _MyVarStruct1 {
|
||||
size_t dataLen;
|
||||
uint8_t data[0];
|
||||
} MyVarStruct1;
|
||||
|
||||
typedef struct _MyVarStruct2 {
|
||||
size_t dataLen;
|
||||
uint8_t data[1];
|
||||
} MyVarStruct2;
|
||||
|
||||
typedef struct _MyVarStruct3 {
|
||||
size_t dataLen;
|
||||
uint8_t data[];
|
||||
} MyVarStruct3;
|
||||
|
||||
typedef struct _MyFixedStruct {
|
||||
size_t dataLen;
|
||||
uint8_t data[1024];
|
||||
} MyFixedStruct;
|
||||
|
||||
void varStructTests() {
|
||||
MyVarStruct1 *a = malloc(sizeof(MyVarStruct1) + 127); // GOOD
|
||||
MyVarStruct2 *b = malloc(sizeof(MyVarStruct2) + 127); // GOOD
|
||||
MyVarStruct3 *c = malloc(sizeof(MyVarStruct3) + 127); // GOOD
|
||||
MyFixedStruct *d = malloc(sizeof(MyFixedStruct) + 127); // BAD --- Not a multiple of sizeof(MyFixedStruct)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
| test.cpp:92:5:92:31 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:97:36:98:3 | { ... } | This catch block |
|
||||
| test.cpp:93:15:93:41 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:97:36:98:3 | { ... } | This catch block |
|
||||
| test.cpp:96:10:96:36 | new[] | This allocation cannot throw. $@ is unnecessary. | test.cpp:97:36:98:3 | { ... } | This catch block |
|
||||
| test.cpp:151:9:151:24 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:152:15:152:18 | { ... } | This catch block |
|
||||
| test.cpp:199:15:199:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:201:16:201:19 | { ... } | This catch block |
|
||||
| test.cpp:212:14:212:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:213:34:213:36 | { ... } | This catch block |
|
||||
| test.cpp:246:17:246:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:247:8:247:12 | ! ... | This check |
|
||||
| test.cpp:160:9:160:24 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:161:15:161:18 | { ... } | This catch block |
|
||||
| test.cpp:229:15:229:35 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:231:16:231:19 | { ... } | This catch block |
|
||||
| test.cpp:242:14:242:34 | new | This allocation cannot throw. $@ is unnecessary. | test.cpp:243:34:243:36 | { ... } | This catch block |
|
||||
| test.cpp:276:17:276:31 | new[] | This allocation cannot return null. $@ is unnecessary. | test.cpp:277:8:277:12 | ! ... | This check |
|
||||
|
||||
@@ -136,6 +136,8 @@ void good_new_handles_nullptr() {
|
||||
return; // GOOD
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
void* operator new(std::size_t count, void*) noexcept;
|
||||
void* operator new[](std::size_t count, void*) noexcept;
|
||||
|
||||
@@ -146,18 +148,46 @@ struct Foo {
|
||||
operator bool();
|
||||
};
|
||||
|
||||
struct Bar {
|
||||
Bar();
|
||||
|
||||
operator bool();
|
||||
};
|
||||
|
||||
void bad_placement_new_with_exception_handling() {
|
||||
char buffer[1024];
|
||||
try { new (buffer) Foo; } // BAD
|
||||
|
||||
try { new (buffer) Foo; } // BAD (placement new should not fail)
|
||||
catch (...) { }
|
||||
}
|
||||
|
||||
void good_placement_new_with_exception_handling() {
|
||||
char buffer[1024];
|
||||
|
||||
try { new (buffer) Foo(42); } // GOOD: Foo constructor might throw
|
||||
catch (...) { }
|
||||
|
||||
try { new (buffer) Bar; } // GOOD: Bar constructor might throw
|
||||
catch (...) { }
|
||||
}
|
||||
|
||||
template<typename F> F *test_template_platement_new() {
|
||||
char buffer[1024];
|
||||
|
||||
try {
|
||||
return new (buffer) F; // GOOD: `F` constructor might throw (when `F` is `Bar`)
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void test_template_platement_new_caller() {
|
||||
test_template_platement_new<Foo>();
|
||||
test_template_platement_new<Bar>();
|
||||
}
|
||||
|
||||
// ---
|
||||
|
||||
int unknown_value_without_exceptions() noexcept;
|
||||
|
||||
void may_throw() {
|
||||
|
||||
Reference in New Issue
Block a user