* [PATCH] c++: structured bindings and lookup of tuple_size/tuple_element [PR115605]
@ 2024-06-25 5:00 Andrew Pinski
2024-06-25 16:20 ` Marek Polacek
0 siblings, 1 reply; 2+ messages in thread
From: Andrew Pinski @ 2024-06-25 5:00 UTC (permalink / raw)
To: gcc-patches; +Cc: Andrew Pinski
The problem here is even though we pass std namespace to lookup_template_class
as the context, it will look at the current scope for the name too.
The fix is to lookup the qualified name first and then use that
for lookup_template_class.
This is how std::initializer_list is handled in listify.
Note g++.dg/cpp1z/decomp22.C testcase now fails correctly
with an error, that tuple_size is not in the std namespace.
I copied a fixed up testcase into g++.dg/cpp1z/decomp62.C.
Bootstrapped and tested on x86_64-linux-gnu with no regressions.
PR c++/115605
gcc/cp/ChangeLog:
* decl.cc (get_tuple_size): Call lookup_qualified_name
before calling lookup_template_class.
(get_tuple_element_type): Likewise.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/decomp22.C: Expect an error
* g++.dg/cpp1z/decomp61.C: New test.
* g++.dg/cpp1z/decomp62.C: Copied from decomp22.C
and wrap tuple_size/tuple_element inside std namespace.
Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
---
gcc/cp/decl.cc | 16 +++++---
gcc/testsuite/g++.dg/cpp1z/decomp22.C | 2 +-
gcc/testsuite/g++.dg/cpp1z/decomp61.C | 53 +++++++++++++++++++++++++++
gcc/testsuite/g++.dg/cpp1z/decomp62.C | 23 ++++++++++++
4 files changed, 88 insertions(+), 6 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp61.C
create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp62.C
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
index 03deb1493a4..81dde4d51a3 100644
--- a/gcc/cp/decl.cc
+++ b/gcc/cp/decl.cc
@@ -9195,10 +9195,13 @@ get_tuple_size (tree type)
{
tree args = make_tree_vec (1);
TREE_VEC_ELT (args, 0) = type;
- tree inst = lookup_template_class (tuple_size_identifier, args,
+ tree std_tuple_size = lookup_qualified_name (std_node, tuple_size_identifier);
+ if (std_tuple_size == error_mark_node)
+ return NULL_TREE;
+ tree inst = lookup_template_class (std_tuple_size, args,
/*in_decl*/NULL_TREE,
- /*context*/std_node,
- tf_none);
+ /*context*/NULL_TREE,
+ tf_warning_or_error);
inst = complete_type (inst);
if (inst == error_mark_node
|| !COMPLETE_TYPE_P (inst)
@@ -9224,9 +9227,12 @@ get_tuple_element_type (tree type, unsigned i)
tree args = make_tree_vec (2);
TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
TREE_VEC_ELT (args, 1) = type;
- tree inst = lookup_template_class (tuple_element_identifier, args,
+ tree std_tuple_elem = lookup_qualified_name (std_node, tuple_element_identifier);
+ if (std_tuple_elem == error_mark_node)
+ return NULL_TREE;
+ tree inst = lookup_template_class (std_tuple_elem, args,
/*in_decl*/NULL_TREE,
- /*context*/std_node,
+ /*context*/NULL_TREE,
tf_warning_or_error);
return make_typename_type (inst, type_identifier,
none_type, tf_warning_or_error);
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp22.C b/gcc/testsuite/g++.dg/cpp1z/decomp22.C
index 9e6b8df486a..4131486e292 100644
--- a/gcc/testsuite/g++.dg/cpp1z/decomp22.C
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp22.C
@@ -17,5 +17,5 @@ int
foo (C<int> t)
{
auto[x0] = t; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
- return x0;
+ return x0; /* { dg-error "cannot convert" } */
}
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp61.C b/gcc/testsuite/g++.dg/cpp1z/decomp61.C
new file mode 100644
index 00000000000..874844b2c61
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp61.C
@@ -0,0 +1,53 @@
+// PR c++/115605
+// { dg-do compile { target c++17 } }
+// { dg-options "" }
+
+using size_t = decltype(sizeof(0));
+
+namespace std
+{
+ template<class T>
+ struct tuple_size;
+ template<size_t, class>
+ struct tuple_element;
+}
+
+struct mytuple
+{
+ int t;
+ template<size_t>
+ int &get()
+ {
+ return t;
+ }
+};
+
+namespace std
+{
+ template<>
+ struct tuple_size<mytuple>
+ {
+ static constexpr int value = 3;
+ };
+ template<size_t I>
+ struct tuple_element<I, mytuple>
+ {
+ using type = int;
+ };
+}
+
+/* The tuple_size/tuple_element lookup should only be from std and not
+ from the current scope so these 2 functions should work. */
+int foo() {
+ int const tuple_size = 5;
+ mytuple array;
+ auto [a, b, c] = array;
+ return c;
+}
+int foo1() {
+ int const tuple_element = 5;
+ mytuple array;
+ auto [a, b, c] = array;
+ return c;
+}
+
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp62.C b/gcc/testsuite/g++.dg/cpp1z/decomp62.C
new file mode 100644
index 00000000000..694f3263bd8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp62.C
@@ -0,0 +1,23 @@
+// PR c++/79205
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+template <unsigned long, typename...> struct B;
+template <unsigned long I, typename H> struct B<I, H> { int b; };
+template <typename... E> struct C { B<0, E...> c; C (C &) = default; C (C &&); };
+namespace std {
+ template <typename> struct tuple_size;
+ template <> struct tuple_size<C<int>> { static constexpr int value = 1; };
+ template <int, typename> struct tuple_element;
+ template <typename H, typename... T>
+ struct tuple_element<0, C<H, T...>> { typedef int type; };
+}
+template <int, typename... E>
+int &&get (C<E...> &&);
+
+int
+foo (C<int> t)
+{
+ auto[x0] = t; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
+ return x0;
+}
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [PATCH] c++: structured bindings and lookup of tuple_size/tuple_element [PR115605]
2024-06-25 5:00 [PATCH] c++: structured bindings and lookup of tuple_size/tuple_element [PR115605] Andrew Pinski
@ 2024-06-25 16:20 ` Marek Polacek
0 siblings, 0 replies; 2+ messages in thread
From: Marek Polacek @ 2024-06-25 16:20 UTC (permalink / raw)
To: Andrew Pinski; +Cc: gcc-patches
On Mon, Jun 24, 2024 at 10:00:40PM -0700, Andrew Pinski wrote:
> The problem here is even though we pass std namespace to lookup_template_class
> as the context, it will look at the current scope for the name too.
> The fix is to lookup the qualified name first and then use that
> for lookup_template_class.
> This is how std::initializer_list is handled in listify.
>
> Note g++.dg/cpp1z/decomp22.C testcase now fails correctly
> with an error, that tuple_size is not in the std namespace.
> I copied a fixed up testcase into g++.dg/cpp1z/decomp62.C.
>
> Bootstrapped and tested on x86_64-linux-gnu with no regressions.
>
> PR c++/115605
>
> gcc/cp/ChangeLog:
>
> * decl.cc (get_tuple_size): Call lookup_qualified_name
> before calling lookup_template_class.
> (get_tuple_element_type): Likewise.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/cpp1z/decomp22.C: Expect an error
Missing .
> * g++.dg/cpp1z/decomp61.C: New test.
> * g++.dg/cpp1z/decomp62.C: Copied from decomp22.C
> and wrap tuple_size/tuple_element inside std namespace.
>
> Signed-off-by: Andrew Pinski <quic_apinski@quicinc.com>
> ---
> gcc/cp/decl.cc | 16 +++++---
> gcc/testsuite/g++.dg/cpp1z/decomp22.C | 2 +-
> gcc/testsuite/g++.dg/cpp1z/decomp61.C | 53 +++++++++++++++++++++++++++
> gcc/testsuite/g++.dg/cpp1z/decomp62.C | 23 ++++++++++++
> 4 files changed, 88 insertions(+), 6 deletions(-)
> create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp61.C
> create mode 100644 gcc/testsuite/g++.dg/cpp1z/decomp62.C
>
> diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc
> index 03deb1493a4..81dde4d51a3 100644
> --- a/gcc/cp/decl.cc
> +++ b/gcc/cp/decl.cc
> @@ -9195,10 +9195,13 @@ get_tuple_size (tree type)
> {
> tree args = make_tree_vec (1);
> TREE_VEC_ELT (args, 0) = type;
> - tree inst = lookup_template_class (tuple_size_identifier, args,
> + tree std_tuple_size = lookup_qualified_name (std_node, tuple_size_identifier);
> + if (std_tuple_size == error_mark_node)
> + return NULL_TREE;
> + tree inst = lookup_template_class (std_tuple_size, args,
> /*in_decl*/NULL_TREE,
> - /*context*/std_node,
> - tf_none);
> + /*context*/NULL_TREE,
> + tf_warning_or_error);
> inst = complete_type (inst);
> if (inst == error_mark_node
> || !COMPLETE_TYPE_P (inst)
> @@ -9224,9 +9227,12 @@ get_tuple_element_type (tree type, unsigned i)
> tree args = make_tree_vec (2);
> TREE_VEC_ELT (args, 0) = build_int_cst (integer_type_node, i);
> TREE_VEC_ELT (args, 1) = type;
> - tree inst = lookup_template_class (tuple_element_identifier, args,
> + tree std_tuple_elem = lookup_qualified_name (std_node, tuple_element_identifier);
This line is too long.
> + if (std_tuple_elem == error_mark_node)
> + return NULL_TREE;
> + tree inst = lookup_template_class (std_tuple_elem, args,
> /*in_decl*/NULL_TREE,
> - /*context*/std_node,
> + /*context*/NULL_TREE,
> tf_warning_or_error);
> return make_typename_type (inst, type_identifier,
> none_type, tf_warning_or_error);
> diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp22.C b/gcc/testsuite/g++.dg/cpp1z/decomp22.C
> index 9e6b8df486a..4131486e292 100644
> --- a/gcc/testsuite/g++.dg/cpp1z/decomp22.C
> +++ b/gcc/testsuite/g++.dg/cpp1z/decomp22.C
> @@ -17,5 +17,5 @@ int
> foo (C<int> t)
> {
> auto[x0] = t; // { dg-warning "structured bindings only available with" "" { target c++14_down } }
> - return x0;
> + return x0; /* { dg-error "cannot convert" } */
> }
> diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp61.C b/gcc/testsuite/g++.dg/cpp1z/decomp61.C
> new file mode 100644
> index 00000000000..874844b2c61
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/cpp1z/decomp61.C
> @@ -0,0 +1,53 @@
> +// PR c++/115605
> +// { dg-do compile { target c++17 } }
> +// { dg-options "" }
(I don't think you need the empty dg-options here.)
The patch looks good to me otherwise, thanks.
Marek
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-06-25 16:20 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-25 5:00 [PATCH] c++: structured bindings and lookup of tuple_size/tuple_element [PR115605] Andrew Pinski
2024-06-25 16:20 ` Marek Polacek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).