From: Matthias Gehre Date: Wed, 14 Aug 2019 21:55:57 +0000 (+0000) Subject: [LifetimeAnalysis] Support std::stack::top() and std::optional::value() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=30684d096269a615b16a1e5310f5dba1e06d64bf;p=clang [LifetimeAnalysis] Support std::stack::top() and std::optional::value() Summary: Diagnose dangling pointers that come from std::stack::top() and std::optional::value(). Reviewers: gribozavr Subscribers: cfe-commits, xazax.hun Tags: #clang Differential Revision: https://reviews.llvm.org/D66164 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@368929 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 0811d3fd14..e11cc92e1b 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6610,7 +6610,7 @@ static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) { OO == OverloadedOperatorKind::OO_Star; } return llvm::StringSwitch(Callee->getName()) - .Cases("front", "back", "at", true) + .Cases("front", "back", "at", "top", "value", true) .Default(false); } return false; diff --git a/test/Sema/warn-lifetime-analysis-nocfg.cpp b/test/Sema/warn-lifetime-analysis-nocfg.cpp index ba3cc1fc96..c8016bf55c 100644 --- a/test/Sema/warn-lifetime-analysis-nocfg.cpp +++ b/test/Sema/warn-lifetime-analysis-nocfg.cpp @@ -170,7 +170,15 @@ template struct optional { optional(); optional(const T&); - T &operator*(); + T &operator*() &; + T &&operator*() &&; + T &value() &; + T &&value() &&; +}; + +template +struct stack { + T &top(); }; } @@ -188,6 +196,16 @@ const char *danglingRawPtrFromLocal() { return s.c_str(); // expected-warning {{address of stack memory associated with local variable 's' returned}} } +int &danglingRawPtrFromLocal2() { + std::optional o; + return o.value(); // expected-warning {{reference to stack memory associated with local variable 'o' returned}} +} + +int &danglingRawPtrFromLocal3() { + std::optional o; + return *o; // expected-warning {{reference to stack memory associated with local variable 'o' returned}} +} + const char *danglingRawPtrFromTemp() { return std::basic_string().c_str(); // expected-warning {{returning address of local temporary object}} } @@ -203,9 +221,10 @@ int *danglingUniquePtrFromTemp2() { } void danglingReferenceFromTempOwner() { - int &r = *std::optional(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - int &r2 = *std::optional(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} - int &r3 = std::vector().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r = *std::optional(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r2 = *std::optional(5); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &&r3 = std::optional(5).value(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} + int &r4 = std::vector().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} } std::vector getTempVec();