public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
@ 2017-11-29 22:35 Jakub Jelinek
  2017-11-30  2:42 ` Martin Sebor
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-11-29 22:35 UTC (permalink / raw)
  To: Jason Merrill; +Cc: gcc-patches

Hi!

If tsize doesn't fit into uhwi, then it obviously can't match the number of
identifiers in the structured binding declaration.  While we could use
compare_tree_int and avoid that way this conversion to uhwi (though,
compare_tree_int does that anyway), for the normal uhwi case we have special
cases in cnt_mismatch shared by the other kinds of structured bindings
that handle smaller and larger cases separately, so I think it is better
to do it this way.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2017-11-29  Jakub Jelinek  <jakub@redhat.com>

	PR c++/83205
	* decl.c (cp_finish_decomp): Handle the case when tsize is not
	error_mark_node, but doesn't fit into uhwi.

	* g++.dg/cpp1z/decomp32.C: New test.

--- gcc/cp/decl.c.jj	2017-11-28 22:23:34.000000000 +0100
+++ gcc/cp/decl.c	2017-11-29 15:00:24.487658715 +0100
@@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first,
 			 "constant expression", type);
 	  goto error_out;
 	}
+      if (!tree_fits_uhwi_p (tsize))
+	{
+	  error_at (loc, "%u names provided while %qT decomposes into "
+			 "%E elements", count, type, tsize);
+	  goto error_out;
+	}
       eltscnt = tree_to_uhwi (tsize);
       if (count != eltscnt)
 	goto cnt_mismatch;
--- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj	2017-11-29 15:08:59.215378903 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp32.C	2017-11-29 15:10:31.576244649 +0100
@@ -0,0 +1,24 @@
+// PR c++/83205
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A { int i; };
+struct B { int i; };
+namespace std {
+  template <typename T> struct tuple_size;
+  template <> struct tuple_size<A> {
+    static constexpr int value = -1;
+  };
+#ifdef __SIZEOF_INT128__
+  template <> struct tuple_size<B> {
+    static constexpr unsigned __int128 value = -1;
+  };
+#endif
+}
+
+auto [a] = A{};	// { dg-error "1 names provided while 'A' decomposes into -1 elements" }
+		// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+#ifdef __SIZEOF_INT128__
+auto [b] = B{};	// { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } }
+		// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 }
+#endif

	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
  2017-11-29 22:35 [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jakub Jelinek
@ 2017-11-30  2:42 ` Martin Sebor
  2017-11-30  9:26   ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek
  2017-12-15 19:01   ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill
  0 siblings, 2 replies; 12+ messages in thread
From: Martin Sebor @ 2017-11-30  2:42 UTC (permalink / raw)
  To: Jakub Jelinek, Jason Merrill; +Cc: gcc-patches

