return type;
if (TREE_CODE (type) == BITINT_TYPE
- /* signed _BitInt(1) is invalid, avoid creating that. */
- && (unsignedp || TYPE_PRECISION (type) > 1))
+ /* signed _BitInt(1) is invalid before C2Y, avoid creating that. */
+ && (unsignedp || flag_isoc2y || TYPE_PRECISION (type) > 1))
return build_bitint_type (TYPE_PRECISION (type), unsignedp);
#define TYPE_OK(node) \
TYPE_ALIAS_SET_KNOWN_P. */
if (TYPE_UNSIGNED (t))
{
- /* There is no signed _BitInt(1). */
- if (TREE_CODE (t) == BITINT_TYPE && TYPE_PRECISION (t) == 1)
+ /* There is no signed _BitInt(1) before C2Y. */
+ if (TREE_CODE (t) == BITINT_TYPE
+ && !flag_isoc2y
+ && TYPE_PRECISION (t) == 1)
return -1;
tree t1 = c_common_signed_type (t);
gcc_checking_assert (t != t1);
}
prec = wi::min_precision (wval, UNSIGNED);
- if (prec == 0)
+ if (prec == 0 && ((flags & CPP_N_UNSIGNED) != 0 || !flag_isoc2y))
prec = 1;
if ((flags & CPP_N_UNSIGNED) == 0)
++prec;
case cts_bitint:
gcc_assert (!specs->long_p && !specs->short_p
&& !specs->complex_p);
- if (!specs->unsigned_p && specs->u.bitint_prec == 1)
+ if (!specs->unsigned_p && specs->u.bitint_prec == 1 && !flag_isoc2y)
{
error_at (specs->locations[cdw_typespec],
- "%<signed _BitInt%> argument must be at least 2");
+ "%<signed _BitInt%> argument must be at least 2 "
+ "before C2Y");
specs->type = integer_type_node;
break;
}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors -O2" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options float64 } */
+/* { dg-add-options float32x } */
+/* { dg-require-effective-target float32 } */
+/* { dg-require-effective-target float32x } */
+/* { dg-require-effective-target float64 } */
+
+[[gnu::noipa]] void
+foo (_BitInt(1) p[3], _Float32 q, _Float64 r, _Float32x s)
+{
+ p[0] = q;
+ p[1] = r;
+ p[2] = s;
+}
+
+[[gnu::noipa]] void
+bar (_BitInt(1) p[2], _Float32 q[2], _Float64 r[2], _Float32x s[2])
+{
+ q[0] = p[0];
+ q[1] = p[1];
+ r[0] = p[0];
+ r[1] = p[1];
+ s[0] = p[0];
+ s[1] = p[1];
+}
+
+int
+main ()
+{
+ _BitInt(1) e[15];
+ foo (e, 0.5f32, 0.25f64, 0.75f32x);
+ foo (e + 3, -0.5f32, -0.25f64, -0.75f32x);
+ foo (e + 6, 0.f32, 0.f64, 0.f32x);
+ foo (e + 9, -1.f32, -1.f64, -1.f32x);
+ foo (e + 12, -1.5f32, -1.25f64, -1.75f32x);
+ for (int i = 0; i < 15; ++i)
+ if (e[i] != (i < 9 ? 0 : -1))
+ __builtin_abort ();
+ e[0] = 0wb;
+ e[1] = ~0wb;
+ _Float32 j[2];
+ _Float64 k[2];
+ _Float32x l[2];
+ bar (e, j, k, l);
+ if (j[0] != 0.0f32 || j[1] != -1.0f32
+ || k[0] != 0.0f64 || k[1] != -1.0f64
+ || l[0] != 0.0f32x || l[1] != -1.0f32x)
+ __builtin_abort ();
+}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors -O2" } */
+/* { dg-add-options float128 } */
+/* { dg-add-options float64x } */
+/* { dg-require-effective-target float128 } */
+/* { dg-require-effective-target float64x } */
+
+[[gnu::noipa]] void
+foo (_BitInt(1) p[2], _Float128 q, _Float64x r)
+{
+ p[0] = q;
+ p[1] = r;
+}
+
+[[gnu::noipa]] void
+bar (_BitInt(1) p[2], _Float128 q[2], _Float64x r[2])
+{
+ q[0] = p[0];
+ q[1] = p[1];
+ r[0] = p[0];
+ r[1] = p[1];
+}
+
+int
+main ()
+{
+ _BitInt(1) e[10];
+ foo (e, 0.5f128, 0.25f64x);
+ foo (e + 2, -0.5f128, -0.25f64x);
+ foo (e + 4, 0.f128, 0.f64x);
+ foo (e + 6, -1.f128, -1.f64x);
+ foo (e + 8, -1.5f128, -1.25f64x);
+ for (int i = 0; i < 10; ++i)
+ if (e[i] != (i < 6 ? 0 : -1))
+ __builtin_abort ();
+ e[0] = 0wb;
+ e[1] = ~0wb;
+ _Float128 j[2];
+ _Float64x k[2];
+ bar (e, j, k);
+ if (j[0] != 0.0f128 || j[1] != -1.0f128
+ || k[0] != 0.0f64x || k[1] != -1.0f64x)
+ __builtin_abort ();
+}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors -O2" } */
+/* { dg-add-options float16 } */
+/* { dg-require-effective-target float16_runtime } */
+
+[[gnu::noipa]] _BitInt(1)
+foo (_Float16 x)
+{
+ return x;
+}
+
+[[gnu::noipa]] _Float16
+bar (_BitInt(1) x)
+{
+ return x;
+}
+
+int
+main ()
+{
+ if (foo (0.5f16) != 0wb || foo (0.25f16) != 0wb
+ || foo (-0.5f16) != 0wb || foo (-0.25f16) != 0wb
+ || foo (0.f16) != 0wb || foo (-0.75f16) != 0wb
+ || foo (-1.f16) != ~0wb || foo (-1.75f16) != ~0wb
+ || foo (-1.5f16) != ~0wb || foo (-1.25f16) != ~0wb)
+ __builtin_abort ();
+ if (bar (0wb) != 0.f16 || bar (~0wb) != -1.f16)
+ __builtin_abort ();
+}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+
+void
+foo ()
+{
+ _BitInt(1) a = (_BitInt(1)) -1;
+ static_assert (expr_has_type (a, signed _BitInt(1)), "");
+ static_assert (expr_has_type (0wb, _BitInt(1)), "");
+ static_assert (expr_has_type (~0wb, _BitInt(1)), "");
+ static_assert (expr_has_type (1wb, _BitInt(2)), "");
+ static_assert (expr_has_type (-1wb, _BitInt(2)), "");
+ static_assert (expr_has_type (2wb, _BitInt(3)), "");
+ static_assert (expr_has_type (0wb + 0wb, signed _BitInt(1)), "");
+ static_assert (expr_has_type (0wb + 0uwb, unsigned _BitInt(1)), "");
+ static_assert (expr_has_type (0wb + 1wb, _BitInt(2)), "");
+ static_assert (expr_has_type (0uwb + 0wb, unsigned _BitInt(1)), "");
+ static_assert (expr_has_type (1wb + 0wb, _BitInt(2)), "");
+ static_assert (0wb == 0, "");
+ static_assert (~0wb == -1, "");
+ static_assert (~~0wb == 0, "");
+ static_assert (-1wb == -1, "");
+}
+
+_BitInt(1) b = 0wb;
+_BitInt(1) c = ~0wb;
+_BitInt(1) d = 0wb;
+
+[[gnu::noipa]] void
+bar (_BitInt(1) a[21], signed _BitInt(1) b[21], const _BitInt(1) c[21])
+{
+ a[0] = b[0] + c[0];
+ a[1] = b[1] + c[1];
+ a[2] = b[2] + c[2];
+ a[3] = b[3] - c[3];
+ a[4] = b[4] - c[4];
+ a[5] = b[5] - c[5];
+ a[6] = b[6] * c[6];
+ a[7] = b[7] * c[8];
+ a[8] = b[8] * c[8];
+ a[9] = b[9] / c[9];
+ a[10] = b[10] % c[10];
+ a[11] = b[11] % c[11];
+ a[12] = b[12] & c[12];
+ a[13] = b[13] & c[13];
+ a[14] = b[14] & c[14];
+ a[15] = b[15] | c[15];
+ a[16] = b[16] | c[16];
+ a[17] = b[17] | c[17];
+ a[18] = b[18] ^ c[18];
+ a[19] = b[19] ^ c[19];
+ a[20] = b[20] ^ c[20];
+}
+
+#if __BITINT_MAXWIDTH__ >= 256
+[[gnu::noipa]] _BitInt(256)
+baz (_BitInt(256) x, _BitInt(1) y)
+{
+ return x * y;
+}
+#endif
+
+[[gnu::noipa]] void
+qux (_BitInt(1) p[3], float q, double r, long double s)
+{
+ p[0] = q;
+ p[1] = r;
+ p[2] = s;
+}
+
+[[gnu::noipa]] void
+corge (_BitInt(1) p[2], float q[2], double r[2], long double s[2])
+{
+ q[0] = p[0];
+ q[1] = p[1];
+ r[0] = p[0];
+ r[1] = p[1];
+ s[0] = p[0];
+ s[1] = p[1];
+}
+
+int
+main ()
+{
+ if (b != 0 || c != -1)
+ __builtin_abort ();
+ --b;
+ ++c;
+ if (b != -1 || c != 0)
+ __builtin_abort ();
+ b = ~b;
+ c = ~c;
+ if (b != 0 || c != -1)
+ __builtin_abort ();
+ c *= d;
+ if (d != 0)
+ __builtin_abort ();
+ _BitInt(1) e[21];
+ _BitInt(1) f[21] = {
+ 0, -1, 0,
+ 0, -1, -1,
+ 0, -1, 0,
+ 0,
+ 0, -1,
+ 0, -1, -1,
+ 0, 0, -1,
+ 0, -1, -1
+ };
+ signed _BitInt(1) g[21] = {
+ 0, 0, -1,
+ 0, 0, -1,
+ 0, 0, -1,
+ -1,
+ -1, -1,
+ 0, 0, -1,
+ 0, -1, -1,
+ 0, 0, -1
+ };
+ bar (e, f, g);
+ _BitInt(1) h[21] = {
+ 0, -1, -1,
+ 0, -1, 0,
+ 0, 0, 0,
+ 0,
+ 0, 0,
+ 0, 0, -1,
+ 0, -1, -1,
+ 0, -1, 0
+ };
+ for (int i = 0; i < 21; ++i)
+ if (e[i] != h[i])
+ __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 256
+ if (baz (24807048826655379640613156875228202584070386120119745959437529938064756141700wb, ~0wb)
+ != -24807048826655379640613156875228202584070386120119745959437529938064756141700wb)
+ __builtin_abort ();
+ if (baz (24807048826655379640613156875228202584070386120119745959437529938064756141700wb, 0wb) != 0wb)
+ __builtin_abort ();
+ if (baz (-24807048826655379640613156875228202584070386120119745959437529938064756141700wb, 0wb)
+ != 24807048826655379640613156875228202584070386120119745959437529938064756141700wb)
+ __builtin_abort ();
+ if (baz (0wb, ~0wb) != 0wb)
+ __builtin_abort ();
+#endif
+ qux (e, 0.5f, 0.25, 0.75L);
+ qux (e + 3, -0.5f, -0.25, -0.75L);
+ qux (e + 6, 0.f, 0., 0.L);
+ qux (e + 9, -1.f, -1., -1.L);
+ qux (e + 12, -1.5f, -1.25, -1.75L);
+ for (int i = 0; i < 15; ++i)
+ if (e[i] != (i < 9 ? 0 : -1))
+ __builtin_abort ();
+ e[0] = 0wb;
+ e[1] = ~0wb;
+ float j[2];
+ double k[2];
+ long double l[2];
+ corge (e, j, k, l);
+ if (j[0] != 0.0f || j[1] != -1.0f
+ || k[0] != 0.0 || k[1] != -1.0
+ || l[0] != 0.0L || l[1] != -1.0L)
+ __builtin_abort ();
+}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors -fwrapv" } */
+
+[[gnu::noipa]] void
+bar (_BitInt(1) a[8], signed _BitInt(1) b[8], const _BitInt(1) c[8])
+{
+ a[0] = b[0] + c[0];
+ a[1] = b[1] - c[1];
+ a[2] = b[2] / c[2];
+ a[3] = ++b[3];
+ a[4] = b[4]++;
+ a[5] = --b[5];
+ a[6] = b[6]--;
+ a[7] = -b[7];
+}
+
+int
+main ()
+{
+ _BitInt(1) e[8];
+ _BitInt(1) f[8] = {
+ -1, 0, -1, 0, 0, -1, -1, -1,
+ };
+ signed _BitInt(1) g[8] = {
+ -1, -1, -1, -1, -1, 0, 0, -1,
+ };
+ bar (e, f, g);
+ _BitInt(1) h[8] = {
+ 0, -1, -1, -1, 0, 0, -1, -1
+ };
+ for (int i = 0; i < 8; ++i)
+ if (e[i] != h[i] || (i > 2 && f[i] != g[i]))
+ __builtin_abort ();
+}
--- /dev/null
+/* C2Y N3747 - Integer Sets, v5 */
+/* { dg-do compile { target bitint } } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "*" } { "-O0" "-O2" } } */
+/* { dg-skip-if "" { ! run_expensive_tests } { "-flto" } { "" } } */
+
+#if __BITINT_MAXWIDTH__ >= 256
+[[gnu::noipa]] bool
+foo (_BitInt(256) x, _BitInt(256) y, _BitInt(1) *z)
+{
+ return __builtin_add_overflow (x, y, z);
+}
+
+[[gnu::noipa]] bool
+bar (_BitInt(256) x, _BitInt(256) y, _BitInt(1) *z)
+{
+ return __builtin_sub_overflow (x, y, z);
+}
+
+[[gnu::noipa]] bool
+baz (_BitInt(256) x, _BitInt(256) y, _BitInt(1) *z)
+{
+ return __builtin_mul_overflow (x, y, z);
+}
+
+#endif
+
+int
+main ()
+{
+#if __BITINT_MAXWIDTH__ >= 256
+ _BitInt(1) z;
+ if (foo (42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ -42733374111348455377695489439454828259303231857505551329091595050247393780228wb, &z)
+ || z)
+ __builtin_abort ();
+ if (foo (-42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ 42733374111348455377695489439454828259303231857505551329091595050247393780227wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!foo (42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ -42733374111348455377695489439454828259303231857505551329091595050247393780227wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!foo (16820456121763970532229687954276499920583743168031969051240987845040434685573wb,
+ 23294062539967091892447346238664352846257951403931317361440421661377004317436wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!foo (16820456121763970532229687954276499920583743168031969051240987845040434685574wb,
+ 23294062539967091892447346238664352846257951403931317361440421661377004317436wb, &z)
+ || z != 0wb)
+ __builtin_abort ();
+ if (bar (42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ 42733374111348455377695489439454828259303231857505551329091595050247393780228wb, &z)
+ || z)
+ __builtin_abort ();
+ if (bar (-42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ -42733374111348455377695489439454828259303231857505551329091595050247393780227wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!bar (42733374111348455377695489439454828259303231857505551329091595050247393780228wb,
+ 42733374111348455377695489439454828259303231857505551329091595050247393780227wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!bar (16820456121763970532229687954276499920583743168031969051240987845040434685573wb,
+ -23294062539967091892447346238664352846257951403931317361440421661377004317436wb, &z)
+ || z != ~0wb)
+ __builtin_abort ();
+ if (!bar (16820456121763970532229687954276499920583743168031969051240987845040434685574wb,
+ -23294062539967091892447346238664352846257951403931317361440421661377004317436wb, &z)
+ || z != 0wb)
+ __builtin_abort ();
+ if (baz (0, 0, &z) || z != 0wb)
+ __builtin_abort ();
+ if (baz (-1, 0, &z) || z != 0wb)
+ __builtin_abort ();
+ if (baz (-1, 1, &z) || z != ~0wb)
+ __builtin_abort ();
+ if (!baz (-1, -1, &z) || z != ~0wb)
+ __builtin_abort ();
+ if (!baz (30448945616760427177055226753240458517982932603339745354716666930701331527103wb,
+ 42368953827467495356095621726856482300912964572736555031468887238137186859246wb, &z) || z != 0wb)
+ __builtin_abort ();
+ if (!baz (30448945616760427177055226753240458517982932603339745354716666930701331527103wb,
+ -42368953827467495356095621726856482300912964572736555031468887238137186859247wb, &z) || z != ~0wb)
+ __builtin_abort ();
+#endif
+}
{
tree itype, ret;
- gcc_checking_assert (precision >= 1 + !unsignedp);
+ gcc_checking_assert (precision >= 1);
if (unsignedp)
unsignedp = MAX_INT_CACHED_PREC + 1;
else
return NULL_TREE;
- if (TREE_CODE (type) == BITINT_TYPE && (unsignedp || bits > 1))
+ if (TREE_CODE (type) == BITINT_TYPE)
return build_bitint_type (bits, unsignedp);
return build_nonstandard_integer_type (bits, unsignedp);
}