Skip to content

Commit 8e0d7d8

Browse files
committed
lifetime-safety-paren
1 parent b90459c commit 8e0d7d8

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

clang/lib/Analysis/LifetimeSafety/Origins.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ Origin &OriginManager::addOrigin(OriginID ID, const clang::Expr &E) {
3434

3535
// TODO: Mark this method as const once we remove the call to getOrCreate.
3636
OriginID OriginManager::get(const Expr &E) {
37+
if (auto *ParenIgnored = E.IgnoreParens(); ParenIgnored != &E)
38+
return get(*ParenIgnored);
3739
auto It = ExprToOriginID.find(&E);
3840
if (It != ExprToOriginID.end())
3941
return It->second;

clang/test/Sema/warn-lifetime-safety.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,34 @@ void conditional_operator(bool cond) {
635635
} // expected-note 4 {{destroyed here}}
636636
(void)*p; // expected-note 4 {{later used here}}
637637
}
638+
639+
void parentheses(bool cond) {
640+
MyObj* p;
641+
{
642+
MyObj a;
643+
p = &((((a)))); // expected-warning {{object whose reference is captured does not live long enough}}
644+
} // expected-note {{destroyed here}}
645+
(void)*p; // expected-note {{later used here}}
646+
647+
{
648+
MyObj a;
649+
p = ((GetPointer((a)))); // expected-warning {{object whose reference is captured does not live long enough}}
650+
} // expected-note {{destroyed here}}
651+
(void)*p; // expected-note {{later used here}}
652+
653+
{
654+
MyObj a, b, c, d;
655+
p = &(cond ? (cond ? a // expected-warning {{object whose reference is captured does not live long enough}}.
656+
: b) // expected-warning {{object whose reference is captured does not live long enough}}.
657+
: (cond ? c // expected-warning {{object whose reference is captured does not live long enough}}.
658+
: d)); // expected-warning {{object whose reference is captured does not live long enough}}.
659+
} // expected-note 4 {{destroyed here}}
660+
(void)*p; // expected-note 4 {{later used here}}
661+
662+
{
663+
MyObj a, b, c, d;
664+
p = ((cond ? (((cond ? &a : &b))) // expected-warning 2 {{object whose reference is captured does not live long enough}}.
665+
: &(((cond ? c : d))))); // expected-warning 2 {{object whose reference is captured does not live long enough}}.
666+
} // expected-note 4 {{destroyed here}}
667+
(void)*p; // expected-note 4 {{later used here}}
668+
}

clang/unittests/Analysis/LifetimeSafetyTest.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,23 @@ TEST_F(LifetimeAnalysisTest, GslPointerInConditionalOperator) {
700700
EXPECT_THAT(Origin("v"), HasLoansTo({"a", "b"}, "p1"));
701701
}
702702

703+
TEST_F(LifetimeAnalysisTest, ExtraParenthesis) {
704+
SetupTest(R"(
705+
void target() {
706+
MyObj a;
707+
View x = ((View((((a))))));
708+
View y = ((View{(((x)))}));
709+
View z = ((View(((y)))));
710+
View p = ((View{((x))}));
711+
POINT(p1);
712+
}
713+
)");
714+
EXPECT_THAT(Origin("x"), HasLoansTo({"a"}, "p1"));
715+
EXPECT_THAT(Origin("y"), HasLoansTo({"a"}, "p1"));
716+
EXPECT_THAT(Origin("z"), HasLoansTo({"a"}, "p1"));
717+
EXPECT_THAT(Origin("p"), HasLoansTo({"a"}, "p1"));
718+
}
719+
703720
// FIXME: Handle temporaries.
704721
TEST_F(LifetimeAnalysisTest, ViewFromTemporary) {
705722
SetupTest(R"(

0 commit comments

Comments
 (0)