r368454 - Even more warnings utilizing gsl::Owner/gsl::Pointer annotations
Gabor Horvath via cfe-commits
cfe-commits at lists.llvm.org
Fri Aug 9 10:11:33 PDT 2019
Author: xazax
Date: Fri Aug 9 10:11:32 2019
New Revision: 368454
URL: http://llvm.org/viewvc/llvm-project?rev=368454&view=rev
Log:
Even more warnings utilizing gsl::Owner/gsl::Pointer annotations
Differential Revision: https://reviews.llvm.org/D65127
Modified:
cfe/trunk/lib/Sema/SemaInit.cpp
cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp
Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=368454&r1=368453&r2=368454&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug 9 10:11:32 2019
@@ -6568,19 +6568,33 @@ static bool shouldTrackImplicitObjectArg
if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
return true;
- if (!Callee->getParent()->isInStdNamespace() || !Callee->getIdentifier())
+ if (!Callee->getParent()->isInStdNamespace())
return false;
if (!isRecordWithAttr<PointerAttr>(Callee->getThisObjectType()) &&
!isRecordWithAttr<OwnerAttr>(Callee->getThisObjectType()))
return false;
- if (!isRecordWithAttr<PointerAttr>(Callee->getReturnType()) &&
- !Callee->getReturnType()->isPointerType())
- return false;
- return llvm::StringSwitch<bool>(Callee->getName())
- .Cases("begin", "rbegin", "cbegin", "crbegin", true)
- .Cases("end", "rend", "cend", "crend", true)
- .Cases("c_str", "data", "get", true)
- .Default(false);
+ if (Callee->getReturnType()->isPointerType() ||
+ isRecordWithAttr<PointerAttr>(Callee->getReturnType())) {
+ if (!Callee->getIdentifier())
+ return false;
+ return llvm::StringSwitch<bool>(Callee->getName())
+ .Cases("begin", "rbegin", "cbegin", "crbegin", true)
+ .Cases("end", "rend", "cend", "crend", true)
+ .Cases("c_str", "data", "get", true)
+ // Map and set types.
+ .Cases("find", "equal_range", "lower_bound", "upper_bound", true)
+ .Default(false);
+ } else if (Callee->getReturnType()->isReferenceType()) {
+ if (!Callee->getIdentifier()) {
+ auto OO = Callee->getOverloadedOperator();
+ return OO == OverloadedOperatorKind::OO_Subscript ||
+ OO == OverloadedOperatorKind::OO_Star;
+ }
+ return llvm::StringSwitch<bool>(Callee->getName())
+ .Cases("front", "back", "at", true)
+ .Default(false);
+ }
+ return false;
}
static void handleGslAnnotatedTypes(IndirectLocalPath &Path, Expr *Call,
@@ -6600,6 +6614,12 @@ static void handleGslAnnotatedTypes(Indi
if (MD && shouldTrackImplicitObjectArg(MD))
VisitPointerArg(MD, MCE->getImplicitObjectArgument());
return;
+ } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(Call)) {
+ FunctionDecl *Callee = OCE->getDirectCallee();
+ if (Callee->isCXXInstanceMember() &&
+ shouldTrackImplicitObjectArg(cast<CXXMethodDecl>(Callee)))
+ VisitPointerArg(Callee, OCE->getArg(0));
+ return;
}
if (auto *CCE = dyn_cast<CXXConstructExpr>(Call)) {
Modified: cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp?rev=368454&r1=368453&r2=368454&view=diff
==============================================================================
--- cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp (original)
+++ cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp Fri Aug 9 10:11:32 2019
@@ -121,24 +121,47 @@ void initLocalGslPtrWithTempOwner() {
namespace std {
template <typename T>
-struct basic_iterator {};
+struct basic_iterator {
+ basic_iterator operator++();
+ T& operator*();
+};
+
+template<typename T>
+bool operator!=(basic_iterator<T>, basic_iterator<T>);
template <typename T>
struct vector {
typedef basic_iterator<T> iterator;
iterator begin();
+ iterator end();
T *data();
+ T &at(int n);
+};
+
+template<typename T>
+struct basic_string_view {
+ basic_string_view(const T *);
+ const T *begin() const;
};
template<typename T>
struct basic_string {
const T *c_str() const;
+ operator basic_string_view<T> () const;
};
+
template<typename T>
struct unique_ptr {
T *get() const;
};
+
+template<typename T>
+struct optional {
+ optional();
+ optional(const T&);
+ T &operator*();
+};
}
void modelIterators() {
@@ -168,3 +191,29 @@ int *danglingUniquePtrFromTemp() {
int *danglingUniquePtrFromTemp2() {
return std::unique_ptr<int>().get(); // expected-warning {{returning address of local temporary object}}
}
+
+void danglingReferenceFromTempOwner() {
+ int &r = *std::optional<int>(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
+ int &r2 = *std::optional<int>(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
+ int &r3 = std::vector<int>().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
+}
+
+std::vector<int> getTempVec();
+std::optional<std::vector<int>> getTempOptVec();
+
+int &usedToBeFalsePositive(std::vector<int> &v) {
+ std::vector<int>::iterator it = v.begin();
+ int& value = *it;
+ return value; // ok
+}
+
+int &doNotFollowReferencesForLocalOwner() {
+ std::unique_ptr<int> localOwner;
+ int &p = *localOwner.get();
+ // In real world code localOwner is usually moved here.
+ return p; // ok
+}
+
+const char *trackThroughMultiplePointer() {
+ return std::basic_string_view<char>(std::basic_string<char>()).begin(); // expected-warning {{returning address of local temporary object}}
+}
More information about the cfe-commits
mailing list