Skip to content

Commit abe964a

Browse files
authored
[clang] Don't emit bogus dangling diagnostics when [[gsl::Owner]] and [[clang::lifetimebound]] are used together. (#108280)
In the GSL analysis, we don't track the `this` object if the conversion is not from gsl::owner to gsl pointer, we want to be conservative here to avoid triggering false positives. Fixes #108272
1 parent ed4a2a1 commit abe964a

File tree

3 files changed

+38
-1
lines changed

3 files changed

+38
-1
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,8 @@ Improvements to Clang's diagnostics
305305

306306
- Clang now diagnose when importing module implementation partition units in module interface units.
307307

308+
- Don't emit bogus dangling diagnostics when ``[[gsl::Owner]]`` and `[[clang::lifetimebound]]` are used together (#GH108272).
309+
308310
Improvements to Clang's time-trace
309311
----------------------------------
310312

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,8 @@ static bool isInStlNamespace(const Decl *D) {
269269

270270
static bool shouldTrackImplicitObjectArg(const CXXMethodDecl *Callee) {
271271
if (auto *Conv = dyn_cast_or_null<CXXConversionDecl>(Callee))
272-
if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()))
272+
if (isRecordWithAttr<PointerAttr>(Conv->getConversionType()) &&
273+
Callee->getParent()->hasAttr<OwnerAttr>())
273274
return true;
274275
if (!isInStlNamespace(Callee->getParent()))
275276
return false;

clang/test/Sema/warn-lifetime-analysis-nocfg.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,3 +553,37 @@ void test() {
553553
std::string_view svjkk1 = ReturnStringView(StrCat("bar", "x")); // expected-warning {{object backing the pointer will be destroyed at the end of the full-expression}}
554554
}
555555
} // namespace GH100549
556+
557+
namespace GH108272 {
558+
template <typename T>
559+
struct [[gsl::Owner]] StatusOr {
560+
const T &value() [[clang::lifetimebound]];
561+
};
562+
563+
template <typename V>
564+
class Wrapper1 {
565+
public:
566+
operator V() const;
567+
V value;
568+
};
569+
std::string_view test1() {
570+
StatusOr<Wrapper1<std::string_view>> k;
571+
// Be conservative in this case, as there is not enough information available
572+
// to infer the lifetime relationship for the Wrapper1 type.
573+
std::string_view good = StatusOr<Wrapper1<std::string_view>>().value();
574+
return k.value();
575+
}
576+
577+
template <typename V>
578+
class Wrapper2 {
579+
public:
580+
operator V() const [[clang::lifetimebound]];
581+
V value;
582+
};
583+
std::string_view test2() {
584+
StatusOr<Wrapper2<std::string_view>> k;
585+
// We expect dangling issues as the conversion operator is lifetimebound。
586+
std::string_view bad = StatusOr<Wrapper2<std::string_view>>().value(); // expected-warning {{temporary whose address is used as value of}}
587+
return k.value(); // expected-warning {{address of stack memory associated}}
588+
}
589+
} // namespace GH108272

0 commit comments

Comments
 (0)