// RUN: %clang_cc1 -fsyntax-only -Wdangling -Wdangling-field -Wreturn-stack-address -verify %s
// RUN: %clang_cc1 -fsyntax-only -Wlifetime-safety -Wno-dangling -verify=cfg %s
// RUN: %clang_cc1 -fsyntax-only -flifetime-safety-inference -fexperimental-lifetime-safety-tu-analysis -Wlifetime-safety -Wno-dangling -verify=cfg,tu %s

#include "Inputs/lifetime-analysis.h"

struct [[gsl::Owner(int)]] MyIntOwner {
  MyIntOwner();
  // TODO: Do this behind a macro and run tests without this dtor to verify trivial dtor cases.
  ~MyIntOwner();
  int &operator*();
};

struct [[gsl::Pointer(int)]] MyIntPointer {
  MyIntPointer(int *p = nullptr);
  // Conversion operator and constructor conversion will result in two
  // different ASTs. The former is tested with another owner and
  // pointer type.
  MyIntPointer(const MyIntOwner &);
  int &operator*();
  MyIntOwner toOwner();
};

struct MySpecialIntPointer : MyIntPointer {
};

// We did see examples in the wild when a derived class changes
// the ownership model. So we have a test for it.
struct [[gsl::Owner(int)]] MyOwnerIntPointer : MyIntPointer {
};

struct [[gsl::Pointer(long)]] MyLongPointerFromConversion {
  MyLongPointerFromConversion(long *p = nullptr);
  long &operator*();
};

struct [[gsl::Owner(long)]] MyLongOwnerWithConversion {
  MyLongOwnerWithConversion();
  // TODO: Do this behind a macro and run tests without this dtor to verify trivial dtor cases.
  ~MyLongOwnerWithConversion();
  operator MyLongPointerFromConversion();
  long &operator*();
  MyIntPointer releaseAsMyPointer();
  long *releaseAsRawPointer();
};

template<class... T> void use(T... arg);

void danglingHeapObject() {
  new MyLongPointerFromConversion(MyLongOwnerWithConversion{}); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
  new MyIntPointer(MyIntOwner{}); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
}

void intentionalFalseNegative() {
  int i;
  MyIntPointer p{&i};
  // In this case we do not have enough information in a statement local
  // analysis to detect the problem.
  new MyIntPointer(p);
  new MyIntPointer(MyIntPointer{p});
}

MyIntPointer ownershipTransferToMyPointer() {
  MyLongOwnerWithConversion t;
  return t.releaseAsMyPointer(); // ok
}

long *ownershipTransferToRawPointer() {
  MyLongOwnerWithConversion t;
  return t.releaseAsRawPointer(); // ok
}

struct Y {
  int a[4];
};

void dangligGslPtrFromTemporary() {
  MyIntPointer p = Y{}.a; // cfg-warning {{object whose reference is captured does not live long enough}} \
                          // cfg-note {{destroyed here}}
  (void)p;                // cfg-note {{later used here}}
}

struct DanglingGslPtrField {
  MyIntPointer p; // expected-note {{pointer member declared here}} \
                  // cfg-note 3 {{this field dangles}}
  MyLongPointerFromConversion p2; // expected-note {{pointer member declared here}} \
                                  // cfg-note 2 {{this field dangles}}

  DanglingGslPtrField(int i) : p(&i) {} // cfg-warning {{address of stack memory escapes to a field}}
  DanglingGslPtrField() : p2(MyLongOwnerWithConversion{}) {}  // expected-warning {{initializing pointer member 'p2' to point to a temporary object whose lifetime is shorter than the lifetime of the constructed object}} \
                                                              // cfg-warning {{address of stack memory escapes to a field}}
  DanglingGslPtrField(double) : p(MyIntOwner{}) {}  // expected-warning {{initializing pointer member 'p' to point to a temporary object whose lifetime is shorter than the lifetime of the constructed object}} \
                                                    // cfg-warning {{address of stack memory escapes to a field}}
  DanglingGslPtrField(MyIntOwner io) : p(io) {} // cfg-warning {{address of stack memory escapes to a field}}
  DanglingGslPtrField(MyLongOwnerWithConversion lo) : p2(lo) {} // cfg-warning {{address of stack memory escapes to a field}}
};

