This is an archive of the discontinued LLVM Phabricator instance.

[libc++] Add [[clang::lifetimebound]] attribute to std::forward and friends
ClosedPublic

Authored by philnik on Jan 9 2023, 1:29 PM.

Details

Summary

This allows clang to catch lifetime bugs through these functions.
As a drive-by, replace _LIBCPP_INLINE_VISIBILITY with _LIBCPP_HIDE_FROM_ABI.
Fixes #59900

Diff Detail

Event Timeline

philnik created this revision.Jan 9 2023, 1:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 9 2023, 1:29 PM
philnik requested review of this revision.Jan 9 2023, 1:29 PM
Herald added a project: Restricted Project. · View Herald TranscriptJan 9 2023, 1:29 PM
Herald added a reviewer: Restricted Project. · View Herald Transcript
philnik edited the summary of this revision. (Show Details)Jan 9 2023, 1:31 PM

Thanks! This is a nice improvement IMO.

However, the CI issue you're seeing is actually a very interesting and slightly deeper issue. Indeed, remember when Clang decided to define forward and move as builtins in D123345? One impact of that change is that we don't control our std::forward and std::move anymore, so we'd need to make the change in this patch inside Clang, not inside libc++. An obvious follow-up question is then do we make the change in Clang and strive to keep libc++ in synchronization with how Clang defines std::forward? Or do we not care about keeping them in sync? Should we have a way to ensure that both definitions stay in sync?

CC Clang folks @rnk @rsmith @aaron.ballman

Thanks! This is a nice improvement IMO.

However, the CI issue you're seeing is actually a very interesting and slightly deeper issue. Indeed, remember when Clang decided to define forward and move as builtins in D123345? One impact of that change is that we don't control our std::forward and std::move anymore, so we'd need to make the change in this patch inside Clang, not inside libc++. An obvious follow-up question is then do we make the change in Clang and strive to keep libc++ in synchronization with how Clang defines std::forward? Or do we not care about keeping them in sync? Should we have a way to ensure that both definitions stay in sync?

CC Clang folks @rnk @rsmith @aaron.ballman

I'm not sure how clang handles this, but the warnings get emitted. It's just that I forgot to guard std::forward_like pre-C++23. I guess it just adds the attributes to the builtin declaration magically.

philnik updated this revision to Diff 487885.Jan 10 2023, 10:44 AM
philnik edited the summary of this revision. (Show Details)

Try to fix CI

I like this idea. I think it would be useful for "views" like string_view and span too.

libcxx/include/__config
1059

Why not [[clang::lifetimebound]] ?

libcxx/include/__utility/forward_like.h
37–38

Should this extension be documented, like we do with [[nodiscard]]?

philnik added inline comments.Jan 10 2023, 12:36 PM
libcxx/include/__config
1059

For the same reason that we _Uglify all other names: macros. Attributes are not immune to them, so we have to _Uglify them too. https://godbolt.org/z/MqW68b9PY

libcxx/include/__utility/forward_like.h
37–38

I'm not convinced we should list the [[nodiscard]] decorated functions. As we extend the use of these kinds of macros the lists become long and I don't see why anybody who is actually interested in that list. Users are interested in getting warnings from the compiler, not which functions have some specific attribute. We also don't document which symbols are marked [[clang::preferred_name]].

Thanks! This is a nice improvement IMO.

However, the CI issue you're seeing is actually a very interesting and slightly deeper issue. Indeed, remember when Clang decided to define forward and move as builtins in D123345? One impact of that change is that we don't control our std::forward and std::move anymore, so we'd need to make the change in this patch inside Clang, not inside libc++. An obvious follow-up question is then do we make the change in Clang and strive to keep libc++ in synchronization with how Clang defines std::forward? Or do we not care about keeping them in sync? Should we have a way to ensure that both definitions stay in sync?

CC Clang folks @rnk @rsmith @aaron.ballman

I think trying to stay in sync is probably the right approach, but I don't have good ideas about how to automatically catch differences. However, I don't expect to make a lot of changes to these signatures, so maybe we don't need something to catch differences. I suspect the correct way to do this in Clang is to modify Builtins.def to add a new encoding for lifetime bound to the list of attributes, and then update ASTContext::GetBuiltinType()/Sema::ActOnFunctionDeclarator() to properly add the attribute where needed.

ldionne accepted this revision.Jan 13 2023, 9:28 AM

I think trying to stay in sync is probably the right approach, but I don't have good ideas about how to automatically catch differences. However, I don't expect to make a lot of changes to these signatures, so maybe we don't need something to catch differences. I suspect the correct way to do this in Clang is to modify Builtins.def to add a new encoding for lifetime bound to the list of attributes, and then update ASTContext::GetBuiltinType()/Sema::ActOnFunctionDeclarator() to properly add the attribute where needed.

Actually, I think we do have a way to make sure that they stay in sync, at least for the aspects of it that we care about. We have our tests, and they will fail if somehow Clang doesn't do the right thing! It seems to do the right thing right now, since the tests are passing. IDK how that works, but oh well.

libcxx/include/__utility/forward_like.h
37–38

Yeah, I'd agree with dropping the list of [[nodiscard]] extensions in the docs, but please make sure they are all marked with _LIBCPP_NODISCARD_EXT so we can find them. Having the actual list in the documentation has little value and it will only get out of sync.

That should be done in a separate patch, obv.

This revision is now accepted and ready to land.Jan 13 2023, 9:28 AM
This revision was landed with ongoing or failed builds.Jan 13 2023, 5:54 PM
This revision was automatically updated to reflect the committed changes.