|
16 | 16 | #include "clang/AST/ExprObjC.h"
|
17 | 17 | #include "clang/AST/ExprOpenMP.h"
|
18 | 18 | #include "clang/AST/TypeLoc.h"
|
| 19 | +#include "clang/Basic/CharInfo.h" |
19 | 20 | #include "clang/Basic/TargetInfo.h"
|
20 | 21 | #include "clang/Sema/Designator.h"
|
21 | 22 | #include "clang/Sema/Initialization.h"
|
@@ -6564,11 +6565,29 @@ template <typename T> static bool isRecordWithAttr(QualType Type) {
|
6564 | 6565 | return false;
|
6565 | 6566 | }
|
6566 | 6567 |
|
| 6568 | +// Decl::isInStdNamespace will return false for iterators in some STL |
| 6569 | +// implementations due to them being defined in a namespace outside of the std |
| 6570 | +// namespace. |
| 6571 | +static bool isInStlNamespace(const Decl *D) { |
| 6572 | + const DeclContext *DC = D->getDeclContext(); |
| 6573 | + if (!DC) |
| 6574 | + return false; |
| 6575 | + if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) |
| 6576 | + if (const IdentifierInfo *II = ND->getIdentifier()) { |
| 6577 | + StringRef Name = II->getName(); |
| 6578 | + if (Name.size() >= 2 && Name.front() == '_' && |
| 6579 | + (Name[1] == '_' || isUppercase(Name[1]))) |
| 6580 | + return true; |
| 6581 | + } |
| 6582 | + |
| 6583 | + return DC->isStdNamespace(); |
| 6584 | +} |
| 6585 | + |
6567 | 6586 | static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
|
6568 | 6587 | if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
|
6569 | 6588 | if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
|
6570 | 6589 | return true;
|
6571 |
| - if (!Callee->getParent()->isInStdNamespace()) |
| 6590 | + if (!isInStlNamespace(Callee->getParent())) |
6572 | 6591 | return false;
|
6573 | 6592 | if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) &&
|
6574 | 6593 | !isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType()))
|
@@ -7107,25 +7126,29 @@ void Sema::checkInitializerLifetime(const InitializedEntity &Entity,
|
7107 | 7126 | SourceLocation DiagLoc = DiagRange.getBegin();
|
7108 | 7127 |
|
7109 | 7128 | auto *MTE = dyn_cast<MaterializeTemporaryExpr>(L);
|
7110 |
| - bool IsTempGslOwner = MTE && !MTE->getExtendingDecl() && |
7111 |
| - isRecordWithAttr<OwnerAttr>(MTE->getType()); |
7112 |
| - bool IsLocalGslOwner = |
7113 |
| - isa<DeclRefExpr>(L) && isRecordWithAttr<OwnerAttr>(L->getType()); |
7114 |
| - |
7115 |
| - // Skipping a chain of initializing gsl::Pointer annotated objects. |
7116 |
| - // We are looking only for the final source to find out if it was |
7117 |
| - // a local or temporary owner or the address of a local variable/param. We |
7118 |
| - // do not want to follow the references when returning a pointer originating |
7119 |
| - // from a local owner to avoid the following false positive: |
7120 |
| - // int &p = *localUniquePtr; |
7121 |
| - // someContainer.add(std::move(localUniquePtr)); |
7122 |
| - // return p; |
7123 |
| - if (!IsTempGslOwner && pathOnlyInitializesGslPointer(Path) && |
7124 |
| - !(IsLocalGslOwner && !pathContainsInit(Path))) |
7125 |
| - return true; |
7126 | 7129 |
|
7127 |
| - bool IsGslPtrInitWithGslTempOwner = |
7128 |
| - IsTempGslOwner && pathOnlyInitializesGslPointer(Path); |
| 7130 | + bool IsGslPtrInitWithGslTempOwner = false; |
| 7131 | + bool IsLocalGslOwner = false; |
| 7132 | + if (pathOnlyInitializesGslPointer(Path)) { |
| 7133 | + if (isa<DeclRefExpr>(L)) { |
| 7134 | + // We do not want to follow the references when returning a pointer originating |
| 7135 | + // from a local owner to avoid the following false positive: |
| 7136 | + // int &p = *localUniquePtr; |
| 7137 | + // someContainer.add(std::move(localUniquePtr)); |
| 7138 | + // return p; |
| 7139 | + IsLocalGslOwner = isRecordWithAttr<OwnerAttr>(L->getType()); |
| 7140 | + if (pathContainsInit(Path) || !IsLocalGslOwner) |
| 7141 | + return false; |
| 7142 | + } else { |
| 7143 | + IsGslPtrInitWithGslTempOwner = MTE && !MTE->getExtendingDecl() && |
| 7144 | + isRecordWithAttr<OwnerAttr>(MTE->getType()); |
| 7145 | + // Skipping a chain of initializing gsl::Pointer annotated objects. |
| 7146 | + // We are looking only for the final source to find out if it was |
| 7147 | + // a local or temporary owner or the address of a local variable/param. |
| 7148 | + if (!IsGslPtrInitWithGslTempOwner) |
| 7149 | + return true; |
| 7150 | + } |
| 7151 | + } |
7129 | 7152 |
|
7130 | 7153 | switch (LK) {
|
7131 | 7154 | case LK_FullExpression:
|
|
0 commit comments