MyIntPointer danglingGslPtrFromLocal() {
  int j;
  // Detected only by CFG analysis.
  return &j; // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

MyIntPointer returningLocalPointer() {
  MyIntPointer localPointer;
  return localPointer; // ok
}

MyIntPointer daglingGslPtrFromLocalOwner() {
  MyIntOwner localOwner;
  return localOwner; // expected-warning {{address of stack memory associated with local variable 'localOwner' returned}} \
                     // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

MyLongPointerFromConversion daglingGslPtrFromLocalOwnerConv() {
  MyLongOwnerWithConversion localOwner;
  return localOwner; // expected-warning {{address of stack memory associated with local variable 'localOwner' returned}} \
                     // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

MyIntPointer danglingGslPtrFromTemporary() {
  return MyIntOwner{}; // expected-warning {{returning address of local temporary object}} \
                       // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

MyIntOwner makeTempOwner();

MyIntPointer danglingGslPtrFromTemporary2() {
  return makeTempOwner(); // expected-warning {{returning address of local temporary object}} \
                          // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

MyLongPointerFromConversion danglingGslPtrFromTemporaryConv() {
  return MyLongOwnerWithConversion{}; // expected-warning {{returning address of local temporary object}} \
                                      // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int *noFalsePositive(MyIntOwner &o) {
  MyIntPointer p = o;
  return &*p; // ok
}

MyIntPointer global;
MyLongPointerFromConversion global2;

void initLocalGslPtrWithTempOwner() {
  MyIntPointer p = MyIntOwner{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                 // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p);                        // cfg-note {{later used here}}

  MyIntPointer pp = p = MyIntOwner{}; // expected-warning {{object backing the pointer 'p' will be}} \
                                      // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p, pp);                         // cfg-note {{later used here}}

  p = MyIntOwner{}; // expected-warning {{object backing the pointer 'p' }} \
                    // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p);           // cfg-note {{later used here}}

  pp = p; // no warning
  use(p, pp);

  global = MyIntOwner{}; // expected-warning {{object backing the pointer 'global' }} \
                         // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(global);           // cfg-note {{later used here}}

  MyLongPointerFromConversion p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                                                // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p2);                                                      // cfg-note {{later used here}}

  p2 = MyLongOwnerWithConversion{}; // expected-warning {{object backing the pointer 'p2' }} \
                                    // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  global2 = MyLongOwnerWithConversion{};  // expected-warning {{object backing the pointer 'global2' }} \
                                          // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(global2, p2);                       // cfg-note 2 {{later used here}}
}

struct LifetimeBoundCtor {
  LifetimeBoundCtor(const MyIntOwner& obj1 [[clang::lifetimebound]]);
  LifetimeBoundCtor(std::string_view sv [[clang::lifetimebound]]);
};

auto lifetimebound_make_unique_single_param() {
  return std::make_unique<LifetimeBoundCtor>(MyIntOwner{}); // tu-warning {{address of stack memory is returned later}} tu-note {{returned here}}
}



struct Unannotated {
  typedef std::vector<int>::iterator iterator;
  iterator begin();
  operator iterator() const;
};

void modelIterators() {
  std::vector<int>::iterator it = std::vector<int>().begin(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                                              // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  (void)it; // cfg-note {{later used here}}
}

std::vector<int>::iterator modelIteratorReturn() {
  return std::vector<int>().begin(); // expected-warning {{returning address of local temporary object}} \
                                     // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

const int *modelFreeFunctions() {
  return std::data(std::vector<int>()); // expected-warning {{returning address of local temporary object}} \
                                        // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int &modelAnyCast() {
  return std::any_cast<int&>(std::any{}); // expected-warning {{returning reference to local temporary object}} \
                                          // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int modelAnyCast2() {
  return std::any_cast<int>(std::any{}); // ok
}

int modelAnyCast3() {
  return std::any_cast<int&>(std::any{}); // ok
}

const char *danglingRawPtrFromLocal() {
  std::basic_string<char> s;
  return s.c_str(); // expected-warning {{address of stack memory associated with local variable 's' returned}} \
                    // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int &danglingRawPtrFromLocal2() {
  std::optional<int> o;
  return o.value(); // expected-warning {{reference to stack memory associated with local variable 'o' returned}} \
                    // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int &danglingRawPtrFromLocal3() {
  std::optional<int> o;
  return *o; // expected-warning {{reference to stack memory associated with local variable 'o' returned}} \
             // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

// GH100384
std::string_view containerWithAnnotatedElements() {
  std::string_view c1 = std::vector<std::string>().at(0); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                                          // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(c1);                                                // cfg-note {{later used here}}

  c1 = std::vector<std::string>().at(0); // expected-warning {{object backing the pointer}} \
                                         // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(c1);                               // cfg-note {{later used here}}

  // no warning on constructing from gsl-pointer
  std::string_view c2 = std::vector<std::string_view>().at(0);
  use(c2);

  std::vector<std::string> local;
  return local.at(0); // expected-warning {{address of stack memory associated with local variable}} \
                      // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::string_view localUniquePtr(int i) {
  std::unique_ptr<std::string> c1;
  if (i)
    return *c1; // expected-warning {{address of stack memory associated with local variable}} \
                // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
  std::unique_ptr<std::string_view> c2;
  return *c2; // expect no-warning.
}

std::string_view localOptional(int i) {
  std::optional<std::string> o;
  if (i)
    return o.value(); // expected-warning {{address of stack memory associated with local variable}} \
                      // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
  std::optional<std::string_view> abc;
  return abc.value(); // expect no warning
}

const char *danglingRawPtrFromTemp() {
  return std::basic_string<char>().c_str(); // expected-warning {{returning address of local temporary object}} \
                                            // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::unique_ptr<int> getUniquePtr();

int *danglingUniquePtrFromTemp() {
  return getUniquePtr().get(); // expected-warning {{returning address of local temporary object}} \
                               // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

int *danglingUniquePtrFromTemp2() {
  return std::unique_ptr<int>().get(); // expected-warning {{returning address of local temporary object}} \
                                       // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

const int& danglingRefToOptionalFromTemp3() {
  return std::optional<int>().value(); // expected-warning {{returning reference to local temporary object}} \
                                       // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::optional<std::string> getTempOptStr();

std::string_view danglingRefToOptionalFromTemp4() {
  return getTempOptStr().value(); // expected-warning {{returning address of local temporary object}} \
                                  // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

void danglingReferenceFromTempOwner() {
  int &&r = *std::optional<int>();          // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  // https://github.com/llvm/llvm-project/issues/175893
  int &&r2 = *std::optional<int>(5);        // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                              // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  // https://github.com/llvm/llvm-project/issues/175893
  int &&r3 = std::optional<int>(5).value(); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                              // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  const int &r4 = std::vector<int>().at(3); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  int &&r5 = std::vector<int>().at(3);      // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(r, r2, r3, r4, r5);                   // cfg-note 5 {{later used here}}

  std::string_view sv = *getTempOptStr();  // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                           // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(sv);                                 // cfg-note {{later used here}}
}

std::vector<int> getTempVec();
std::optional<std::vector<int>> getTempOptVec();

void testLoops() {
  for (auto i : getTempVec()) // ok
    ;
  for (auto i : *getTempOptVec()) // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}} cfg-note {{later used here}}
    ;
}

int &usedToBeFalsePositive(std::vector<int> &v) {
  std::vector<int>::iterator it = v.begin();
  int& value = *it;
  return value; // ok
}

int &doNotFollowReferencesForLocalOwner() {
// Warning caught by CFG analysis.
  std::unique_ptr<int> localOwner;
  int &p = *localOwner // cfg-warning {{address of stack memory is returned later}}
            .get();
  return p; // cfg-note {{returned here}}
}

const char *trackThroughMultiplePointer() {
  return std::basic_string_view<char>(std::basic_string<char>()).begin(); // expected-warning {{returning address of local temporary object}} \
         // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

struct X {
  X(std::unique_ptr<int> up) :
    pointee(*up),             // cfg-warning {{may have been moved.}}
    pointee2(up.get()),       // cfg-warning {{may have been moved.}}
    pointer(std::move(up)) {} // cfg-note 2 {{potentially moved here}}
  int &pointee;               // cfg-note {{this field dangles}}
  int *pointee2;              // cfg-note {{this field dangles}}
  std::unique_ptr<int> pointer;
};

struct [[gsl::Owner]] XOwner {
  int* get() const [[clang::lifetimebound]];
};
struct X2 {
  // A common usage that moves the passing owner to the class.
  // verify a strict warning on this case.
  X2(XOwner owner) :
    pointee(owner.get()),       // cfg-warning {{may have been moved.}}
    owner(std::move(owner)) {}  // cfg-note {{potentially moved here}}
  int* pointee;                 // cfg-note {{this field dangles}}
  XOwner owner;
};

std::vector<int>::iterator getIt();
std::vector<int> getVec();

const int &handleGslPtrInitsThroughReference() {
  const auto &it = getIt(); // Ok, it is lifetime extended.
  return *it;
}

void handleGslPtrInitsThroughReference2() {
  const std::vector<int> &v = getVec();
  const int *val = v.data(); // Ok, it is lifetime extended.
}

void handleTernaryOperator(bool cond) {
    std::basic_string<char> def;
    std::basic_string_view<char> v = cond ? def : ""; // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                                      // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
    use(v); // cfg-note {{later used here}}
}

std::string operator+(std::string_view s1, std::string_view s2);
void danglingStringviewAssignment(std::string_view a1, std::string_view a2) {
  a1 = std::string(); // expected-warning {{object backing}} \
                      // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(a1);            // cfg-note {{later used here}}

  a2 = a1 + a1; // expected-warning {{object backing}} \
                // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(a2);      // cfg-note {{later used here}}
}

std::reference_wrapper<int> danglingPtrFromNonOwnerLocal() {
  int i = 5;
  return i; // TODO
}

std::reference_wrapper<int> danglingPtrFromNonOwnerLocal2() {
  int i = 5;
  return std::ref(i); // TODO
}

std::reference_wrapper<int> danglingPtrFromNonOwnerLocal3() {
  int i = 5;
  return std::reference_wrapper<int>(i); // TODO
}

std::reference_wrapper<Unannotated> danglingPtrFromNonOwnerLocal4() {
  Unannotated i;
  return std::reference_wrapper<Unannotated>(i); // TODO
}

std::reference_wrapper<Unannotated> danglingPtrFromNonOwnerLocal5() {
  Unannotated i;
  return std::ref(i); // TODO
}

int *returnPtrToLocalArray() {
  int a[5];
  return std::begin(a); // TODO
}

namespace lifetimebound_stl_algorithms {

std::vector<std::string> GetTemporaryString();
std::vector<std::string_view> GetTemporaryView();

std::string_view test_str_local() {
  std::vector<std::string> v;
  return *std::find(v.begin(), // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
                    v.end(), "42");
}
std::string_view test_str_temporary() {
  return *std::find(GetTemporaryString().begin(), // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
                    GetTemporaryString().end(), "42");
}
std::string_view test_view() {
  std::vector<std::string_view> v;
  return *std::find(v.begin(), v.end(), "42");
}
std::string_view test_view_local() {
  return *std::find(GetTemporaryView().begin(), GetTemporaryView().end(), "42");
}
} // namespace lifetimebound_stl_algorithms

struct ptr_wrapper {
  std::vector<int>::iterator member;
};

ptr_wrapper getPtrWrapper();

std::vector<int>::iterator returnPtrFromWrapper() {
  ptr_wrapper local = getPtrWrapper();
  return local.member;
}

std::vector<int>::iterator returnPtrFromWrapperThroughRef() {
  ptr_wrapper local = getPtrWrapper();
  ptr_wrapper &local2 = local;
  return local2.member;
}

std::vector<int>::iterator returnPtrFromWrapperThroughRef2() {
  ptr_wrapper local = getPtrWrapper();
  std::vector<int>::iterator &local2 = local.member;
  return local2;
}

void checkPtrMemberFromAggregate() {
  std::vector<int>::iterator local = getPtrWrapper().member; // OK.
}

std::vector<int>::iterator doNotInterferWithUnannotated() {
  Unannotated value;
  // Conservative choice for now. Probably not ok, but we do not warn.
  return std::begin(value);
}

std::vector<int>::iterator doNotInterferWithUnannotated2() {
  Unannotated value;
  return value;
}

std::vector<int>::iterator supportDerefAddrofChain(int a, std::vector<int>::iterator value) {
  switch (a)  {
    default:
      return value;
    case 1:
      return *&value;
    case 2:
      return *&*&value;
    case 3:
      return *&*&*&value;
  }
}

int &supportDerefAddrofChain2(int a, std::vector<int>::iterator value) {
  switch (a)  {
    default:
      return *value;
    case 1:
      return **&value;
    case 2:
      return **&*&value;
    case 3:
      return **&*&*&value;
  }
}

int *supportDerefAddrofChain3(int a, std::vector<int>::iterator value) {
  switch (a)  {
    default:
      return &*value;
    case 1:
      return &*&*value;
    case 2:
      return &*&**&value;
    case 3:
      return &*&**&*&value;
  }
}

MyIntPointer handleDerivedToBaseCast1(MySpecialIntPointer ptr) {
  return ptr;
}

MyIntPointer handleDerivedToBaseCast2(MyOwnerIntPointer ptr) {
  return ptr; // expected-warning {{address of stack memory associated with parameter 'ptr' returned}}
}

std::vector<int>::iterator noFalsePositiveWithVectorOfPointers() {
  std::vector<std::vector<int>::iterator> iters;
  return iters.at(0);
}

void testForBug49342()
{
  auto it = std::iter<char>{} - 2; // Used to be false positive.
}

namespace GH93386 {
// verify no duplicated diagnostics are emitted.
struct [[gsl::Pointer]] S {
  S(const std::vector<int>& abc [[clang::lifetimebound]]);
};

S test(std::vector<int> a) {
  return S(a);  // expected-warning {{address of stack memory associated with}} \
                // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

// FIXME: Detect this using the CFG-based lifetime analysis (global initialisation).
auto s = S(std::vector<int>()); // expected-warning {{temporary whose address is used as value of local variable}}

// Verify no regression on the follow case.
std::string_view test2(int i, std::optional<std::string_view> a) {
  if (i)
    return std::move(*a);
  return std::move(a.value());
}

struct Foo;
struct FooView {
  FooView(const Foo& foo [[clang::lifetimebound]]);
};
FooView test3(int i, std::optional<Foo> a) {
  if (i)
    return *a; // expected-warning {{address of stack memory}} \
               // cfg-warning {{address of stack memory is returned later}} \
               // cfg-note {{returned here}}
  return a.value(); // expected-warning {{address of stack memory}} \
                    // cfg-warning {{address of stack memory is returned later}} \
                    // cfg-note {{returned here}}
}
} // namespace GH93386

namespace GH100549 {
struct UrlAnalyzed {
  UrlAnalyzed(std::string_view url [[clang::lifetimebound]]);
};
std::string StrCat(std::string_view, std::string_view);
void test1() {
  UrlAnalyzed url(StrCat("abc", "bcd")); // expected-warning {{object backing the pointer will be destroyed}} \
                                         // cfg-warning {{object whose reference is captured does not live long enough}} \
                                         // cfg-note {{destroyed here}}
  use(url);                              // cfg-note {{later used here}}
}

std::string_view ReturnStringView(std::string_view abc [[clang::lifetimebound]]);

void test() {
  std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}} \
                                                                  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(svjkk1);                                                    // cfg-note {{later used here}}
}
} // namespace GH100549

namespace GH108272 {
template <typename T>
struct [[gsl::Owner]] StatusOr {
  const T &value() [[clang::lifetimebound]];
  // TODO: Do this behind a macro and run tests without this dtor to verify trivial dtor cases.
  ~StatusOr();
};

template <typename V>
class Wrapper1 {
 public:
  operator V() const;
  V value;
};
std::string_view test1() {
  StatusOr<Wrapper1<std::string_view>> k;
  // Be conservative in this case, as there is not enough information available
  // to infer the lifetime relationship for the Wrapper1 type.
  std::string_view good = StatusOr<Wrapper1<std::string_view>>().value();
  return k.value();
}

template <typename V>
class Wrapper2 {
 public:
  operator V() const [[clang::lifetimebound]];
  V value;
};
std::string_view test2() {
  StatusOr<Wrapper2<std::string_view>> k;
  // We expect dangling issues as the conversion operator is lifetimebound。
  std::string_view bad = StatusOr<Wrapper2<std::string_view>>().value(); // expected-warning {{temporary whose address is used as value of}}
  
  return k.value(); // expected-warning {{address of stack memory associated}} \
                    // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}
} // namespace GH108272

namespace GH100526 {
// FIXME: Detect this using the CFG-based lifetime analysis.
//        Container of pointers
//        https://github.com/llvm/llvm-project/issues/175025
void test() {
  std::vector<std::string_view> v1({std::string()}); // expected-warning {{object backing the pointer will be destroyed at the end}}
  use(v1);

  std::vector<std::string_view> v2({
    std::string(), // expected-warning {{object backing the pointer will be destroyed at the end}}
    std::string_view()
  });
  use(v2);

  std::vector<std::string_view> v3({
    std::string_view(),
    std::string()  // expected-warning {{object backing the pointer will be destroyed at the end}}
  });
  use(v3);

  std::optional<std::string_view> o1 = std::string(); // expected-warning {{object backing the pointer}}
  use(o1);

  std::string s;
  // This is a tricky use-after-free case, what it does:
  //   1. make_optional creates a temporary "optional<string>"" object
  //   2. the temporary object owns the underlying string which is copied from s.
  //   3. the t3 object holds the view to the underlying string of the temporary object.
  std::optional<std::string_view> o2 = std::make_optional(s); // expected-warning {{object backing the pointer}}
  std::optional<std::string_view> o3 = std::optional<std::string>(s); // expected-warning {{object backing the pointer}}
  std::optional<std::string_view> o4 = std::optional<std::string_view>(s);
  use(o2, o3, o4);

  // FIXME: should work for assignment cases
  v1 = {std::string()};
  o1 = std::string();
  use(o1, v1);

  // no warning on copying pointers.
  std::vector<std::string_view> n1 = {std::string_view()};
  std::optional<std::string_view> n2 = {std::string_view()};
  std::optional<std::string_view> n3 = std::string_view();
  std::optional<std::string_view> n4 = std::make_optional(std::string_view());
  const char* b = "";
  std::optional<std::string_view> n5 = std::make_optional(b);
  std::optional<std::string_view> n6 = std::make_optional("test");
  use(n1, n2, n3, n4, n5, n6);
}

std::vector<std::string_view> test2(int i) {
  std::vector<std::string_view> t;
  if (i)
    return t; // this is fine, no dangling
  return std::vector<std::string_view>(t.begin(), t.end());
}

class Foo {
  public:
   operator std::string_view() const { return ""; }
};
class [[gsl::Owner]] FooOwner {
  public:
   operator std::string_view() const { return ""; }
};
std::optional<Foo> GetFoo();
std::optional<FooOwner> GetFooOwner();

template <typename T>
struct [[gsl::Owner]] Container1 {
   Container1();
};
template <typename T>
struct [[gsl::Owner]] Container2 {
  template<typename U>
  Container2(const Container1<U>& C2);
};

std::optional<std::string_view> test3(int i) {
  std::string s;
  std::string_view sv;
  if (i)
   return s; // expected-warning {{address of stack memory associated}}
  return sv; // fine
  Container2<std::string_view> c1 = Container1<Foo>(); // no diagnostic as Foo is not an Owner.
  Container2<std::string_view> c2 = Container1<FooOwner>(); // expected-warning {{object backing the pointer will be destroyed}}
  return GetFoo(); // fine, we don't know Foo is owner or not, be conservative.
  return GetFooOwner(); // expected-warning {{returning address of local temporary object}}
}

std::optional<int*> test4(int a) {
  return std::make_optional(nullptr); // fine
}


template <typename T>
struct [[gsl::Owner]] StatusOr {
  const T &valueLB() const [[clang::lifetimebound]];
  const T &valueNoLB() const;
};

template<typename T>
struct [[gsl::Pointer]] Span {
  Span(const std::vector<T> &V);

  const int& getFieldLB() const [[clang::lifetimebound]];
  const int& getFieldNoLB() const;
};


/////// From Owner<Pointer> ///////

// Pointer from Owner<Pointer>
std::string_view test5() {
  // The Owner<Pointer> doesn't own the object which its inner pointer points to.
  std::string_view a = StatusOr<std::string_view>().valueLB(); // OK
  return StatusOr<std::string_view>().valueLB(); // OK

  // No dangling diagnostics on non-lifetimebound methods.
  std::string_view b = StatusOr<std::string_view>().valueNoLB();
  return StatusOr<std::string_view>().valueNoLB();
}

// Pointer<Pointer> from Owner<Pointer>
// Prevent regression GH108463
Span<int*> test6(std::vector<int*> v) {
  Span<int *> dangling = std::vector<int*>(); // expected-warning {{object backing the pointer}}
  dangling = std::vector<int*>(); // expected-warning {{object backing the pointer}}
  return v; // expected-warning {{address of stack memory}} \
            // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

/////// From Owner<Owner<Pointer>> ///////

// Pointer from Owner<Owner<Pointer>>
int* test7(StatusOr<StatusOr<int*>> aa) {
  // No dangling diagnostic on pointer.
  return aa.valueLB().valueLB(); // OK.
}

// Owner<Pointer> from Owner<Owner<Pointer>>
std::vector<int*> test8(StatusOr<std::vector<int*>> aa) {
  return aa.valueLB(); // OK, no pointer being construct on this case.
  return aa.valueNoLB();
}

// Pointer<Pointer> from Owner<Owner<Pointer>>
Span<int*> test9(StatusOr<std::vector<int*>> aa) {
  return aa.valueLB(); // expected-warning {{address of stack memory associated}} \
                       // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
  return aa.valueNoLB(); // OK.
}

/////// From Owner<Owner> ///////

// Pointer<Owner>> from Owner<Owner>
Span<std::string> test10(StatusOr<std::vector<std::string>> aa) {
  return aa.valueLB(); // expected-warning {{address of stack memory}} \
                       // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
  return aa.valueNoLB(); // OK.
}

/////// From Owner<Pointer<Owner>> ///////

// Pointer<Owner>> from Owner<Pointer<Owner>>
Span<std::string> test11(StatusOr<Span<std::string>> aa) {
  return aa.valueLB(); // OK
  return aa.valueNoLB(); // OK.
}

// Lifetimebound and gsl::Pointer.
const int& test12(Span<int> a) {
  return a.getFieldLB(); // expected-warning {{reference to stack memory associated}} \
                         // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
  return a.getFieldNoLB(); // OK.
}

void test13() {
  // FIXME: RHS is Owner<Pointer>, we skip this case to avoid false positives.
  std::optional<Span<int*>> abc = std::vector<int*>{};

  // FIXME: Detect this using the CFG-based lifetime analysis (container of pointer).
  std::optional<Span<int>> t = std::vector<int> {}; // expected-warning {{object backing the pointer will be destroyed}}
  use(t);
}

} // namespace GH100526

namespace GH118064{

void test() {
  auto y = std::set<int>{}.begin(); // expected-warning {{object backing the pointer}} \
  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(y); // cfg-note {{later used here}}
}
} // namespace GH118064

namespace LifetimeboundInterleave {

const std::string& Ref(const std::string& abc [[clang::lifetimebound]]);

std::string_view TakeSv(std::string_view abc [[clang::lifetimebound]]);
std::string_view TakeStrRef(const std::string& abc [[clang::lifetimebound]]);
std::string_view TakeStr(std::string abc [[clang::lifetimebound]]);

std::string_view test1_1() {
  std::string_view t1 = Ref(std::string()); // expected-warning {{object backing}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t1);                                  // cfg-note {{later used here}}
  t1 = Ref(std::string()); // expected-warning {{object backing}} \
                           // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t1);                 // cfg-note {{later used here}}
  return Ref(std::string()); // expected-warning {{returning address}} \
                             // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::string_view test1_2() {
  std::string_view t2 = TakeSv(std::string()); // expected-warning {{object backing}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t2);                                  // cfg-note {{later used here}}
  t2 = TakeSv(std::string()); // expected-warning {{object backing}} \
                              // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t2);                    // cfg-note {{later used here}}

  return TakeSv(std::string()); // expected-warning {{returning address}} \
                                // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::string_view test1_3() {
  std::string_view t3 = TakeStrRef(std::string()); // expected-warning {{temporary}} \
                                                   // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t3);                                         // cfg-note {{later used here}}
  t3 = TakeStrRef(std::string()); // expected-warning {{object backing}} \
                                  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t3);                        // cfg-note {{later used here}}
  return TakeStrRef(std::string()); // expected-warning {{returning address}} \
                                    // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

std::string_view test1_4() {
  std::string_view t4 = TakeStr(std::string());
  t4 = TakeStr(std::string());
  use(t4);
  return TakeStr(std::string());
}

template <typename T>
struct Foo {
  const T& get() const [[clang::lifetimebound]];
  const T& getNoLB() const;
  // TODO: Do this behind a macro and run tests without this dtor to verify trivial dtor cases.
  ~Foo();
};
std::string_view test2_1(Foo<std::string> r1, Foo<std::string_view> r2) {
  std::string_view t1 = Foo<std::string>().get(); // expected-warning {{object backing}} \
                                                  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t1);                                        // cfg-note {{later used here}}
  t1 = Foo<std::string>().get(); // expected-warning {{object backing}} \
                                 // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(t1);                       // cfg-note {{later used here}}
  return r1.get(); // expected-warning {{address of stack}} \
                   // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}
std::string_view test2_2(Foo<std::string> r1, Foo<std::string_view> r2) {
  std::string_view t2 = Foo<std::string_view>().get();
  use(t2);
  t2 = Foo<std::string_view>().get();
  use(t2);
  return r2.get();
}
std::string_view test2_3(Foo<std::string> r1, Foo<std::string_view> r2) {
  // no warning on no-LB-annotated method.
  std::string_view t3 = Foo<std::string>().getNoLB();
  use(t3);
  t3 = Foo<std::string>().getNoLB();
  use(t3);
  return r1.getNoLB();
}

struct Bar {
  // TODO: Do this behind a macro and run tests without this dtor to verify trivial dtor cases.
  ~Bar();
};
struct [[gsl::Pointer]] Pointer {
  Pointer(const Bar & bar [[clang::lifetimebound]]);
};
Pointer test3(Bar bar) {
  Pointer p = Pointer(Bar()); // expected-warning {{temporary}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p);                     // cfg-note {{later used here}}
  p = Pointer(Bar());         // expected-warning {{object backing}} cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  use(p);                     // cfg-note {{later used here}}
  return bar;                 // expected-warning {{address of stack}} cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

template<typename T>
struct MySpan {
  MySpan(const std::vector<T>& v);
  ~MySpan();
  using iterator = std::iterator<T>;
  // FIXME: It is not possible to annotate accessor methods of non-owning view types.
  // Clang should provide another annotation to mark such functions as 'transparent'.
  iterator begin() const;
};
// FIXME: Same as above.
template <typename T>
typename MySpan<T>::iterator ReturnFirstIt(const MySpan<T>& v);

void test4() {
  std::vector<int> v{1};
  // MySpan<T> doesn't own any underlying T objects, the pointee object of
  // the MySpan iterator is still alive when the whole span is destroyed, thus
  // no diagnostic.
  const int& t1 = *MySpan<int>(v).begin();
  const int& t2 = *ReturnFirstIt(MySpan<int>(v));
  // Ideally, we would diagnose the following case, but due to implementation
  // constraints, we do not.
  const int& t4 = *MySpan<int>(std::vector<int>{}).begin();
  use(t1, t2, t4);

  auto it1 = MySpan<int>(v).begin();
  auto it2 = ReturnFirstIt(MySpan<int>(v));
  use(it1, it2);
}

} // namespace LifetimeboundInterleave

namespace range_based_for_loop_variables {
std::string_view test_view_loop_var(std::vector<std::string> strings) {
  for (std::string_view s : strings) {  // cfg-warning {{address of stack memory is returned later}} 
    return s; //cfg-note {{returned here}}
  }
  return "";
}

const char* test_view_loop_var_with_data(std::vector<std::string> strings) {
  for (std::string_view s : strings) {  // cfg-warning {{address of stack memory is returned later}} 
    return s.data(); //cfg-note {{returned here}}
  }
  return "";
}

std::string_view test_no_error_for_views(std::vector<std::string_view> views) {
  for (std::string_view s : views) {
    return s;
  }
  return "";
}

std::string_view test_string_ref_var(std::vector<std::string> strings) {
  for (const std::string& s : strings) {  // cfg-warning {{address of stack memory is returned later}} 
    return s; //cfg-note {{returned here}}
  }
  return "";
}

std::string_view test_opt_strings(std::optional<std::vector<std::string>> strings_or) {
  for (const std::string& s : *strings_or) {  // cfg-warning {{address of stack memory is returned later}} 
    return s; //cfg-note {{returned here}}
  }
  return "";
}
} // namespace range_based_for_loop_variables

namespace iterator_arrow {
std::string_view test() {
  std::vector<std::string> strings;
  return strings.begin()->data(); // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}
}

void operator_star_arrow_reference() {
  std::vector<std::string> v;
  const char* p = v.begin()->data();
  const char* q = (*v.begin()).data();
  const std::string& r = *v.begin();

  auto temporary = []() { return std::vector<std::string>{{"1"}}; };
  const char* x = temporary().begin()->data();    // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  const char* y = (*temporary().begin()).data();  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  const std::string& z = (*temporary().begin());  // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  use(p, q, r, x, y, z); // cfg-note 3 {{later used here}}
}

void operator_star_arrow_of_iterators_false_positive_no_cfg_analysis() {
  std::vector<std::pair<int, std::string>> v;
  const char* p = v.begin()->second.data();
  const char* q = (*v.begin()).second.data();
  const std::string& r = (*v.begin()).second;

  auto temporary = []() { return std::vector<std::pair<int, std::string>>{{1, "1"}}; };
  const char* x = temporary().begin()->second.data();   // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  const char* y = (*temporary().begin()).second.data(); // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  const std::string& z = (*temporary().begin()).second; // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  use(p, q, r, x, y, z); // cfg-note 3 {{later used here}}
}
} // namespace iterator_arrow

namespace GH120206 {
struct S {
  std::string_view s;
};

struct [[gsl::Owner]] Q1 {
  const S* get() const [[clang::lifetimebound]];
};
std::string_view test1(int c, std::string_view sv) {
  std::string_view k = c > 1 ? Q1().get()->s : sv;
  if (c == 1)
    return  c > 1 ? Q1().get()->s : sv;
  Q1 q;
  return c > 1 ? q.get()->s : sv;
}

struct Q2 {
  const S* get() const [[clang::lifetimebound]];
};
std::string_view test2(int c, std::string_view sv) {
  std::string_view k = c > 1 ? Q2().get()->s : sv;
  if (c == 1)
    return c > 1 ? Q2().get()->s : sv;
  Q2 q;
  return c > 1 ? q.get()->s : sv;
}

} // namespace GH120206

namespace GH120543 {
struct S {
  std::string_view sv;
  std::string s;
};
struct Q {
  const S* get() const [[clang::lifetimebound]];
  ~Q();
};

std::string_view foo(std::string_view sv [[clang::lifetimebound]]);

void test1() {
  std::string_view k1 = S().sv; // OK
  std::string_view k2 = S().s; // expected-warning {{object backing the pointer will}} \
                               // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  std::string_view k3 = Q().get()->sv; // OK
  std::string_view k4  = Q().get()->s; // expected-warning {{object backing the pointer will}} \
                                       // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}


  std::string_view lb1 = foo(S().s); // expected-warning {{object backing the pointer will}} \
                                     // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}
  std::string_view lb2 = foo(Q().get()->s); // expected-warning {{object backing the pointer will}} \
                                            // cfg-warning {{object whose reference is captured does not live long enough}} cfg-note {{destroyed here}}

  use(k1, k2, k3, k4, lb1, lb2);  // cfg-note 4 {{later used here}}
}

struct Bar {};
struct Foo {
  std::vector<Bar> v;
};
Foo getFoo();
void test2() {
  const Foo& foo = getFoo();
  const Bar& bar = foo.v.back(); // OK
}

struct Foo2 {
   std::unique_ptr<Bar> bar;
};

struct Test {
  Test(Foo2 foo) : bar(foo.bar.get()),  // cfg-warning-re {{address of stack memory escapes to a field. {{.*}} may have been moved}}
      storage(std::move(foo.bar)) {};   // cfg-note {{potentially moved here}}

  Bar* bar; // cfg-note {{this field dangles}}
  std::unique_ptr<Bar> storage;
};

} // namespace GH120543

namespace GH127195 {
template <typename T>
struct StatusOr {
  T* operator->() [[clang::lifetimebound]];
  T* value() [[clang::lifetimebound]];
};

const char* foo() {
  StatusOr<std::string> s;
  return s->data(); // expected-warning {{address of stack memory associated with local variable}} \
                    // cfg-warning {{address of stack memory is returned later}} cfg-note {{returned here}}

  StatusOr<std::string_view> s2;
  return s2->data();

  StatusOr<StatusOr<std::string_view>> s3;
  return s3.value()->value()->data();

  // FIXME: nested cases are not supported now.
  StatusOr<StatusOr<std::string>> s4;
  return s4.value()->value()->data();
}

} // namespace GH127195

// Lifetimebound on definition vs declaration on implicit this param.
namespace GH175391 {
// Version A: Attribute on declaration only
class StringA {
public:
    const char* data() const [[clang::lifetimebound]];  // Declaration with attribute
private:
    char buffer[32] = "hello";
};
inline const char* StringA::data() const {  // Definition WITHOUT attribute
    return buffer;
}

// Version B: Attribute on definition only
class StringB {
public:
    const char* data() const;  // No attribute
private:
    char buffer[32] = "hello";
};
inline const char* StringB::data() const [[clang::lifetimebound]] {
    return buffer;
}

// Version C: Attribute on BOTH declaration and definition
class StringC {
public:
    const char* data() const [[clang::lifetimebound]];
private:
    char buffer[32] = "hello";
};
inline const char* StringC::data() const [[clang::lifetimebound]] {
    return buffer;
}

// TEMPLATED VERSIONS

// Template Version A: Attribute on declaration only
template<typename T>
class StringTemplateA {
public:
    const T* data() const [[clang::lifetimebound]];  // Declaration with attribute
private:
    T buffer[32];
};
template<typename T>
inline const T* StringTemplateA<T>::data() const {  // Definition WITHOUT attribute
    return buffer;
}

// Template Version B: Attribute on definition only
template<typename T>
class StringTemplateB {
public:
    const T* data() const;  // No attribute
private:
    T buffer[32];
};
template<typename T>
inline const T* StringTemplateB<T>::data() const [[clang::lifetimebound]] {
    return buffer;
}

// Template Version C: Attribute on BOTH declaration and definition
template<typename T>
class StringTemplateC {
public:
    const T* data() const [[clang::lifetimebound]];
private:
    T buffer[32];
};
template<typename T>
inline const T* StringTemplateC<T>::data() const [[clang::lifetimebound]] {
    return buffer;
}

// TEMPLATE SPECIALIZATION VERSIONS

// Template predeclarations for specializations
template<typename T> class StringTemplateSpecA;
template<typename T> class StringTemplateSpecB;
template<typename T> class StringTemplateSpecC;

// Template Specialization Version A: Attribute on declaration only - <char> specialization
template<>
class StringTemplateSpecA<char> {
public:
    const char* data() const [[clang::lifetimebound]];  // Declaration with attribute
private:
    char buffer[32] = "hello";
};
inline const char* StringTemplateSpecA<char>::data() const {  // Definition WITHOUT attribute
    return buffer;
}

// Template Specialization Version B: Attribute on definition only - <char> specialization
template<>
class StringTemplateSpecB<char> {
public:
    const char* data() const;  // No attribute
private:
    char buffer[32] = "hello";
};
inline const char* StringTemplateSpecB<char>::data() const [[clang::lifetimebound]] {
    return buffer;
}

// Template Specialization Version C: Attribute on BOTH declaration and definition - <char> specialization
template<>
class StringTemplateSpecC<char> {
public:
    const char* data() const [[clang::lifetimebound]];
private:
    char buffer[32] = "hello";
};
inline const char* StringTemplateSpecC<char>::data() const [[clang::lifetimebound]] {
    return buffer;
}

void test() {
    // Non-templated tests
    const auto ptrA = StringA().data();  // Declaration-only attribute  // expected-warning {{temporary whose address is used}}
    const auto ptrB = StringB().data();  // Definition-only attribute   // expected-warning {{temporary whose address is used}}
    const auto ptrC = StringC().data();  // Both have attribute         // expected-warning {{temporary whose address is used}}

    // Templated tests (generic templates)
    const auto ptrTA = StringTemplateA<char>().data();  // Declaration-only attribute // expected-warning {{temporary whose address is used}}
    const auto ptrTB = StringTemplateB<char>().data();  // Definition-only attribute  // expected-warning {{temporary whose address is used}}
    const auto ptrTC = StringTemplateC<char>().data();  // Both have attribute        // expected-warning {{temporary whose address is used}}

    // Template specialization tests
    const auto ptrTSA = StringTemplateSpecA<char>().data();  // Declaration-only attribute  // expected-warning {{temporary whose address is used}}
    const auto ptrTSB = StringTemplateSpecB<char>().data();  // Definition-only attribute   // expected-warning {{temporary whose address is used}}
    const auto ptrTSC = StringTemplateSpecC<char>().data();  // Both have attribute         // expected-warning {{temporary whose address is used}}
}
} // namespace GH175391

void string_insert_GH_186817() {
    std::string msg;
    msg.insert(0, std::string_view(std::string("a temporary")));
}
