https://github.com/tbaederr created 
https://github.com/llvm/llvm-project/pull/147207

We need to ignore the lvalue path, just like we do for lvalue reference types.

>From aaa42f44c12a10070c1ad94965e2f63574600b1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Timm=20B=C3=A4der?= <tbae...@redhat.com>
Date: Sun, 6 Jul 2025 20:09:45 +0200
Subject: [PATCH] [clang][bytecode] Fix APValue generation for
 RValueReferenceType

We need to ignore the lvalue path, just like we do for lvalue reference
types.
---
 clang/lib/AST/ByteCode/Pointer.cpp            |   2 +-
 .../libcxx/rvalue-reference-param.cpp         | 122 ++++++++++++++++++
 2 files changed, 123 insertions(+), 1 deletion(-)
 create mode 100644 clang/test/AST/ByteCode/libcxx/rvalue-reference-param.cpp

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, "", {});
+}

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to