-
Notifications
You must be signed in to change notification settings - Fork 15.1k
[clang][bytecode] Fix APValue generation for RValueReferenceType #147207
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
Conversation
We need to ignore the lvalue path, just like we do for lvalue reference types.
|
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesWe need to ignore the lvalue path, just like we do for lvalue reference types. Full diff: https://github.com/llvm/llvm-project/pull/147207.diff 2 Files Affected:
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 0ad47645d39cc..08eec8172cd4e 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -207,7 +207,7 @@ APValue Pointer::toAPValue(const ASTContext &ASTCtx) const {
bool UsePath = true;
if (const ValueDecl *VD = getDeclDesc()->asValueDecl();
- VD && VD->getType()->isLValueReferenceType())
+ VD && VD->getType()->isReferenceType())
UsePath = false;
// Build the path into the object.
diff --git a/clang/test/AST/ByteCode/libcxx/rvalue-reference-param.cpp b/clang/test/AST/ByteCode/libcxx/rvalue-reference-param.cpp
new file mode 100644
index 0000000000000..0e8127d27f888
--- /dev/null
+++ b/clang/test/AST/ByteCode/libcxx/rvalue-reference-param.cpp
@@ -0,0 +1,122 @@
+// RUN: %clang_cc1 -std=c++2c -verify=expected,both %s -fexperimental-new-constant-interpreter
+// RUN: %clang_cc1 -std=c++2c -verify=ref,both %s
+
+template <int __v> struct integral_constant {
+ static const int value = __v;
+};
+template <bool _Val> using _BoolConstant = integral_constant<_Val>;
+template <class _From, class _To>
+constexpr bool is_convertible_v = __is_convertible(_From, _To);
+template <class _Tp> _Tp __declval(int);
+template <class _Tp> decltype(__declval<_Tp>(0)) declval();
+template <class _Tp, class _Up>
+using _IsSame = _BoolConstant<__is_same(_Tp, _Up)>;
+template <class _If> struct conditional {
+ using type = _If;
+};
+template <bool, class _IfRes, class>
+using conditional_t = conditional<_IfRes>::type;
+template <class _Tp, class>
+concept __weakly_equality_comparable_with = requires(_Tp __t) { __t; };
+template <bool, class _Tp = void> using __enable_if_t = _Tp;
+template <template <class> class, class>
+integral_constant<true> __sfinae_test_impl(int);
+template <template <class> class _Templ, class... _Args>
+using _IsValidExpansion = decltype(__sfinae_test_impl<_Templ, _Args...>(0));
+template <class _Tp>
+using __test_for_primary_template =
+ __enable_if_t<_IsSame<_Tp, typename _Tp::__primary_template>::value>;
+template <class _Tp>
+using __is_primary_template =
+ _IsValidExpansion<__test_for_primary_template, _Tp>;
+template <class _Ip>
+using iter_difference_t =
+ conditional_t<__is_primary_template<_Ip>::value, _Ip, _Ip>::difference_type;
+template <int> struct _OrImpl {
+ template <class, class _First>
+ using _Result = _OrImpl<!_First::value>::template _Result<_First>;
+};
+template <> struct _OrImpl<false> {
+ template <class _Res> using _Result = _Res;
+};
+template <class... _Args>
+using _Or = _OrImpl<sizeof...(_Args)>::template _Result<_Args...>;
+struct input_iterator_tag {};
+template <class _Dp, class _Bp>
+concept derived_from = is_convertible_v<_Dp, _Bp>;
+template <class _Ip>
+concept input_or_output_iterator = requires(_Ip __i) { __i; };
+template <class _Sp, class _Ip>
+concept sentinel_for = __weakly_equality_comparable_with<_Sp, _Ip>;
+struct __iter_concept_category_test {
+ template <class> using _Apply = input_iterator_tag;
+};
+struct __test_iter_concept
+ : _IsValidExpansion<__iter_concept_category_test::_Apply, int>,
+ __iter_concept_category_test {};
+struct __iter_concept_cache {
+ using type = _Or<int, __test_iter_concept>;
+};
+template <class _Iter>
+using _ITER_CONCEPT = __iter_concept_cache::type::_Apply<_Iter>;
+template <class _Ip>
+concept input_iterator = derived_from<_ITER_CONCEPT<_Ip>, input_iterator_tag>;
+template <class _T1, class _T2> struct pair {
+ _T1 first;
+ _T2 second;
+};
+struct {
+ template <class _Tp> auto operator()(_Tp __t) { return __t.begin(); }
+} begin;
+template <class _Tp> using iterator_t = decltype(begin(declval<_Tp>()));
+template <class _Tp>
+concept __member_size = requires(_Tp __t) { __t; };
+struct {
+ template <__member_size _Tp> constexpr void operator()(_Tp &&__t) {
+ __t.size(); // both-note 2{{in instantiation}}
+ }
+} size;
+template <class _Tp>
+concept range = requires(_Tp __t) { __t; };
+template <class _Tp>
+concept input_range = input_iterator<_Tp>;
+template <range _Rp>
+using range_difference_t = iter_difference_t<iterator_t<_Rp>>;
+struct {
+ template <range _Rp> constexpr range_difference_t<_Rp> operator()(_Rp &&__r) {
+ size(__r); // both-note 2{{in instantiation}}
+ } // both-warning {{does not return a value}}
+} distance;
+template <input_or_output_iterator _Iter, sentinel_for<_Iter> _Sent>
+struct subrange {
+ _Iter __begin_;
+ _Sent __end_;
+ _Iter begin();
+ constexpr _Iter size() { __end_ - __begin_; } // both-warning {{does not return a value}} \
+ // both-note {{in instantiation}}
+};
+struct {
+ template <input_range _Range1, input_range _Range2>
+ void operator()(_Range1 &&__range1, _Range2) {
+ (void)(distance(__range1) != 0); // both-note 3{{in instantiation}}
+ }
+} equal;
+template <class _Owner> struct __key_value_iterator {
+ using difference_type = _Owner::difference_type;
+ constexpr friend difference_type operator-(__key_value_iterator,
+ __key_value_iterator &) {} // both-warning {{does not return a value}}
+};
+struct flat_multimap {
+ template <bool> using __iterator = __key_value_iterator<flat_multimap>;
+ using difference_type =
+ decltype(static_cast<int *>(nullptr) - static_cast<int *>(nullptr));
+ pair<__iterator<true>, __iterator<true>> equal_range(const char *);
+} test_expected_range;
+void test() {
+ flat_multimap m;
+ auto test_found = [](auto map, auto expected_key, int) {
+ auto [first, last] = map.equal_range(expected_key);
+ equal(subrange(first, last), test_expected_range); // both-note 3{{in instantiation}}
+ };
+ test_found(m, "", {});
+}
|
|
LLVM Buildbot has detected a new failure on builder Full details are available at: https://lab.llvm.org/buildbot/#/builders/207/builds/3473 Here is the relevant piece of the build log for the reference |
We need to ignore the lvalue path, just like we do for lvalue reference types.