On 11/29/2017 03:32 PM, Jakub Jelinek wrote:
> Hi!
>
> If tsize doesn't fit into uhwi, then it obviously can't match the number of
> identifiers in the structured binding declaration.  While we could use
> compare_tree_int and avoid that way this conversion to uhwi (though,
> compare_tree_int does that anyway), for the normal uhwi case we have special
> cases in cnt_mismatch shared by the other kinds of structured bindings
> that handle smaller and larger cases separately, so I think it is better
> to do it this way.
>
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
>
> 2017-11-29  Jakub Jelinek  <jakub@redhat.com>
>
> 	PR c++/83205
> 	* decl.c (cp_finish_decomp): Handle the case when tsize is not
> 	error_mark_node, but doesn't fit into uhwi.
>
> 	* g++.dg/cpp1z/decomp32.C: New test.
>
> --- gcc/cp/decl.c.jj	2017-11-28 22:23:34.000000000 +0100
> +++ gcc/cp/decl.c	2017-11-29 15:00:24.487658715 +0100
> @@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first,
>  			 "constant expression", type);
>  	  goto error_out;
>  	}
> +      if (!tree_fits_uhwi_p (tsize))
> +	{
> +	  error_at (loc, "%u names provided while %qT decomposes into "

When count is 1 as in the test below the error isn't grammatically
correct ("1 names").  I see that the same message is already issued
elsewhere in the function so this seems like an opportunity to use
the right form here and also fix the other one at the same time or
in a followup.  The error_n function exists to issue the right form
for the language, singular or plural.  It's not as convenient when
the sentence contains two terms that may be singular or plural,
but that can also be dealt with.

Martin

> +			 "%E elements", count, type, tsize);
> +	  goto error_out;
> +	}
>        eltscnt = tree_to_uhwi (tsize);
>        if (count != eltscnt)
>  	goto cnt_mismatch;
> --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj	2017-11-29 15:08:59.215378903 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C	2017-11-29 15:10:31.576244649 +0100
> @@ -0,0 +1,24 @@
> +// PR c++/83205
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +struct A { int i; };
> +struct B { int i; };
> +namespace std {
> +  template <typename T> struct tuple_size;
> +  template <> struct tuple_size<A> {
> +    static constexpr int value = -1;
> +  };
> +#ifdef __SIZEOF_INT128__
> +  template <> struct tuple_size<B> {
> +    static constexpr unsigned __int128 value = -1;
> +  };
> +#endif
> +}
> +
> +auto [a] = A{};	// { dg-error "1 names provided while 'A' decomposes into -1 elements" }
> +		// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
> +#ifdef __SIZEOF_INT128__
> +auto [b] = B{};	// { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } }
> +		// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 }
> +#endif
>
> 	Jakub
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30  2:42 ` Martin Sebor
@ 2017-11-30  9:26   ` Jakub Jelinek
  2017-11-30 11:59     ` Nathan Sidwell
  2017-12-15 19:01   ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill
  1 sibling, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-11-30  9:26 UTC (permalink / raw)
  To: Martin Sebor, Nathan Sidwell, Jason Merrill; +Cc: gcc-patches

On Wed, Nov 29, 2017 at 06:19:04PM -0700, Martin Sebor wrote:
> > --- gcc/cp/decl.c.jj	2017-11-28 22:23:34.000000000 +0100
> > +++ gcc/cp/decl.c	2017-11-29 15:00:24.487658715 +0100
> > @@ -7518,6 +7518,12 @@ cp_finish_decomp (tree decl, tree first,
> >  			 "constant expression", type);
> >  	  goto error_out;
> >  	}
> > +      if (!tree_fits_uhwi_p (tsize))
> > +	{
> > +	  error_at (loc, "%u names provided while %qT decomposes into "
> 
> When count is 1 as in the test below the error isn't grammatically
> correct ("1 names").  I see that the same message is already issued
> elsewhere in the function so this seems like an opportunity to use
> the right form here and also fix the other one at the same time or
> in a followup.  The error_n function exists to issue the right form
> for the language, singular or plural.  It's not as convenient when
> the sentence contains two terms that may be singular or plural,
> but that can also be dealt with.

Here is an incremental patch to deal with that on top of the previously
posted patch, ok for trunk if it passes testing?  Note, not using inform_n
in this !tree_fits_uhwi_p case, because gettext doesn't recommend that for
negative values and the other values printed there (the very large ones) are
printed using hexadecimal where also I think human plural forms are rarely
useful.

2017-11-30  Jakub Jelinek  <jakub@redhat.com>

	* decl.c (cp_finish_decomp): Split up count != eltscnt and
	!tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n
	to handle plural forms properly.

	* g++.dg/cpp1z/decomp3.C: Adjust for structured binding count
	mismatch diagnostics split into error and warning with plural
	forms.
	* g++.dg/cpp1z/decomp10.C: Likewise.
	* g++.dg/cpp1z/decomp32.C: Likewise.

--- gcc/cp/decl.c.jj	2017-11-30 09:44:19.000000000 +0100
+++ gcc/cp/decl.c	2017-11-30 09:57:44.539504854 +0100
@@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first,
 	{
        cnt_mismatch:
 	  if (count > eltscnt)
-	    error_at (loc, "%u names provided while %qT decomposes into "
-			   "%wu elements", count, type, eltscnt);
+	    error_n (loc, count,
+		     "%u name provided for structured binding",
+		     "%u names provided for structured binding", count);
 	  else
-	    error_at (loc, "only %u names provided while %qT decomposes into "
-			   "%wu elements", count, type, eltscnt);
+	    error_n (loc, count,
+		     "only %u name provided for structured binding",
+		     "only %u names provided for structured binding", count);
+	  inform_n (loc, eltscnt != (unsigned long) eltscnt
+			 ? (eltscnt % 1000000) + 1000000 : eltscnt,
+		    "while %qT decomposes into %wu element",
+		    "while %qT decomposes into %wu elements",
+		    type, eltscnt);
 	  goto error_out;
 	}
       eltype = TREE_TYPE (type);
@@ -7520,8 +7527,11 @@ cp_finish_decomp (tree decl, tree first,
 	}
       if (!tree_fits_uhwi_p (tsize))
 	{
-	  error_at (loc, "%u names provided while %qT decomposes into "
-			 "%E elements", count, type, tsize);
+	  error_n (loc, count,
+		   "%u name provided for structured binding",
+		   "%u names provided for structured binding", count);
+	  inform (loc, "while %qT decomposes into %E elements",
+		  type, tsize);
 	  goto error_out;
 	}
       eltscnt = tree_to_uhwi (tsize);
--- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj	2017-09-15 18:11:04.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp3.C	2017-11-30 10:09:42.756619330 +0100
@@ -51,16 +51,21 @@ int arr[4];
 void
 test3 (A &b, B c)
 {
-  auto [ d, e, f ] = arr;		// { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto & [ g, h, i, j, k ] = arr;	// { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto [ l, m ] = b;			// { dg-error "only 2 names provided while 'A' decomposes into 3 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto & [ n, o, p, q ] = b;		// { dg-error "4 names provided while 'A' decomposes into 3 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
+  auto [ d, e, f ] = arr;		// { dg-error "only 3 names provided" }
+					// { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto & [ g, h, i, j, k ] = arr;	// { dg-error "5 names provided" }
+					// { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto [ l, m ] = b;			// { dg-error "only 2 names provided" }
+					// { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto & [ n, o, p, q ] = b;		// { dg-error "4 names provided" }
+					// { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
   auto [] { c };			// { dg-error "empty structured binding declaration" }
 					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto [ r, s ] = c;			// { dg-error "2 names provided while 'B' decomposes into 1 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
+  auto [ r, s ] = c;			// { dg-error "2 names provided" }
+					// { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
 }
--- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj	2017-09-15 18:11:04.000000000 +0200
+++ gcc/testsuite/g++.dg/cpp1z/decomp10.C	2017-11-30 10:03:08.356491129 +0100
@@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; }	// { dg-e
 
 struct A2 { int i,j; } a2;
 template<> struct std::tuple_size<A2> { enum { value = 5 }; };
-void f2() { auto [ x ] = a2; }	// { dg-error "decomposes into 5" }
+void f2() { auto [ x ] = a2; }	// { dg-error "only 1 name provided" }
+			        // { dg-message "decomposes into 5" "" { target *-*-* } .-1 }
 
 struct A3 { int i,j; } a3;
 template<> struct std::tuple_size<A3> { enum { value = 1 }; };
--- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj	2017-11-30 09:44:19.000000000 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp32.C	2017-11-30 10:09:53.126490397 +0100
@@ -16,9 +16,17 @@ namespace std {
 #endif
 }
 
-auto [a] = A{};	// { dg-error "1 names provided while 'A' decomposes into -1 elements" }
-		// { dg-warning "structured bindings only available with" "" { target c++14_down } .-1 }
+auto [a] = A{};	// { dg-error "1 name provided" }
+		// { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
+		// { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
 #ifdef __SIZEOF_INT128__
-auto [b] = B{};	// { dg-error "1 names provided while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } }
-		// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-1 }
+auto [b] = B{};	// { dg-error "1 name provided" }
+		// { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
+		// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
+auto [c, d] = B{};	// { dg-error "2 names provided" }
+			// { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
+			// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
 #endif
+auto [e, f, g] = A{};	// { dg-error "3 names provided" }
+			// { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
+			// { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }


	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30  9:26   ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek
@ 2017-11-30 11:59     ` Nathan Sidwell
  2017-11-30 12:09       ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Nathan Sidwell @ 2017-11-30 11:59 UTC (permalink / raw)
  To: Jakub Jelinek, Martin Sebor, Jason Merrill; +Cc: gcc-patches

On 11/30/2017 04:18 AM, Jakub Jelinek wrote:

> Here is an incremental patch to deal with that on top of the previously
> posted patch, ok for trunk if it passes testing?  Note, not using inform_n
> in this !tree_fits_uhwi_p case, because gettext doesn't recommend that for
> negative values and the other values printed there (the very large ones) are
> printed using hexadecimal where also I think human plural forms are rarely
> useful.
> 
> 2017-11-30  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* decl.c (cp_finish_decomp): Split up count != eltscnt and
> 	!tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n
> 	to handle plural forms properly.
> 
> 	* g++.dg/cpp1z/decomp3.C: Adjust for structured binding count
> 	mismatch diagnostics split into error and warning with plural
> 	forms.
> 	* g++.dg/cpp1z/decomp10.C: Likewise.
> 	* g++.dg/cpp1z/decomp32.C: Likewise.

Ok.

> --- gcc/cp/decl.c.jj	2017-11-30 09:44:19.000000000 +0100
> +++ gcc/cp/decl.c	2017-11-30 09:57:44.539504854 +0100
> @@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first,

> +	  inform_n (loc, eltscnt != (unsigned long) eltscnt
> +			 ? (eltscnt % 1000000) + 1000000 : eltscnt,

Is such elaboration with the modulo operator necessary? wouldn;t an 
arbitrary non-unity constant do.  (It took me a while to figure out what 
this was trying to do.  At least a comment?)

nathan

-- 
Nathan Sidwell

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30 11:59     ` Nathan Sidwell
@ 2017-11-30 12:09       ` Jakub Jelinek
  2017-11-30 13:01         ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-11-30 12:09 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches

On Thu, Nov 30, 2017 at 06:55:08AM -0500, Nathan Sidwell wrote:
> > --- gcc/cp/decl.c.jj	2017-11-30 09:44:19.000000000 +0100
> > +++ gcc/cp/decl.c	2017-11-30 09:57:44.539504854 +0100
> > @@ -7445,11 +7445,18 @@ cp_finish_decomp (tree decl, tree first,
> 
> > +	  inform_n (loc, eltscnt != (unsigned long) eltscnt
> > +			 ? (eltscnt % 1000000) + 1000000 : eltscnt,
> 
> Is such elaboration with the modulo operator necessary? wouldn;t an
> arbitrary non-unity constant do.  (It took me a while to figure out what
> this was trying to do.  At least a comment?)

For english it isn't needed of course.

I just followed:
https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html

"About larger integer types, such as ‘uintmax_t’ or ‘unsigned long long’: they can be
handled by reducing the value to a range that fits in an ‘unsigned long’. Simply
casting the value to ‘unsigned long’ would not do the right thing, since it would
treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you
can exploit the fact that all mentioned plural form formulas eventually become periodic,
with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large
value to another one in the range [1000000, 1999999] that ends in the same 6 decimal
digits, you can assume that it will lead to the same plural form selection. This code
does this:

#include <inttypes.h>
uintmax_t nbytes = ...;
printf (ngettext ("The file has %"PRIuMAX" byte.",
                  "The file has %"PRIuMAX" bytes.",
                  (nbytes > ULONG_MAX
                   ? (nbytes % 1000000) + 1000000
                   : nbytes)),
        nbytes);"

I can surely add a comment about that.

Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
patch.

	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30 12:09       ` Jakub Jelinek
@ 2017-11-30 13:01         ` Jakub Jelinek
  2017-11-30 13:47           ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-11-30 13:01 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches

On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote:
> I just followed:
> https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html
> 
> "About larger integer types, such as ‘uintmax_t’ or ‘unsigned long long’: they can be
> handled by reducing the value to a range that fits in an ‘unsigned long’. Simply
> casting the value to ‘unsigned long’ would not do the right thing, since it would
> treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you
> can exploit the fact that all mentioned plural form formulas eventually become periodic,
> with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large
> value to another one in the range [1000000, 1999999] that ends in the same 6 decimal
> digits, you can assume that it will lead to the same plural form selection. This code
> does this:
> 
> #include <inttypes.h>
> uintmax_t nbytes = ...;
> printf (ngettext ("The file has %"PRIuMAX" byte.",
>                   "The file has %"PRIuMAX" bytes.",
>                   (nbytes > ULONG_MAX
>                    ? (nbytes % 1000000) + 1000000
>                    : nbytes)),
>         nbytes);"
> 
> I can surely add a comment about that.
> 
> Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
> patch.

Though, looking at our *_n diagnostic routines, the n argument is actually
int there, not unsigned long for some reason.  So, either we should fix
that (seems ngettext has unsigned long), or the above would need to be
(unsigned HOST_WIDE_INT) (int) eltscnt != eltscnt || (int) eltscnt < 0 

	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30 13:01         ` Jakub Jelinek
@ 2017-11-30 13:47           ` Jakub Jelinek
  2017-11-30 15:51             ` Pedro Alves
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-11-30 13:47 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches

On Thu, Nov 30, 2017 at 01:33:48PM +0100, Jakub Jelinek wrote:
> On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote:
> > I just followed:
> > https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html
> > 
> > "About larger integer types, such as ‘uintmax_t’ or ‘unsigned long long’: they can be
> > handled by reducing the value to a range that fits in an ‘unsigned long’. Simply
> > casting the value to ‘unsigned long’ would not do the right thing, since it would
> > treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you
> > can exploit the fact that all mentioned plural form formulas eventually become periodic,
> > with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large
> > value to another one in the range [1000000, 1999999] that ends in the same 6 decimal
> > digits, you can assume that it will lead to the same plural form selection. This code
> > does this:
> > 
> > #include <inttypes.h>
> > uintmax_t nbytes = ...;
> > printf (ngettext ("The file has %"PRIuMAX" byte.",
> >                   "The file has %"PRIuMAX" bytes.",
> >                   (nbytes > ULONG_MAX
> >                    ? (nbytes % 1000000) + 1000000
> >                    : nbytes)),
> >         nbytes);"
> > 
> > I can surely add a comment about that.
> > 
> > Note the patch depends on the https://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
> > patch.
> 
> Though, looking at our *_n diagnostic routines, the n argument is actually
> int there, not unsigned long for some reason.  So, either we should fix
> that (seems ngettext has unsigned long), or the above would need to be
> (unsigned HOST_WIDE_INT) (int) eltscnt != eltscnt || (int) eltscnt < 0 

Of course better eltscnt > INT_MAX

	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics
  2017-11-30 13:47           ` Jakub Jelinek
@ 2017-11-30 15:51             ` Pedro Alves
  0 siblings, 0 replies; 12+ messages in thread
From: Pedro Alves @ 2017-11-30 15:51 UTC (permalink / raw)
  To: Jakub Jelinek, Nathan Sidwell; +Cc: Martin Sebor, Jason Merrill, gcc-patches

On 11/30/2017 01:10 PM, Jakub Jelinek wrote:
> On Thu, Nov 30, 2017 at 01:33:48PM +0100, Jakub Jelinek wrote:
>> On Thu, Nov 30, 2017 at 01:01:58PM +0100, Jakub Jelinek wrote:
>>> I just followed:
>>> https://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/Plural-forms.html
>>>
>>> "About larger integer types, such as ‘uintmax_t’ or ‘unsigned long long’: they can be
>>> handled by reducing the value to a range that fits in an ‘unsigned long’. Simply
>>> casting the value to ‘unsigned long’ would not do the right thing, since it would
>>> treat ULONG_MAX + 1 like zero, ULONG_MAX + 2 like singular, and the like. Here you
>>> can exploit the fact that all mentioned plural form formulas eventually become periodic,
>>> with a period that is a divisor of 100 (or 1000 or 1000000). So, when you reduce a large
>>> value to another one in the range [1000000, 1999999] that ends in the same 6 decimal
>>> digits, you can assume that it will lead to the same plural form selection. This code
>>> does this:
>>>
>>> #include <inttypes.h>
>>> uintmax_t nbytes = ...;
>>> printf (ngettext ("The file has %"PRIuMAX" byte.",
>>>                   "The file has %"PRIuMAX" bytes.",
>>>                   (nbytes > ULONG_MAX
>>>                    ? (nbytes % 1000000) + 1000000
>>>                    : nbytes)),
>>>         nbytes);"
>>>
>>> I can surely add a comment about that.

How about wrapping it in a function to make it self-describing?
Something around:

/* Comment/url here.  */

unsigned long
plural_form_for (unsigned HOST_WIDE_INT val)
{
  return (val > ULONG_MAX
          ? (val % 1000000) + 1000000
          : val);
}

and then:

	  inform_n (loc, plural_form_for (eltscnt),
		    "while %qT decomposes into %wu element",
		    "while %qT decomposes into %wu elements",
		    type, eltscnt);

Pedro Alves

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
  2017-11-30  2:42 ` Martin Sebor
  2017-11-30  9:26   ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek
@ 2017-12-15 19:01   ` Jason Merrill
  2017-12-15 19:09     ` Jakub Jelinek
  1 sibling, 1 reply; 12+ messages in thread
From: Jason Merrill @ 2017-12-15 19:01 UTC (permalink / raw)
  To: Martin Sebor, Jakub Jelinek; +Cc: gcc-patches

On 11/29/2017 08:19 PM, Martin Sebor wrote:
> On 11/29/2017 03:32 PM, Jakub Jelinek wrote:
>> +      if (!tree_fits_uhwi_p (tsize))
>> +    {
>> +      error_at (loc, "%u names provided while %qT decomposes into "
> 
> When count is 1 as in the test below the error isn't grammatically
> correct ("1 names").  I see that the same message is already issued
> elsewhere in the function so this seems like an opportunity to use
> the right form here and also fix the other one at the same time or
> in a followup.  The error_n function exists to issue the right form
> for the language, singular or plural.  It's not as convenient when
> the sentence contains two terms that may be singular or plural,
> but that can also be dealt with.

Agreed.

Jason

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
  2017-12-15 19:01   ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill
@ 2017-12-15 19:09     ` Jakub Jelinek
  2017-12-15 19:46       ` Jakub Jelinek
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-12-15 19:09 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Martin Sebor, gcc-patches

On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote:
> On 11/29/2017 08:19 PM, Martin Sebor wrote:
> > On 11/29/2017 03:32 PM, Jakub Jelinek wrote:
> > > +      if (!tree_fits_uhwi_p (tsize))
> > > +    {
> > > +      error_at (loc, "%u names provided while %qT decomposes into "
> > 
> > When count is 1 as in the test below the error isn't grammatically
> > correct ("1 names").  I see that the same message is already issued
> > elsewhere in the function so this seems like an opportunity to use
> > the right form here and also fix the other one at the same time or
> > in a followup.  The error_n function exists to issue the right form
> > for the language, singular or plural.  It's not as convenient when
> > the sentence contains two terms that may be singular or plural,
> > but that can also be dealt with.
> 
> Agreed.

Yeah, I've implemented it as an incremental patch.
So
http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
for the ICE and
http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html
on top of it.  The latter is what Nathan approved already, the former
needs review.

	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
  2017-12-15 19:09     ` Jakub Jelinek
@ 2017-12-15 19:46       ` Jakub Jelinek
  2017-12-15 21:16         ` Jason Merrill
  0 siblings, 1 reply; 12+ messages in thread
From: Jakub Jelinek @ 2017-12-15 19:46 UTC (permalink / raw)
  To: Jason Merrill; +Cc: Martin Sebor, gcc-patches

On Fri, Dec 15, 2017 at 08:09:20PM +0100, Jakub Jelinek wrote:
> On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote:
> > On 11/29/2017 08:19 PM, Martin Sebor wrote:
> > > On 11/29/2017 03:32 PM, Jakub Jelinek wrote:
> > > > +      if (!tree_fits_uhwi_p (tsize))
> > > > +    {
> > > > +      error_at (loc, "%u names provided while %qT decomposes into "
> > > 
> > > When count is 1 as in the test below the error isn't grammatically
> > > correct ("1 names").  I see that the same message is already issued
> > > elsewhere in the function so this seems like an opportunity to use
> > > the right form here and also fix the other one at the same time or
> > > in a followup.  The error_n function exists to issue the right form
> > > for the language, singular or plural.  It's not as convenient when
> > > the sentence contains two terms that may be singular or plural,
> > > but that can also be dealt with.
> > 
> > Agreed.
> 
> Yeah, I've implemented it as an incremental patch.
> So
> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
> for the ICE and
> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html
> on top of it.  The latter is what Nathan approved already, the former
> needs review.

If it helps any, here are the 2 patches combined, re-tested on x86_64-linux
with check-c++-all.

2017-12-15  Jakub Jelinek  <jakub@redhat.com>

	PR c++/83205
	* decl.c (cp_finish_decomp): Handle the case when tsize is not
	error_mark_node, but doesn't fit into uhwi.  Split up count != eltscnt
	and !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n
	to handle plural forms properly.

	* g++.dg/cpp1z/decomp3.C: Adjust for structured binding count
	mismatch diagnostics split into error and warning with plural
	forms.
	* g++.dg/cpp1z/decomp10.C: Likewise.
	* g++.dg/cpp1z/decomp32.C: New test.

--- gcc/cp/decl.c.jj	2017-12-15 20:40:00.601221086 +0100
+++ gcc/cp/decl.c	2017-12-15 20:42:25.917445216 +0100
@@ -7427,11 +7427,20 @@ cp_finish_decomp (tree decl, tree first,
 	{
        cnt_mismatch:
 	  if (count > eltscnt)
-	    error_at (loc, "%u names provided while %qT decomposes into "
-			   "%wu elements", count, type, eltscnt);
+	    error_n (loc, count,
+		     "%u name provided for structured binding",
+		     "%u names provided for structured binding", count);
 	  else
-	    error_at (loc, "only %u names provided while %qT decomposes into "
-			   "%wu elements", count, type, eltscnt);
+	    error_n (loc, count,
+		     "only %u name provided for structured binding",
+		     "only %u names provided for structured binding", count);
+	  /* Some languages have special plural rules even for large values,
+	     but it is periodic with period of 10, 100, 1000 etc.  */
+	  inform_n (loc, eltscnt > INT_MAX
+			 ? (eltscnt % 1000000) + 1000000 : eltscnt,
+		    "while %qT decomposes into %wu element",
+		    "while %qT decomposes into %wu elements",
+		    type, eltscnt);
 	  goto error_out;
 	}
       eltype = TREE_TYPE (type);
@@ -7500,6 +7509,15 @@ cp_finish_decomp (tree decl, tree first,
 			 "constant expression", type);
 	  goto error_out;
 	}
+      if (!tree_fits_uhwi_p (tsize))
+	{
+	  error_n (loc, count,
+		   "%u name provided for structured binding",
+		   "%u names provided for structured binding", count);
+	  inform (loc, "while %qT decomposes into %E elements",
+		  type, tsize);
+	  goto error_out;
+	}
       eltscnt = tree_to_uhwi (tsize);
       if (count != eltscnt)
 	goto cnt_mismatch;
--- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj	2017-11-30 11:18:00.078805693 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp3.C	2017-12-15 20:42:25.917445216 +0100
@@ -51,16 +51,21 @@ int arr[4];
 void
 test3 (A &b, B c)
 {
-  auto [ d, e, f ] = arr;		// { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto & [ g, h, i, j, k ] = arr;	// { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto [ l, m ] = b;			// { dg-error "only 2 names provided while 'A' decomposes into 3 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto & [ n, o, p, q ] = b;		// { dg-error "4 names provided while 'A' decomposes into 3 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
+  auto [ d, e, f ] = arr;		// { dg-error "only 3 names provided" }
+					// { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto & [ g, h, i, j, k ] = arr;	// { dg-error "5 names provided" }
+					// { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto [ l, m ] = b;			// { dg-error "only 2 names provided" }
+					// { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
+  auto & [ n, o, p, q ] = b;		// { dg-error "4 names provided" }
+					// { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
   auto [] { c };			// { dg-error "empty structured binding declaration" }
 					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
-  auto [ r, s ] = c;			// { dg-error "2 names provided while 'B' decomposes into 1 elements" }
-					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
+  auto [ r, s ] = c;			// { dg-error "2 names provided" }
+					// { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 }
+					// { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
 }
--- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj	2017-11-30 11:18:00.102805393 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp10.C	2017-12-15 20:42:25.918445204 +0100
@@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; }	// { dg-e
 
 struct A2 { int i,j; } a2;
 template<> struct std::tuple_size<A2> { enum { value = 5 }; };
-void f2() { auto [ x ] = a2; }	// { dg-error "decomposes into 5" }
+void f2() { auto [ x ] = a2; }	// { dg-error "only 1 name provided" }
+			        // { dg-message "decomposes into 5" "" { target *-*-* } .-1 }
 
 struct A3 { int i,j; } a3;
 template<> struct std::tuple_size<A3> { enum { value = 1 }; };
--- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj	2017-12-15 20:42:58.977041204 +0100
+++ gcc/testsuite/g++.dg/cpp1z/decomp32.C	2017-12-15 20:42:25.918445204 +0100
@@ -0,0 +1,32 @@
+// PR c++/83205
+// { dg-do compile { target c++11 } }
+// { dg-options "" }
+
+struct A { int i; };
+struct B { int i; };
+namespace std {
+  template <typename T> struct tuple_size;
+  template <> struct tuple_size<A> {
+    static constexpr int value = -1;
+  };
+#ifdef __SIZEOF_INT128__
+  template <> struct tuple_size<B> {
+    static constexpr unsigned __int128 value = -1;
+  };
+#endif
+}
+
+auto [a] = A{};	// { dg-error "1 name provided" }
+		// { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
+		// { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
+#ifdef __SIZEOF_INT128__
+auto [b] = B{};	// { dg-error "1 name provided" "" { target int128 } }
+		// { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
+		// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
+auto [c, d] = B{};	// { dg-error "2 names provided" "" { target int128 } }
+			// { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
+			// { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
+#endif
+auto [e, f, g] = A{};	// { dg-error "3 names provided" }
+			// { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
+			// { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }


	Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205)
  2017-12-15 19:46       ` Jakub Jelinek
@ 2017-12-15 21:16         ` Jason Merrill
  0 siblings, 0 replies; 12+ messages in thread
From: Jason Merrill @ 2017-12-15 21:16 UTC (permalink / raw)
  To: Jakub Jelinek; +Cc: Martin Sebor, gcc-patches List

OK.

On Fri, Dec 15, 2017 at 2:46 PM, Jakub Jelinek <jakub@redhat.com> wrote:
> On Fri, Dec 15, 2017 at 08:09:20PM +0100, Jakub Jelinek wrote:
>> On Fri, Dec 15, 2017 at 02:01:36PM -0500, Jason Merrill wrote:
>> > On 11/29/2017 08:19 PM, Martin Sebor wrote:
>> > > On 11/29/2017 03:32 PM, Jakub Jelinek wrote:
>> > > > +      if (!tree_fits_uhwi_p (tsize))
>> > > > +    {
>> > > > +      error_at (loc, "%u names provided while %qT decomposes into "
>> > >
>> > > When count is 1 as in the test below the error isn't grammatically
>> > > correct ("1 names").  I see that the same message is already issued
>> > > elsewhere in the function so this seems like an opportunity to use
>> > > the right form here and also fix the other one at the same time or
>> > > in a followup.  The error_n function exists to issue the right form
>> > > for the language, singular or plural.  It's not as convenient when
>> > > the sentence contains two terms that may be singular or plural,
>> > > but that can also be dealt with.
>> >
>> > Agreed.
>>
>> Yeah, I've implemented it as an incremental patch.
>> So
>> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02521.html
>> for the ICE and
>> http://gcc.gnu.org/ml/gcc-patches/2017-11/msg02538.html
>> on top of it.  The latter is what Nathan approved already, the former
>> needs review.
>
> If it helps any, here are the 2 patches combined, re-tested on x86_64-linux
> with check-c++-all.
>
> 2017-12-15  Jakub Jelinek  <jakub@redhat.com>
>
>         PR c++/83205
>         * decl.c (cp_finish_decomp): Handle the case when tsize is not
>         error_mark_node, but doesn't fit into uhwi.  Split up count != eltscnt
>         and !tree_fits_uhwi_p (tsize) error_at calls into error_n and inform_n
>         to handle plural forms properly.
>
>         * g++.dg/cpp1z/decomp3.C: Adjust for structured binding count
>         mismatch diagnostics split into error and warning with plural
>         forms.
>         * g++.dg/cpp1z/decomp10.C: Likewise.
>         * g++.dg/cpp1z/decomp32.C: New test.
>
> --- gcc/cp/decl.c.jj    2017-12-15 20:40:00.601221086 +0100
> +++ gcc/cp/decl.c       2017-12-15 20:42:25.917445216 +0100
> @@ -7427,11 +7427,20 @@ cp_finish_decomp (tree decl, tree first,
>         {
>         cnt_mismatch:
>           if (count > eltscnt)
> -           error_at (loc, "%u names provided while %qT decomposes into "
> -                          "%wu elements", count, type, eltscnt);
> +           error_n (loc, count,
> +                    "%u name provided for structured binding",
> +                    "%u names provided for structured binding", count);
>           else
> -           error_at (loc, "only %u names provided while %qT decomposes into "
> -                          "%wu elements", count, type, eltscnt);
> +           error_n (loc, count,
> +                    "only %u name provided for structured binding",
> +                    "only %u names provided for structured binding", count);
> +         /* Some languages have special plural rules even for large values,
> +            but it is periodic with period of 10, 100, 1000 etc.  */
> +         inform_n (loc, eltscnt > INT_MAX
> +                        ? (eltscnt % 1000000) + 1000000 : eltscnt,
> +                   "while %qT decomposes into %wu element",
> +                   "while %qT decomposes into %wu elements",
> +                   type, eltscnt);
>           goto error_out;
>         }
>        eltype = TREE_TYPE (type);
> @@ -7500,6 +7509,15 @@ cp_finish_decomp (tree decl, tree first,
>                          "constant expression", type);
>           goto error_out;
>         }
> +      if (!tree_fits_uhwi_p (tsize))
> +       {
> +         error_n (loc, count,
> +                  "%u name provided for structured binding",
> +                  "%u names provided for structured binding", count);
> +         inform (loc, "while %qT decomposes into %E elements",
> +                 type, tsize);
> +         goto error_out;
> +       }
>        eltscnt = tree_to_uhwi (tsize);
>        if (count != eltscnt)
>         goto cnt_mismatch;
> --- gcc/testsuite/g++.dg/cpp1z/decomp3.C.jj     2017-11-30 11:18:00.078805693 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp3.C        2017-12-15 20:42:25.917445216 +0100
> @@ -51,16 +51,21 @@ int arr[4];
>  void
>  test3 (A &b, B c)
>  {
> -  auto [ d, e, f ] = arr;              // { dg-error "only 3 names provided while 'int .4.' decomposes into 4 elements" }
> -                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> -  auto & [ g, h, i, j, k ] = arr;      // { dg-error "5 names provided while 'int .4.' decomposes into 4 elements" }
> -                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> -  auto [ l, m ] = b;                   // { dg-error "only 2 names provided while 'A' decomposes into 3 elements" }
> -                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> -  auto & [ n, o, p, q ] = b;           // { dg-error "4 names provided while 'A' decomposes into 3 elements" }
> -                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> +  auto [ d, e, f ] = arr;              // { dg-error "only 3 names provided" }
> +                                       // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
> +                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
> +  auto & [ g, h, i, j, k ] = arr;      // { dg-error "5 names provided" }
> +                                       // { dg-message "while 'int .4.' decomposes into 4 elements" "" { target *-*-* } .-1 }
> +                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
> +  auto [ l, m ] = b;                   // { dg-error "only 2 names provided" }
> +                                       // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
> +                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
> +  auto & [ n, o, p, q ] = b;           // { dg-error "4 names provided" }
> +                                       // { dg-message "while 'A' decomposes into 3 elements" "" { target *-*-* } .-1 }
> +                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
>    auto [] { c };                       // { dg-error "empty structured binding declaration" }
>                                         // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> -  auto [ r, s ] = c;                   // { dg-error "2 names provided while 'B' decomposes into 1 elements" }
> -                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-1 }
> +  auto [ r, s ] = c;                   // { dg-error "2 names provided" }
> +                                       // { dg-message "while 'B' decomposes into 1 element" "" { target *-*-* } .-1 }
> +                                       // { dg-warning "structured bindings only available with -std=c..17 or -std=gnu..17" "" { target c++14_down } .-2 }
>  }
> --- gcc/testsuite/g++.dg/cpp1z/decomp10.C.jj    2017-11-30 11:18:00.102805393 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp10.C       2017-12-15 20:42:25.918445204 +0100
> @@ -11,7 +11,8 @@ void f1() { auto [ x ] = a1; }        // { dg-e
>
>  struct A2 { int i,j; } a2;
>  template<> struct std::tuple_size<A2> { enum { value = 5 }; };
> -void f2() { auto [ x ] = a2; } // { dg-error "decomposes into 5" }
> +void f2() { auto [ x ] = a2; } // { dg-error "only 1 name provided" }
> +                               // { dg-message "decomposes into 5" "" { target *-*-* } .-1 }
>
>  struct A3 { int i,j; } a3;
>  template<> struct std::tuple_size<A3> { enum { value = 1 }; };
> --- gcc/testsuite/g++.dg/cpp1z/decomp32.C.jj    2017-12-15 20:42:58.977041204 +0100
> +++ gcc/testsuite/g++.dg/cpp1z/decomp32.C       2017-12-15 20:42:25.918445204 +0100
> @@ -0,0 +1,32 @@
> +// PR c++/83205
> +// { dg-do compile { target c++11 } }
> +// { dg-options "" }
> +
> +struct A { int i; };
> +struct B { int i; };
> +namespace std {
> +  template <typename T> struct tuple_size;
> +  template <> struct tuple_size<A> {
> +    static constexpr int value = -1;
> +  };
> +#ifdef __SIZEOF_INT128__
> +  template <> struct tuple_size<B> {
> +    static constexpr unsigned __int128 value = -1;
> +  };
> +#endif
> +}
> +
> +auto [a] = A{};        // { dg-error "1 name provided" }
> +               // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
> +               // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
> +#ifdef __SIZEOF_INT128__
> +auto [b] = B{};        // { dg-error "1 name provided" "" { target int128 } }
> +               // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
> +               // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
> +auto [c, d] = B{};     // { dg-error "2 names provided" "" { target int128 } }
> +                       // { dg-message "while 'B' decomposes into \[0-9xa-fXA-F]* elements" "" { target int128 } .-1 }
> +                       // { dg-warning "structured bindings only available with" "" { target { c++14_down && int128 } } .-2 }
> +#endif
> +auto [e, f, g] = A{};  // { dg-error "3 names provided" }
> +                       // { dg-message "while 'A' decomposes into -1 elements" "" { target *-*-* } .-1 }
> +                       // { dg-warning "structured bindings only available with" "" { target c++14_down } .-2 }
>
>
>         Jakub

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2017-12-15 21:16 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-11-29 22:35 [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jakub Jelinek
2017-11-30  2:42 ` Martin Sebor
2017-11-30  9:26   ` [C++ PATCH] Plural forms for count != eltscnt structured binding diagnostics Jakub Jelinek
2017-11-30 11:59     ` Nathan Sidwell
2017-11-30 12:09       ` Jakub Jelinek
2017-11-30 13:01         ` Jakub Jelinek
2017-11-30 13:47           ` Jakub Jelinek
2017-11-30 15:51             ` Pedro Alves
2017-12-15 19:01   ` [C++ PATCH] Fix ICE on invalid std::tuple_size<...>::value (PR c++/83205) Jason Merrill
2017-12-15 19:09     ` Jakub Jelinek
2017-12-15 19:46       ` Jakub Jelinek
2017-12-15 21:16         ` Jason Merrill

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