-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang][bytecode] Fix builtin_memcmp buffer sizes for pointers #130570
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
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
// RUN: %clang_cc1 -std=c++2c -fexperimental-new-constant-interpreter -verify=expected,both %s | ||
// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s | ||
|
||
// both-no-diagnostics | ||
|
||
namespace std { | ||
inline namespace { | ||
template <int __v> struct integral_constant { | ||
static const int value = __v; | ||
}; | ||
template <bool, class> using __enable_if_t = int; | ||
char *addressof(char &); | ||
struct pointer_traits { | ||
template <class _Up> using rebind = _Up *; | ||
}; | ||
} // namespace | ||
} // namespace std | ||
void *operator new(decltype(sizeof(int)), void *); | ||
namespace std { | ||
inline namespace { | ||
template <class _Tp> using __make_unsigned_t = __make_unsigned(_Tp); | ||
template <class _Default, template <class> class> | ||
using __detected_or_t = _Default; | ||
template <class _Tp> using __pointer_member = _Tp; | ||
template <class _Tp, class> | ||
using __pointer = __detected_or_t<_Tp *, __pointer_member>; | ||
template <class _Tp> using __size_type_member = _Tp; | ||
template <class, class _DiffType> | ||
using __size_type = | ||
__detected_or_t<__make_unsigned_t<_DiffType>, __size_type_member>; | ||
struct allocation_result { | ||
char *ptr; | ||
unsigned long count; | ||
}; | ||
template <class _Alloc> struct allocator_traits { | ||
using allocator_type = _Alloc; | ||
using pointer = | ||
__pointer<typename allocator_type::value_type, allocator_type>; | ||
using const_pointer = pointer_traits::rebind<char>; | ||
using size_type = | ||
__size_type<allocator_type, decltype(static_cast<int *>(nullptr) - | ||
static_cast<int *>(nullptr))>; | ||
template <class _Ap> | ||
static constexpr allocation_result allocate_at_least(_Ap __alloc, | ||
size_type __n) { | ||
return {__alloc.allocate(__n), (unsigned long)__n}; | ||
} | ||
}; | ||
template <class _Alloc> | ||
constexpr auto __allocate_at_least(_Alloc __alloc, decltype(sizeof(int)) __n) { | ||
return allocator_traits<_Alloc>::allocate_at_least(__alloc, __n); | ||
} | ||
template <class> struct allocator { | ||
typedef char value_type; | ||
constexpr char *allocate(decltype(sizeof(int)) __n) { | ||
return static_cast<char *>(operator new(__n)); | ||
} | ||
constexpr void deallocate(char *__p) { operator delete(__p); } | ||
}; | ||
struct __long { | ||
allocator_traits<allocator<char>>::size_type __is_long_; | ||
allocator_traits<allocator<char>>::size_type __size_; | ||
allocator_traits<allocator<char>>::pointer __data_; | ||
}; | ||
allocator<char> __alloc_; | ||
struct basic_string { | ||
__long __l; | ||
constexpr basic_string(basic_string &__str) { | ||
allocator_traits<allocator<char>>::size_type __trans_tmp_1 = | ||
__str.__get_long_size(); | ||
auto __allocation = __allocate_at_least(__alloc_, __trans_tmp_1); | ||
for (allocator_traits<allocator<char>>::size_type __i = 0; | ||
__i != __allocation.count; ++__i) { | ||
char *__trans_tmp_9 = addressof(__allocation.ptr[__i]); | ||
new (__trans_tmp_9) char(); | ||
} | ||
__l.__data_ = __allocation.ptr; | ||
__l.__is_long_ = __l.__size_ = __trans_tmp_1; | ||
} | ||
template <__enable_if_t<integral_constant<false>::value, int> = 0> | ||
constexpr basic_string(const char *__s, allocator<char>) { | ||
decltype(sizeof(int)) __trans_tmp_11, __i = 0; | ||
for (; __s[__i]; ++__i) | ||
__trans_tmp_11 = __i; | ||
auto __allocation = __allocate_at_least(__alloc_, 1); | ||
__l.__data_ = __allocation.ptr; | ||
__l.__size_ = __trans_tmp_11; | ||
} | ||
constexpr ~basic_string() { | ||
allocator<char> __a; | ||
__a.deallocate(__l.__data_); | ||
} | ||
constexpr allocator_traits<allocator<char>>::size_type size() { | ||
return __l.__is_long_; | ||
} | ||
constexpr char *data() { | ||
allocator_traits<allocator<char>>::const_pointer __trans_tmp_6 = | ||
__l.__is_long_ ? __l.__data_ : 0; | ||
return __trans_tmp_6; | ||
} | ||
constexpr allocator_traits<allocator<char>>::size_type __get_long_size() { | ||
return __l.__size_; | ||
} | ||
}; | ||
constexpr void operator==(basic_string __lhs, basic_string __rhs) { | ||
decltype(sizeof(int)) __lhs_sz = __lhs.size(); | ||
char *__trans_tmp_10 = __rhs.data(), *__trans_tmp_15 = __lhs.data(); | ||
__builtin_memcmp(__trans_tmp_15, __trans_tmp_10, __lhs_sz); | ||
} | ||
} // namespace | ||
} // namespace std | ||
constexpr void test(std::basic_string s0) { | ||
std::basic_string s1 = s0, s2(s0); | ||
s2 == s1; | ||
} | ||
constexpr bool test() { | ||
test(std::basic_string("2345678901234567890", std::allocator<char>())); | ||
return true; | ||
} | ||
static_assert(test()); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this funny construct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a reduced test case. Anything special about this line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm just wondering what the meaning of an inline anonymous namespace is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, no meaning at all, I think cvise even removed the
inline
and I added it back so the compiler wouldn't complain.