Skip to content

[ASan][libc++] Initialize __r_ variable with lambda #77394

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

Merged
merged 2 commits into from
Jan 11, 2024

Conversation

AdvenamTacet
Copy link
Member

This commit is a refactor (increases readability) and optimization fix.

This is a fixed commit of #76200 First reverthed here: 1ea7a56

Please, check original PR for details.

The difference is a return type of the lambda.

Original description:

This commit addresses optimization and instrumentation challenges encountered within comma constructors.

  1. _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS does not work in comma constructors.
  2. Code inside comma constructors is not always correctly optimized. Problematic code examples:
    • : __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)), std::move(__str.__r_))) {
    • : __r_(__r_([&](){ if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_);}())) {

However, lambda with argument seems to be correctly optimized. This patch uses that fact.

Use of lambda based on idea from @ldionne.

This commit is a refactor (increases readability) and optimization fix.

This is a fixed commit of llvm#76200
First reverthed here: llvm@1ea7a56

The difference is a return type of the lambda.

Original description:

This commit addresses optimization and instrumentation challenges encountered within comma constructors.
  1) _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS does not work in comma constructors.
  2) Code inside comma constructors is not always correctly optimized. Problematic code examples:
        - `: __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)), std::move(__str.__r_))) {`
        - `: __r_(__r_([&](){ if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_);}())) {`

However, lambda with argument seems to be correctly optimized. This patch uses that fact.

Use of lambda based on idea from @ldionne.
@AdvenamTacet AdvenamTacet requested review from ldionne and EricWF January 9, 2024 00:01
@AdvenamTacet AdvenamTacet requested a review from a team as a code owner January 9, 2024 00:01
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Jan 9, 2024
@llvmbot
Copy link
Member

llvmbot commented Jan 9, 2024

@llvm/pr-subscribers-libcxx

Author: Tacet (AdvenamTacet)

Changes

This commit is a refactor (increases readability) and optimization fix.

This is a fixed commit of #76200 First reverthed here: 1ea7a56

Please, check original PR for details.

The difference is a return type of the lambda.

Original description:

This commit addresses optimization and instrumentation challenges encountered within comma constructors.

  1. _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS does not work in comma constructors.
  2. Code inside comma constructors is not always correctly optimized. Problematic code examples:
    • : __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)), std::move(__str.__r_))) {
    • : __r_(__r_([&](){ if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_);}())) {

However, lambda with argument seems to be correctly optimized. This patch uses that fact.

Use of lambda based on idea from @ldionne.


Full diff: https://github.com/llvm/llvm-project/pull/77394.diff

1 Files Affected:

  • (modified) libcxx/include/string (+1-1)
diff --git a/libcxx/include/string b/libcxx/include/string
index c676182fba8bac..c3cbb560efa911 100644
--- a/libcxx/include/string
+++ b/libcxx/include/string
@@ -922,7 +922,7 @@ public:
       // Turning off ASan instrumentation for variable initialization with _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS
       // does not work consistently during initialization of __r_, so we instead unpoison __str's memory manually first.
       // __str's memory needs to be unpoisoned only in the case where it's a short string.
-      : __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)), std::move(__str.__r_))) {
+      : __r_([](basic_string &__s) -> auto&& { if(!__s.__is_long()) __s.__annotate_delete(); return std::move(__s.__r_); }(__str)) {
     __str.__r_.first() = __rep();
     __str.__annotate_new(0);
     if (!__is_long())

@AdvenamTacet AdvenamTacet changed the title [ASan][libc++] Initialize a variable with lambda [ASan][libc++] Initialize __r_ variable with lambda Jan 9, 2024
@AdvenamTacet AdvenamTacet merged commit 75efddb into llvm:main Jan 11, 2024
@AdvenamTacet AdvenamTacet deleted the lambda-fixed branch January 11, 2024 20:40
@AdvenamTacet
Copy link
Member Author

I see failing buildbots (this time cuda buildbots), bo I see no connection with my changes, therefore I'm not reverting the PR.

Example error:

/buildbot/cuda-p4-0/work/clang-cuda-p4/clang/bin/../include/c++/v1/string:2025:33: error: use of undeclared identifier 'noinline'; did you mean 'inline'?
 2025 |   _LIBCPP_CONSTEXPR_SINCE_CXX20 _LIBCPP_NOINLINE void __erase_external_with_move(size_type __pos, size_type __n);
      |                                 ^
/buildbot/cuda-p4-0/work/clang-cuda-p4/clang/bin/../include/c++/v1/__config:1192:45: note: expanded from macro '_LIBCPP_NOINLINE'
 1192 | #    define _LIBCPP_NOINLINE __attribute__((__noinline__))
      |                                             ^
/buildbot/cuda-p4-0/work/clang-cuda-p4/external/cuda/cuda-11.8/include/crt/host_defines.h:83:24: note: expanded from macro '__noinline__'
   83 |         __attribute__((noinline))
      |

I don't even modify code close to _LIBCPP_NOINLINE.

@ldionne
Copy link
Member

ldionne commented Jan 11, 2024

Yeah those have been failing for a while due to the addition of __noinline__ in <string>. We're still discussing what to do.

@AdvenamTacet
Copy link
Member Author

Thank you for confirmation!

justinfargnoli pushed a commit to justinfargnoli/llvm-project that referenced this pull request Jan 28, 2024
This commit is a refactor (increases readability) and optimization fix.

This is a fixed commit of
llvm#76200 First reverthed here:
llvm@1ea7a56

Please, check original PR for details.

The difference is a return type of the lambda.

Original description:

This commit addresses optimization and instrumentation challenges
encountered within comma constructors.
1) _LIBCPP_STRING_INTERNAL_MEMORY_ACCESS does not work in comma
constructors.
2) Code inside comma constructors is not always correctly optimized.
Problematic code examples:
- `: __r_(((__str.__is_long() ? 0 : (__str.__annotate_delete(), 0)),
std::move(__str.__r_))) {`
- `: __r_(__r_([&](){ if(!__s.__is_long()) __s.__annotate_delete();
return std::move(__s.__r_);}())) {`

However, lambda with argument seems to be correctly optimized. This
patch uses that fact.

Use of lambda based on idea from @ldionne.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants