[PATCH] Reject boolean/enum types in last arg of __builtin_*_overflow_p

Jakub Jelinek jakub@redhat.com
Fri Jun 10 19:08:00 GMT 2016


Hi!

As mentioned in PR71479, for __builtin_*_overflow we right now require
the last argument to be pointer to INTEGER_TYPE, not INTEGRAL_TYPE_P,
but for __builtin_*_overflow_p we were using INTEGRAL_TYPE_P.

For _Bool/bool, I'd think we could make it well defined if we wanted
(check if the infinite precision result is 0 or 1), but it is hardly useful
and as can be seen, right now we don't implement that (for bool we actually
check if the result fits into unsigned 8 bit integer, plus _Complex bool
is kind of weird), but for enums I think the definition on what is an enum
overflow is quite fuzzy, would it for C++ e.g. work differently between
-fstrict-enums and -fno-strict-enums, would it test overflows only on the
underlying type, or exact precision of the enum, something else?

So, I think it is better to continue what we've been doing already for
__builtin_*_overflow before.  We likely need to adjust the documentation
and possibly the diagnostics.  Maybe have one wording for !INTEGRAL_TYPE_P
and another wording for the != INTEGER_TYPE case (where it would complain
that the type is {pointer to,} {enum,bool,_Bool}?  Any preferences?

The patch below just uses the preexisting wording (where integral stood
for integer types including bool/enums, and integer for non-bool/enum
integer types), I'd just like to see it in soon so that people don't start
to rely on something that doesn't really work and is hard to define.

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

2016-06-10  Jakub Jelinek  <jakub@redhat.com>

	* c-common.c (check_builtin_function_arguments): Require last
	argument of BUILT_IN_*_OVERFLOW_P to have INTEGER_TYPE type.

	* c-c++-common/builtin-arith-overflow-1.c (f3): Adjust expected
	diagnostics.
	* g++.dg/ext/builtin-arith-overflow-1.C: Pass 0 instead of C
	as last argument to __builtin_add_overflow_p.

--- gcc/c-family/c-common.c.jj	2016-06-10 20:23:57.433135328 +0200
+++ gcc/c-family/c-common.c	2016-06-10 20:44:51.104848132 +0200
@@ -9999,13 +9999,19 @@ check_builtin_function_arguments (locati
       if (builtin_function_validate_nargs (loc, fndecl, nargs, 3))
 	{
 	  unsigned i;
-	  for (i = 0; i < 3; i++)
+	  for (i = 0; i < 2; i++)
 	    if (!INTEGRAL_TYPE_P (TREE_TYPE (args[i])))
 	      {
 		error_at (ARG_LOCATION (i), "argument %u in call to function "
 			  "%qE does not have integral type", i + 1, fndecl);
 		return false;
 	      }
+	  if (TREE_CODE (TREE_TYPE (args[i])) != INTEGER_TYPE)
+	    {
+	      error_at (ARG_LOCATION (i), "argument %u in call to function "
+			"%qE does not have integer type", i + 1, fndecl);
+	      return false;
+	    }
 	  return true;
 	}
       return false;
--- gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c.jj	2016-06-10 20:24:01.000000000 +0200
+++ gcc/testsuite/c-c++-common/builtin-arith-overflow-1.c	2016-06-10 20:56:04.461095680 +0200
@@ -236,11 +236,11 @@ f3 (float fa, int a, _Complex long int c
   x += __builtin_sub_overflow_p (ca, b, eb);	/* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */
   x += __builtin_mul_overflow_p (a, fb, bb);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
   x += __builtin_add_overflow_p (a, pb, a);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
-  x += __builtin_sub_overflow_p (a, eb, eb);
-  x += __builtin_mul_overflow_p (a, bb, bb);
-  x += __builtin_add_overflow_p (a, b, fa);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
-  x += __builtin_sub_overflow_p (a, b, ca);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
-  x += __builtin_mul_overflow_p (a, b, c);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
+  x += __builtin_sub_overflow_p (a, eb, eb);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integer type" } */
+  x += __builtin_mul_overflow_p (a, bb, bb);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integer type" } */
+  x += __builtin_add_overflow_p (a, b, fa);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integer type" } */
+  x += __builtin_sub_overflow_p (a, b, ca);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integer type" } */
+  x += __builtin_mul_overflow_p (a, b, c);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integer type" } */
   return x;
 }
 
--- gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C.jj	2016-06-08 21:01:25.000000000 +0200
+++ gcc/testsuite/g++.dg/ext/builtin-arith-overflow-1.C	2016-06-10 20:55:04.836870794 +0200
@@ -1,11 +1,11 @@
 // { dg-do compile }
 
-enum A { B = 1, C = 2, D = __builtin_add_overflow_p (B, C, C) };
-int e[__builtin_add_overflow_p (B, C, C) + 1];
+enum A { B = 1, C = 2, D = __builtin_add_overflow_p (B, C, 0) };
+int e[__builtin_add_overflow_p (B, C, 0) + 1];
 template <int N> int foo (int);
 
 void
 bar ()
 {
-  foo <__builtin_add_overflow_p (B, C, C) + 1> (0);
+  foo <__builtin_add_overflow_p (B, C, 0) + 1> (0);
 }

	Jakub



More information about the Gcc-patches mailing list