Author: xazax Date: Fri Aug 9 16:03:50 2019 New Revision: 368499 URL: http://llvm.org/viewvc/llvm-project?rev=368499&view=rev Log: Attempt to reapply "Even more warnings utilizing gsl::Owner/gsl::Pointer annotations"
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=368499&r1=368498&r2=368499&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaInit.cpp (original) +++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Aug 9 16:03:50 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 && 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=368499&r1=368498&r2=368499&view=diff ============================================================================== --- cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp (original) +++ cfe/trunk/test/Sema/warn-lifetime-analysis-nocfg.cpp Fri Aug 9 16:03:50 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}} +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits