Skip to content

Commit 446ebfe

Browse files
committed
A8-4-13: Fix compiler compatibility FPs
Fix false positives identified by compiler compatibility testing on gcc/clang, which identified that shared_ptr used a hidden base class in real compilers causing our detection of modifying function calls to fail. This has been addressed, with a bonus modification to more accurately represent which pointer/reference types are captured.
1 parent 769ece5 commit 446ebfe

File tree

3 files changed

+30
-18
lines changed

3 files changed

+30
-18
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- `A8-4-13` - reduce false positives when using gcc/clang where a modifying operation was used on a shared_ptr.

cpp/autosar/src/rules/A8-4-13/SharedPtrPassedToFunctionWithImproperSemantics.ql

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@ import cpp
1919
import codingstandards.cpp.autosar
2020
import codingstandards.cpp.SmartPointers
2121

22+
class AutosarSharedPointerOrDerived extends Type {
23+
AutosarSharedPointerOrDerived() {
24+
this.getUnspecifiedType() instanceof AutosarSharedPointer or
25+
this.getUnspecifiedType().(DerivedType).getBaseType() instanceof AutosarSharedPointer
26+
}
27+
}
28+
2229
Expr underlyingObjectAffectingSharedPointerExpr(Function f) {
2330
result =
2431
any(VariableAccess va, FunctionCall fc |
2532
va.getEnclosingFunction() = f and
26-
// strip the type so as to include reference parameter types
27-
va.getType().stripType() instanceof AutosarSharedPointer and
28-
fc.getTarget().getDeclaringType().stripType() instanceof AutosarSharedPointer and
33+
// The type of the variable is either a shared_ptr, or a reference or pointer to a shared_ptr
34+
va.getType() instanceof AutosarSharedPointerOrDerived and
2935
fc.getQualifier() = va and
3036
// include only calls to methods which modify the underlying object
3137
fc.getTarget().hasName(["operator=", "reset", "swap"])
@@ -36,7 +42,7 @@ Expr underlyingObjectAffectingSharedPointerExpr(Function f) {
3642

3743
predicate flowsToUnderlyingObjectAffectingExpr(Parameter p) {
3844
// check if a parameter flows locally to an expression which affects smart pointer lifetime
39-
p.getType().stripType() instanceof AutosarSharedPointer and
45+
p.getType() instanceof AutosarSharedPointerOrDerived and
4046
localExprFlow(p.getAnAccess(), underlyingObjectAffectingSharedPointerExpr(p.getFunction()))
4147
or
4248
// else handle nested cases, such as passing smart pointers as reference arguments
@@ -54,7 +60,7 @@ predicate flowsToUnderlyingObjectAffectingExpr(Parameter p) {
5460
from DefinedSmartPointerParameter p, string problem
5561
where
5662
not isExcluded(p, SmartPointers1Package::smartPointerAsParameterWithoutLifetimeSemanticsQuery()) and
57-
p.getType().stripType() instanceof AutosarSharedPointer and
63+
p.getType() instanceof AutosarSharedPointerOrDerived and
5864
(
5965
// handle the parameter depending on its derived type
6066
p.getType() instanceof RValueReferenceType and

cpp/common/test/includes/standard-library/memory.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _GHLIBCPP_MEMORY
22
#define _GHLIBCPP_MEMORY
3-
#include "stddef.h"
43
#include "exception.h"
4+
#include "stddef.h"
55

66
namespace std {
77

@@ -18,6 +18,7 @@ template <typename T> struct default_delete<T[]> {
1818
template <typename T, typename Deleter = std::default_delete<T>>
1919
class unique_ptr {
2020
public:
21+
typedef T *pointer;
2122
unique_ptr() {}
2223
unique_ptr(T *ptr) {}
2324
unique_ptr(const unique_ptr<T> &t) = delete;
@@ -27,9 +28,7 @@ class unique_ptr {
2728
T *operator->() const noexcept { return ptr; }
2829
T *get() const noexcept { return ptr; }
2930
T *release() { return ptr; }
30-
void reset() {}
31-
void reset(T *ptr) {}
32-
void reset(T ptr) {}
31+
void reset(pointer __p = pointer()) {}
3332
T *get() { return ptr; }
3433
unique_ptr<T> &operator=(const unique_ptr &) = delete;
3534
unique_ptr<T> &operator=(unique_ptr &&) { return *this; }
@@ -70,23 +69,29 @@ template <class T, class D> class unique_ptr<T[], D> {
7069
template <class T, class... Args> unique_ptr<T> make_unique(Args &&...args);
7170
template <class T> unique_ptr<T> make_unique(size_t n);
7271

73-
template <typename T> class shared_ptr {
72+
template <typename T> class __shared_ptr {
73+
public:
74+
void reset() noexcept;
75+
template <class Y> void reset(Y *p);
76+
template <class Y, class D> void reset(Y *p, D d);
77+
template <class Y, class D, class A> void reset(Y *p, D d, A a);
78+
};
79+
80+
template <typename T> class shared_ptr : public __shared_ptr<T> {
7481
public:
75-
shared_ptr() {}
76-
shared_ptr(T *ptr) {}
82+
shared_ptr();
83+
shared_ptr(T *ptr);
7784
shared_ptr(const shared_ptr<T> &r) noexcept;
7885
template <class Y> shared_ptr(const shared_ptr<Y> &r) noexcept;
7986
shared_ptr(shared_ptr<T> &&r) noexcept;
8087
template <class Y> shared_ptr(shared_ptr<Y> &&r) noexcept;
8188
shared_ptr(unique_ptr<T> &&t) {}
8289
~shared_ptr() {}
83-
T &operator*() const { return *ptr; }
84-
T *operator->() const noexcept { return ptr; }
85-
void reset() {}
86-
void reset(T *pt) {}
87-
void reset(T pt) {}
90+
T &operator*() const noexcept;
91+
T *operator->() const noexcept;
92+
8893
long use_count() const noexcept { return 0; }
89-
T *get() { return ptr; }
94+
T *get() const noexcept { return ptr; }
9095
shared_ptr<T> &operator=(const shared_ptr &) {}
9196
shared_ptr<T> &operator=(shared_ptr &&) { return *this; }
9297
template <typename S> shared_ptr &operator=(shared_ptr<T> &&) {

0 commit comments

Comments
 (0)