@@ -15066,6 +15066,14 @@ unsigned integer (standard, extended or
promotions are performed on the argument.
@enddefbuiltin
+@defbuiltin{@var{type} __builtin_bit_complement (@var{type} @var{arg})}
+The @code{__builtin_bit_complement} function is available only
+in C. It is type-generic, the argument can be any integral type, and
+is equivalent to @code{(__typeof (@var{arg})) ~(@var{arg})}, except that
+there is no need to specify the argument tokens twice. No integral argument
+promotions are performed on the argument.
+@enddefbuiltin
+
@defbuiltin{double __builtin_powi (double, int)}
@defbuiltinx{float __builtin_powif (float, int)}
@defbuiltinx{{long double} __builtin_powil (long double, int)}
@@ -110,6 +110,7 @@ enum rid
RID_TYPES_COMPATIBLE_P, RID_BUILTIN_COMPLEX, RID_BUILTIN_SHUFFLE,
RID_BUILTIN_SHUFFLEVECTOR, RID_BUILTIN_CONVERTVECTOR, RID_BUILTIN_TGMATH,
RID_BUILTIN_HAS_ATTRIBUTE, RID_BUILTIN_ASSOC_BARRIER,
+ RID_BUILTIN_BIT_COMPLEMENT,
RID_DFLOAT32, RID_DFLOAT64, RID_DFLOAT128,
/* TS 18661-3 keywords, in the same sequence as the TI_* values. */
@@ -380,7 +380,9 @@ const struct c_common_resword c_common_r
{ "__attribute__", RID_ATTRIBUTE, 0 },
{ "__auto_type", RID_AUTO_TYPE, D_CONLY },
{ "__builtin_addressof", RID_ADDRESSOF, D_CXXONLY },
+ { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
{ "__builtin_bit_cast", RID_BUILTIN_BIT_CAST, D_CXXONLY },
+ { "__builtin_bit_complement", RID_BUILTIN_BIT_COMPLEMENT, D_CONLY },
{ "__builtin_call_with_static_chain",
RID_BUILTIN_CALL_WITH_STATIC_CHAIN, D_CONLY },
{ "__builtin_choose_expr", RID_CHOOSE_EXPR, D_CONLY },
@@ -388,7 +390,6 @@ const struct c_common_resword c_common_r
{ "__builtin_convertvector", RID_BUILTIN_CONVERTVECTOR, 0 },
{ "__builtin_has_attribute", RID_BUILTIN_HAS_ATTRIBUTE, 0 },
{ "__builtin_launder", RID_BUILTIN_LAUNDER, D_CXXONLY },
- { "__builtin_assoc_barrier", RID_BUILTIN_ASSOC_BARRIER, 0 },
{ "__builtin_shuffle", RID_BUILTIN_SHUFFLE, 0 },
{ "__builtin_shufflevector", RID_BUILTIN_SHUFFLEVECTOR, 0 },
{ "__builtin_tgmath", RID_BUILTIN_TGMATH, D_CONLY },
@@ -11743,6 +11743,46 @@ c_parser_postfix_expression (c_parser *p
set_c_expr_source_range (&expr, start_loc, end_loc);
}
break;
+ case RID_BUILTIN_BIT_COMPLEMENT:
+ {
+ vec<c_expr_t, va_gc> *cexpr_list;
+ c_expr_t *arg_p;
+ location_t close_paren_loc;
+
+ c_parser_consume_token (parser);
+ if (!c_parser_get_builtin_args (parser,
+ "__builtin_bit_complement",
+ &cexpr_list, false,
+ &close_paren_loc))
+ {
+ expr.set_error ();
+ break;
+ }
+
+ if (vec_safe_length (cexpr_list) != 1)
+ {
+ error_at (loc, "wrong number of arguments to "
+ "%<__builtin_bit_complement%>");
+ expr.set_error ();
+ break;
+ }
+
+ arg_p = &(*cexpr_list)[0];
+ *arg_p = convert_lvalue_to_rvalue (loc, *arg_p, true, true);
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (arg_p->value)))
+ {
+ error_at (loc, "%<__builtin_bit_complement%> operand "
+ "not an integral type");
+ expr.set_error ();
+ break;
+ }
+ expr.value
+ = build1_loc (loc, BIT_NOT_EXPR,
+ TYPE_MAIN_VARIANT (TREE_TYPE (arg_p->value)),
+ arg_p->value);
+ set_c_expr_source_range (&expr, loc, close_paren_loc);
+ break;
+ }
case RID_AT_SELECTOR:
{
gcc_assert (c_dialect_objc ());
@@ -11370,11 +11370,12 @@ names_builtin_p (const char *name)
functions. */
switch (C_RID_CODE (id))
{
+ case RID_BUILTIN_ASSOC_BARRIER:
+ case RID_BUILTIN_BIT_COMPLEMENT:
case RID_BUILTIN_CONVERTVECTOR:
case RID_BUILTIN_HAS_ATTRIBUTE:
case RID_BUILTIN_SHUFFLE:
case RID_BUILTIN_SHUFFLEVECTOR:
- case RID_BUILTIN_ASSOC_BARRIER:
case RID_CHOOSE_EXPR:
case RID_OFFSETOF:
case RID_TYPES_COMPATIBLE_P:
@@ -0,0 +1,87 @@
+/* { dg-do run } */
+/* { dg-options "-std=c11" } */
+
+#define expr_has_type(e, t) _Generic (e, default : 0, t : 1)
+enum E { E0, E1 };
+
+int
+main ()
+{
+ if (__builtin_bit_complement ((unsigned char) 0) != (unsigned char) ~(unsigned char) 0
+ || __builtin_bit_complement ((unsigned char) 0x33) != (unsigned char) ~(unsigned char) 0x33
+ || !expr_has_type (__builtin_bit_complement ((unsigned char) 0), unsigned char)
+ || __builtin_bit_complement ((unsigned short) 0) != (unsigned short) ~(unsigned short) 0
+ || __builtin_bit_complement ((unsigned short) 0x5555) != (unsigned short) ~(unsigned short) 0x5555
+ || !expr_has_type (__builtin_bit_complement ((unsigned short) 0), unsigned short)
+ || __builtin_bit_complement (0U) != ~0U
+ || __builtin_bit_complement (0xaaaaU) != ~0xaaaaU
+ || !expr_has_type (__builtin_bit_complement (0U), unsigned int)
+ || __builtin_bit_complement (0UL) != ~0UL
+ || __builtin_bit_complement (0xaaaaaaaaUL) != ~0xaaaaaaaaUL
+ || !expr_has_type (__builtin_bit_complement (0UL), unsigned long)
+ || __builtin_bit_complement (0ULL) != ~0ULL
+ || __builtin_bit_complement (0xaaaaaaaa55555555ULL) != ~0xaaaaaaaa55555555ULL
+ || !expr_has_type (__builtin_bit_complement (0ULL), unsigned long long)
+ || __builtin_bit_complement ((signed char) 0) != (signed char) ~(signed char) 0
+ || __builtin_bit_complement ((signed char) 0x33) != (signed char) ~(signed char) 0x33
+ || !expr_has_type (__builtin_bit_complement ((signed char) 0), signed char)
+ || __builtin_bit_complement ((signed short) 0) != (signed short) ~(signed short) 0
+ || __builtin_bit_complement ((signed short) 0x5555) != (signed short) ~(signed short) 0x5555
+ || !expr_has_type (__builtin_bit_complement ((signed short) 0), signed short)
+ || __builtin_bit_complement (0) != ~0
+ || __builtin_bit_complement (0x5aaa) != ~0x5aaa
+ || !expr_has_type (__builtin_bit_complement (0), signed int)
+ || __builtin_bit_complement (0L) != ~0L
+ || __builtin_bit_complement (0x5aaaaaaaL) != ~0x5aaaaaaaL
+ || !expr_has_type (__builtin_bit_complement (0L), signed long)
+ || __builtin_bit_complement (0LL) != ~0LL
+ || __builtin_bit_complement (0x5aaaaaaa55555555LL) != ~0x5aaaaaaa55555555LL
+ || !expr_has_type (__builtin_bit_complement (0LL), signed long long)
+ || __builtin_bit_complement ((_Bool) 0) != (_Bool) 1
+ || __builtin_bit_complement ((_Bool) 1) != (_Bool) 0
+ || !expr_has_type (__builtin_bit_complement ((_Bool) 0), _Bool)
+ || __builtin_bit_complement ((enum E) E0) != (enum E) ~0
+ || __builtin_bit_complement ((enum E) E1) != (enum E) ~1
+ || !expr_has_type (__builtin_bit_complement ((enum E) E0), enum E))
+ __builtin_abort ();
+#if __SIZEOF_INT128__
+ if (__builtin_bit_complement ((unsigned __int128) 0) != ~(unsigned __int128) 0
+ || __builtin_bit_complement ((unsigned __int128) 0xaaaaaaaa55555555ULL) != ~(unsigned __int128) 0xaaaaaaaa55555555ULL
+ || !expr_has_type (__builtin_bit_complement ((unsigned __int128) 0), unsigned __int128)
+ || __builtin_bit_complement ((signed __int128) 0) != ~(signed __int128) 0
+ || __builtin_bit_complement ((signed __int128) 0x5aaaaaaa55555555LL) != ~(signed __int128) 0x5aaaaaaa55555555LL
+ || !expr_has_type (__builtin_bit_complement ((signed __int128) 0), signed __int128))
+ __builtin_abort ();
+#endif
+#if __has_builtin (__builtin_bit_complement) != 1
+#error __builtin_bit_complement not implemented
+#endif
+ unsigned char a = 0;
+ if (__builtin_bit_complement (a++) != (unsigned char) ~(unsigned char) 0
+ || a != 1)
+ __builtin_abort ();
+ if (!expr_has_type (__builtin_bit_complement (a++), unsigned char)
+ || a != 1)
+ __builtin_abort ();
+ unsigned short b = 0;
+ if (__builtin_bit_complement (b++) != (unsigned short) ~(unsigned short) 0
+ || b != 1)
+ __builtin_abort ();
+ if (!expr_has_type (__builtin_bit_complement (b++), unsigned short)
+ || b != 1)
+ __builtin_abort ();
+ int c = 0;
+ if (__builtin_bit_complement (c++) != ~0
+ || c != 1)
+ __builtin_abort ();
+ if (!expr_has_type (__builtin_bit_complement (c++), int)
+ || c != 1)
+ __builtin_abort ();
+#if __BITINT_MAXWIDTH__ >= 256
+ if (__builtin_bit_complement (0uwb) != ~0uwb
+ || !expr_has_type (__builtin_bit_complement (0uwb), unsigned _BitInt(1))
+ || __builtin_bit_complement ((signed _BitInt(256)) 0) != ~(signed _BitInt(256)) 0
+ || !expr_has_type (__builtin_bit_complement ((signed _BitInt(256)) 0), signed _BitInt(256)))
+ __builtin_abort ();
+#endif
+}
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (void)
+{
+ typedef int V __attribute__ ((vector_size (4 * sizeof (int))));
+ struct S { int s; };
+ __builtin_bit_complement (0.0f); /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+ __builtin_bit_complement (0.0); /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+ __builtin_bit_complement (0.0L); /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+ __builtin_bit_complement ((V) {}); /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+ __builtin_bit_complement ((struct S) { 0 }); /* { dg-error "'__builtin_bit_complement' operand not an integral type" } */
+ __builtin_bit_complement (); /* { dg-error "wrong number of arguments to '__builtin_bit_complement'" } */
+ __builtin_bit_complement (0, 0); /* { dg-error "wrong number of arguments to '__builtin_bit_complement'" } */
+}