Skip to content

Commit 36697bc

Browse files
committed
[clang] Fix dangling false positives for conditional operators.
1 parent a3db591 commit 36697bc

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,8 @@ Improvements to Clang's diagnostics
677677
views.push_back(std::string("123")); // warning
678678
}
679679

680+
- Fix -Wdangling false positives on conditional operators (#120206).
681+
680682
Improvements to Clang's time-trace
681683
----------------------------------
682684

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,15 @@ static void visitFunctionCallArguments(IndirectLocalPath &Path, Expr *Call,
582582
// Temp().ptr; // Here ptr might not dangle.
583583
if (isa<MemberExpr>(Arg->IgnoreImpCasts()))
584584
return;
585+
// Avoid false positives when the object is constructed from a conditional
586+
// operator argument. A common case is:
587+
// // 'ptr' might not be owned by the Owner object.
588+
// std::string_view s = cond() ? Owner().ptr : sv;
589+
if (const auto *Cond =
590+
dyn_cast<AbstractConditionalOperator>(Arg->IgnoreImpCasts());
591+
Cond && isPointerLikeType(Cond->getType()))
592+
return;
593+
585594
auto ReturnType = Callee->getReturnType();
586595

587596
// Once we initialized a value with a non gsl-owner reference, it can no

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,3 +777,32 @@ void test4() {
777777
}
778778

779779
} // namespace LifetimeboundInterleave
780+
781+
namespace GH120206 {
782+
struct S {
783+
std::string_view s;
784+
};
785+
786+
struct [[gsl::Owner]] Q1 {
787+
const S* get() const [[clang::lifetimebound]];
788+
};
789+
std::string_view test1(int c, std::string_view sv) {
790+
std::string_view k = c > 1 ? Q1().get()->s : sv;
791+
if (c == 1)
792+
return c > 1 ? Q1().get()->s : sv;
793+
Q1 q;
794+
return c > 1 ? q.get()->s : sv;
795+
}
796+
797+
struct Q2 {
798+
const S* get() const [[clang::lifetimebound]];
799+
};
800+
std::string_view test2(int c, std::string_view sv) {
801+
std::string_view k = c > 1 ? Q2().get()->s : sv;
802+
if (c == 1)
803+
return c > 1 ? Q2().get()->s : sv;
804+
Q2 q;
805+
return c > 1 ? q.get()->s : sv;
806+
}
807+
808+
} // namespace GH120206

0 commit comments

Comments
 (0)