public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r13-4460] c++: Deduce range for structured bindings if expression is not type dependent [PR84469]
@ 2022-12-02  9:34 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2022-12-02  9:34 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ee4f25999f6832a1c5060b9277222c03d852709a

commit r13-4460-gee4f25999f6832a1c5060b9277222c03d852709a
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Fri Dec 2 10:29:11 2022 +0100

    c++: Deduce range for structured bindings if expression is not type dependent [PR84469]
    
    As shown on the decomp56.C testcase, if the range for expression
    when using structured bindings is not type dependent, we deduce
    the finish the structured binding types only when not in template
    (cp_convert_range_for takes care of that), but if in templates,
    do_range_for_auto_deduction is called instead and it doesn't handle
    structured bindings.  During instantiation they are handled later,
    but during the parsing keeping the structured bindings type
    dependent when they shouldn't be changes behavior.
    The following patch calls cp_finish_decomp even from
    do_range_for_auto_deduction.
    The patch regresses the OpenMP g++.dg/gomp/for-21.C test (3 errors
    are gone), I'll post an incremental patch for it momentarily.
    
    2022-12-02  Jakub Jelinek  <jakub@redhat.com>
    
            PR c++/84469
            * parser.cc (do_range_for_auto_deduction): Add DECOMP_FIRST_NAME
            and DECOMP_CNT arguments.  Call cp_finish_decomp if DECL
            is a structured binding.
            (cp_parser_range_for): Adjust do_range_for_auto_deduction caller.
            (cp_convert_omp_range_for): Likewise.
    
            * g++.dg/cpp1z/decomp56.C: New test.
            * g++.dg/gomp/pr84469.C: New test.

Diff:
---
 gcc/cp/parser.cc                      | 20 +++++++++++++++-----
 gcc/testsuite/g++.dg/cpp1z/decomp56.C | 29 +++++++++++++++++++++++++++++
 gcc/testsuite/g++.dg/gomp/pr84469.C   | 24 ++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 5 deletions(-)

diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc
index a13fbe41309..e69097d670b 100644
--- a/gcc/cp/parser.cc
+++ b/gcc/cp/parser.cc
@@ -2342,7 +2342,7 @@ static tree cp_parser_c_for
 static tree cp_parser_range_for
   (cp_parser *, tree, tree, tree, bool, unsigned short, bool);
 static void do_range_for_auto_deduction
-  (tree, tree);
+  (tree, tree, tree, unsigned int);
 static tree cp_parser_perform_range_for_lookup
   (tree, tree *, tree *);
 static tree cp_parser_range_for_member_function
@@ -13668,7 +13668,8 @@ cp_parser_range_for (cp_parser *parser, tree scope, tree init, tree range_decl,
       if (!type_dependent_expression_p (range_expr)
 	  /* do_auto_deduction doesn't mess with template init-lists.  */
 	  && !BRACE_ENCLOSED_INITIALIZER_P (range_expr))
-	do_range_for_auto_deduction (range_decl, range_expr);
+	do_range_for_auto_deduction (range_decl, range_expr, decomp_first_name,
+				     decomp_cnt);
     }
   else
     {
@@ -13707,7 +13708,8 @@ build_range_temp (tree range_expr)
    a shortcut version of cp_convert_range_for.  */
 
 static void
-do_range_for_auto_deduction (tree decl, tree range_expr)
+do_range_for_auto_deduction (tree decl, tree range_expr,
+			     tree decomp_first_name, unsigned int decomp_cnt)
 {
   tree auto_node = type_uses_auto (TREE_TYPE (decl));
   if (auto_node)
@@ -13727,6 +13729,8 @@ do_range_for_auto_deduction (tree decl, tree range_expr)
 						iter_decl, auto_node,
 						tf_warning_or_error,
 						adc_variable_type);
+	  if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl))
+	    cp_finish_decomp (decl, decomp_first_name, decomp_cnt);
 	}
     }
 }
@@ -42994,15 +42998,21 @@ cp_convert_omp_range_for (tree &this_pre_body, vec<tree, va_gc> *for_block,
 	  && !BRACE_ENCLOSED_INITIALIZER_P (init))
 	{
 	  tree d = decl;
+	  tree decomp_first_name = NULL_TREE;
+	  unsigned decomp_cnt = 0;
 	  if (decl != error_mark_node && DECL_HAS_VALUE_EXPR_P (decl))
 	    {
 	      tree v = DECL_VALUE_EXPR (decl);
 	      if (TREE_CODE (v) == ARRAY_REF
 		  && VAR_P (TREE_OPERAND (v, 0))
 		  && DECL_DECOMPOSITION_P (TREE_OPERAND (v, 0)))
-		d = TREE_OPERAND (v, 0);
+		{
+		  d = TREE_OPERAND (v, 0);
+		  decomp_cnt = tree_to_uhwi (TREE_OPERAND (v, 1)) + 1;
+		  decomp_first_name = decl;
+		}
 	    }
-	  do_range_for_auto_deduction (d, init);
+	  do_range_for_auto_deduction (d, init, decomp_first_name, decomp_cnt);
 	}
       cond = global_namespace;
       incr = NULL_TREE;
diff --git a/gcc/testsuite/g++.dg/cpp1z/decomp56.C b/gcc/testsuite/g++.dg/cpp1z/decomp56.C
new file mode 100644
index 00000000000..25a4c3def6b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1z/decomp56.C
@@ -0,0 +1,29 @@
+// PR c++/84469
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A {
+  template <typename T>
+  void bar () const {}
+  template <typename T>
+  void baz () const {}
+};
+struct B { A a; };
+
+template <typename>
+void
+foo ()
+{
+  A a[1][1];
+  for (auto const& [b]: a)	// { dg-warning "structured bindings only available with" "" { target c++14_down } }
+    b.bar<int> ();
+  B c;
+  auto const& [d] = c;		// { dg-warning "structured bindings only available with" "" { target c++14_down } }
+  d.baz<double> ();
+}
+
+int
+main ()
+{
+  foo<int> ();
+}
diff --git a/gcc/testsuite/g++.dg/gomp/pr84469.C b/gcc/testsuite/g++.dg/gomp/pr84469.C
new file mode 100644
index 00000000000..973debf14dd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/gomp/pr84469.C
@@ -0,0 +1,24 @@
+// PR c++/84469
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A {
+  template <typename T>
+  void bar () const {}
+};
+
+template <typename>
+void
+foo ()
+{
+  A a[1][1];
+  #pragma omp for
+  for (auto const& [b]: a)	// { dg-warning "structured bindings only available with" "" { target c++14_down } }
+    b.bar<int> ();
+}
+
+int
+main ()
+{
+  foo<int> ();
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-02  9:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-02  9:34 [gcc r13-4460] c++: Deduce range for structured bindings if expression is not type dependent [PR84469] Jakub Jelinek

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).