Skip to content

Support use of clang::lifetime_capture_by in constructors #117680

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
usx95 opened this issue Nov 26, 2024 · 4 comments · Fixed by #117792
Closed

Support use of clang::lifetime_capture_by in constructors #117680

usx95 opened this issue Nov 26, 2024 · 4 comments · Fixed by #117792
Assignees
Labels
clang:memory-safety Issue/FR relating to the lifetime analysis in Clang (-Wdangling, -Wreturn-local-addr)

Comments

@usx95
Copy link
Contributor

usx95 commented Nov 26, 2024

https://godbolt.org/z/KqM3znMhT

struct S{
    S(const int& s [[clang::lifetimebound]]);
};
struct T{
    T(const int& t [[clang::lifetime_capture_by(this)]]);
};

void foo() {
    S s(1); // Error. Good.
    T t(1); // No diagnostic here. Bad.
}
@usx95 usx95 added the clang:memory-safety Issue/FR relating to the lifetime analysis in Clang (-Wdangling, -Wreturn-local-addr) label Nov 26, 2024
@hokein hokein self-assigned this Nov 26, 2024
@hokein
Copy link
Collaborator

hokein commented Nov 26, 2024

This case is already supported. The warning is not shown because this warning is disabled by default, see https://godbolt.org/z/rqKhW9qEW.

@usx95
Copy link
Contributor Author

usx95 commented Nov 26, 2024

Hmm. I expected it to not work.
I think the current code path should not be taken for constructors and we should use the initialisation path. For example, we have a false positive:
https://godbolt.org/z/rzzM16dGc

struct T{
    T(const int& t [[clang::lifetime_capture_by(this)]]);
};

int foo(const T& t);

void foo() {
    auto x = foo(T(1)); // Error. False positive.
}

@hokein
Copy link
Collaborator

hokein commented Nov 26, 2024

I see.

I think this is a case (I hit it in #117690 as well) where both the container and temporary object are destroyed at the end of the full expression, and the lifetimebound doesn't trigger on this case.

Do we want to diagnose on the following case? I think probably not (in order to reduce noise)

void foo() {
    foo(T(1)); 
}

@usx95
Copy link
Contributor Author

usx95 commented Nov 26, 2024

struct T{
    T(const int& t [[clang::lifetime_capture_by(this)]]);
};

int foo(const T& t);
int bar(const T& t [[clang::lifetimebound]]);

void foo() {
    auto x = foo(T(1)); // Should be ok.
    auto y = bar(T(1)); // error is expected.
}

I would lean towards treating this as we treat lifetimebound for ctors here:

if (CheckCoroCall || Callee->getParamDecl(I)->hasAttr<LifetimeBoundAttr>())
VisitLifetimeBoundArg(Callee->getParamDecl(I), Arg);
else if (EnableGSLAnalysis && I == 0) {
// Perform GSL analysis for the first argument
if (shouldTrackFirstArgument(Callee)) {
VisitGSLPointerArg(Callee, Arg);
} else if (auto *Ctor = dyn_cast<CXXConstructExpr>(Call);

And not trigger checkCaptureByLifetime for constructors

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:memory-safety Issue/FR relating to the lifetime analysis in Clang (-Wdangling, -Wreturn-local-addr)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants