mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
c++/reflection: propagate cv-quals for SPLICE_SCOPE [PR125096]
tsubst_splice_scope isn't propagating cv-quals from the template tree to the result, which means wrongly failed asserts in the new test due to a missing 'const'. So let's add the cv-quals like we do in so many other places in tsubst. PR c++/125096 gcc/cp/ChangeLog: * pt.cc (tsubst_splice_scope): Don't return early for dependent_splice_p. Propagate cv-qualifiers from the SPLICE_SCOPE to the result. * reflect.cc (valid_splice_scope_p): Accept SPLICE_SCOPE. gcc/testsuite/ChangeLog: * g++.dg/reflect/mangle4.C: Move dg-error. * g++.dg/reflect/dep16.C: New test. Reviewed-by: Jason Merrill <jason@redhat.com>
This commit is contained in:
@@ -16904,8 +16904,8 @@ tsubst_splice_scope (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
return r;
|
||||
const bool type_p = SPLICE_SCOPE_TYPE_P (t);
|
||||
if (dependent_splice_p (r))
|
||||
return make_splice_scope (r, type_p);
|
||||
if (type_p && ctad_template_p (r))
|
||||
r = make_splice_scope (r, type_p);
|
||||
else if (type_p && ctad_template_p (r))
|
||||
r = make_template_placeholder (r);
|
||||
if (type_p
|
||||
? !valid_splice_type_p (r)
|
||||
@@ -16925,6 +16925,10 @@ tsubst_splice_scope (tree t, tree args, tsubst_flags_t complain, tree in_decl)
|
||||
return error_mark_node;
|
||||
}
|
||||
|
||||
if (type_p)
|
||||
r = cp_build_qualified_type (r, cp_type_quals (t) | cp_type_quals (r),
|
||||
complain | tf_ignore_bad_quals);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
@@ -8912,7 +8912,8 @@ valid_splice_scope_p (const_tree t)
|
||||
{
|
||||
return (CLASS_TYPE_P (t)
|
||||
|| TREE_CODE (t) == ENUMERAL_TYPE
|
||||
|| TREE_CODE (t) == NAMESPACE_DECL);
|
||||
|| TREE_CODE (t) == NAMESPACE_DECL
|
||||
|| TREE_CODE (t) == SPLICE_SCOPE);
|
||||
}
|
||||
|
||||
/* Return true if T is a valid result of the splice in a class member access,
|
||||
|
||||
28
gcc/testsuite/g++.dg/reflect/dep16.C
Normal file
28
gcc/testsuite/g++.dg/reflect/dep16.C
Normal file
@@ -0,0 +1,28 @@
|
||||
// PR c++/125096
|
||||
// { dg-do compile { target c++26 } }
|
||||
// { dg-additional-options "-freflection" }
|
||||
|
||||
#include <meta>
|
||||
#include <vector>
|
||||
|
||||
namespace ctp {
|
||||
template <class T> struct Reflect;
|
||||
|
||||
namespace impl {
|
||||
template <class T> using custom_target = Reflect<T>::target_type;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
using target = [: is_scalar_type(^^T) ? ^^T : substitute(^^impl::custom_target, {^^T}) :];
|
||||
|
||||
template <class T>
|
||||
struct Reflect<std::vector<T>> {
|
||||
using underlying = target<T> const;
|
||||
using target_type = std::span<const target<T>>;
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(dealias(^^ctp::target<int>) == ^^int);
|
||||
static_assert(dealias(^^ctp::target<std::vector<int>>) == ^^std::span<int const>);
|
||||
static_assert(dealias(^^ctp::Reflect<std::vector<int>>::underlying) == ^^int const);
|
||||
static_assert(dealias(^^ctp::Reflect<std::vector<int>>::target_type) == ^^std::span<int const>);
|
||||
@@ -20,7 +20,6 @@ template<random_access_iterator I>
|
||||
}
|
||||
|
||||
int main() {
|
||||
// ??? It's not clear which of these should error.
|
||||
std::default_accessor<int> _ = std::iterator_accessor<int*>();
|
||||
std::default_accessor<const int> _ = std::iterator_accessor<int*>(); // { dg-error "conversion" }
|
||||
std::default_accessor<int> _ = std::iterator_accessor<int*>(); // { dg-error "conversion" }
|
||||
std::default_accessor<const int> _ = std::iterator_accessor<int*>();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user