extern bool comptypes_equiv_p (tree, tree);
extern int comptypes_check_different_types (tree, tree, bool *);
extern int comptypes_check_enum_int (tree, tree, bool *);
-extern bool c_mark_addressable (tree, bool = false);
+extern bool c_mark_addressable (tree, bool = false, bool = false);
extern void c_incomplete_type_error (location_t, const_tree, const_tree);
extern tree c_type_promotes_to (tree);
extern struct c_expr default_function_array_conversion (location_t,
|| (COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (array)))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) != INTEGER_CST))
{
- if (!c_mark_addressable (array, true))
+ if (!c_mark_addressable (array, true, true))
return error_mark_node;
}
/* An array that is indexed by a constant value which is not within
&& TYPE_DOMAIN (TREE_TYPE (array))
&& !int_fits_type_p (index, TYPE_DOMAIN (TREE_TYPE (array))))
{
- if (!c_mark_addressable (array))
+ if (!c_mark_addressable (array, false, true))
return error_mark_node;
+ /* ISO C2Y disallows a negative integer constant expression index
+ when array subscripting has an operand of array type. */
+ if (flag_isoc2y
+ && !TREE_OVERFLOW (index)
+ && tree_int_cst_sgn (index) < 0)
+ error_at (loc, "array subscript is negative");
}
- if ((pedantic || warn_c90_c99_compat)
+ if ((pedantic || warn_c90_c99_compat || warn_c23_c2y_compat)
&& ! was_vector)
{
tree foo = array;
while (TREE_CODE (foo) == COMPONENT_REF)
foo = TREE_OPERAND (foo, 0);
- if (VAR_P (foo) && C_DECL_REGISTER (foo))
- pedwarn (loc, OPT_Wpedantic,
- "ISO C forbids subscripting %<register%> array");
+ if ((VAR_P (foo) && C_DECL_REGISTER (foo))
+ || (TREE_CODE (foo) == COMPOUND_LITERAL_EXPR
+ && C_DECL_REGISTER (COMPOUND_LITERAL_EXPR_DECL (foo))))
+ pedwarn_c23 (loc, OPT_Wpedantic,
+ "ISO C forbids subscripting %<register%> array "
+ "before C2Y");
else if (!lvalue_p (foo))
pedwarn_c90 (loc, OPT_Wpedantic,
"ISO C90 forbids subscripting non-lvalue "
is for ARRAY_REF construction - in that case we don't want
to look through VIEW_CONVERT_EXPR from VECTOR_TYPE to ARRAY_TYPE,
it is fine to use ARRAY_REFs for vector subscripts on vector
- register variables. */
+ register variables. If OVERRIDE_REGISTER, clear DECL_REGISTER rather
+ than producing an error for taking the address of a register. */
bool
-c_mark_addressable (tree exp, bool array_ref_p)
+c_mark_addressable (tree exp, bool array_ref_p, bool override_register)
{
tree x = exp;
case COMPOUND_LITERAL_EXPR:
if (C_DECL_REGISTER (COMPOUND_LITERAL_EXPR_DECL (x)))
{
- error ("address of register compound literal requested");
- return false;
+ if (override_register)
+ DECL_REGISTER (COMPOUND_LITERAL_EXPR_DECL (x)) = 0;
+ else
+ {
+ error ("address of register compound literal requested");
+ return false;
+ }
}
TREE_ADDRESSABLE (x) = 1;
TREE_ADDRESSABLE (COMPOUND_LITERAL_EXPR_DECL (x)) = 1;
{
if (TREE_PUBLIC (x) || is_global_var (x))
error ("address of global register variable %qD requested", x);
+ else if (override_register && !DECL_HARD_REGISTER (x))
+ {
+ DECL_REGISTER (x) = 0;
+ TREE_ADDRESSABLE (x) = 1;
+ mark_decl_used (x, true);
+ return true;
+ }
else
error ("address of register variable %qD requested", x);
return false;
--- /dev/null
+/* Test C2y constraint against negative array indices does not apply in
+ C23. */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+int a[1], b[10];
+struct s { int a[2]; } x;
+void *p;
+
+void
+f ()
+{
+ (void) a[0];
+ (void) a[1];
+ (void) a[12345];
+ (void) a[-1];
+ (void) a[-__LONG_LONG_MAX__];
+ (void) b[0];
+ (void) b[10];
+ (void) b[12345];
+ (void) b[-1];
+ (void) b[-__LONG_LONG_MAX__];
+ (void) x.a[0];
+ (void) x.a[1];
+ (void) x.a[12345];
+ (void) x.a[-1];
+ (void) x.a[-__LONG_LONG_MAX__];
+ int c[1];
+ (void) c[0];
+ (void) c[1];
+ (void) c[12345];
+ (void) c[-1];
+ (void) c[-__LONG_LONG_MAX__];
+ (void) (*(int (*)[1]) p)[0];
+ (void) (*(int (*)[1]) p)[1];
+ (void) (*(int (*)[1]) p)[12345];
+ (void) (*(int (*)[1]) p)[-1];
+ (void) (*(int (*)[1]) p)[-__LONG_LONG_MAX__];
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply even in C2y. */
+ (void) a[__LONG_LONG_MAX__ + 2];
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ /* Likewise, this is only an arithmetic constant expression, not an integer
+ constant expression. */
+ (void) a[(int)-1.0];
+}
--- /dev/null
+/* Test C2y register array element access: not in C23. */
+/* { dg-do compile } */
+/* { dg-options "-std=c23 -pedantic-errors" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ c[i] = i; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 20; i++)
+ b[i] = i; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ if (c[i] != i) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (a[0] != 0) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2) /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (false)
+ (void) a[12345]; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ (void) b[23456]; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2]; /* { dg-error "ISO C forbids subscripting 'register' array before C2Y" } */
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}
--- /dev/null
+/* Test C2y register array element access: C23 warning with -pedantic. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ c[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 20; i++)
+ b[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ if (c[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (a[0] != 0) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (false)
+ (void) a[12345]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ (void) b[23456]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}
--- /dev/null
+/* Test C2y register array element access: C23 warning with
+ -Wc23-c2y-compat. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -Wc23-c2y-compat" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ c[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 20; i++)
+ b[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ if (c[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (a[0] != 0) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (false)
+ (void) a[12345]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ (void) b[23456]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}
--- /dev/null
+/* Test C2y register array element access: no warning in C23 mode with
+ -Wno-c23-c2y-compat. */
+/* { dg-do run } */
+/* { dg-options "-std=c23 -pedantic-errors -Wno-c23-c2y-compat" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0;
+ for (int i = 0; i < n; i++)
+ c[i] = i;
+ for (int i = 0; i < 20; i++)
+ b[i] = i;
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i;
+ for (int i = 0; i < n; i++)
+ if (c[i] != i)
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i)
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i)
+ abort ();
+ if (a[0] != 0)
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3)
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2)
+ abort ();
+ if (false)
+ (void) a[12345];
+ if (false)
+ (void) b[23456];
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2];
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}
--- /dev/null
+/* Test C2y constraint against negative array indices. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+int a[1], b[10];
+struct s { int a[2]; } x;
+void *p;
+
+void
+f ()
+{
+ (void) a[0];
+ (void) a[1];
+ (void) a[12345];
+ (void) a[-1]; /* { dg-error "array subscript is negative" } */
+ (void) a[-__LONG_LONG_MAX__]; /* { dg-error "array subscript is negative" } */
+ (void) b[0];
+ (void) b[10];
+ (void) b[12345];
+ (void) b[-1]; /* { dg-error "array subscript is negative" } */
+ (void) b[-__LONG_LONG_MAX__]; /* { dg-error "array subscript is negative" } */
+ (void) x.a[0];
+ (void) x.a[1];
+ (void) x.a[12345];
+ (void) x.a[-1]; /* { dg-error "array subscript is negative" } */
+ (void) x.a[-__LONG_LONG_MAX__]; /* { dg-error "array subscript is negative" } */
+ int c[1];
+ (void) c[0];
+ (void) c[1];
+ (void) c[12345];
+ (void) c[-1]; /* { dg-error "array subscript is negative" } */
+ (void) c[-__LONG_LONG_MAX__]; /* { dg-error "array subscript is negative" } */
+ (void) (*(int (*)[1]) p)[0];
+ (void) (*(int (*)[1]) p)[1];
+ (void) (*(int (*)[1]) p)[12345];
+ (void) (*(int (*)[1]) p)[-1]; /* { dg-error "array subscript is negative" } */
+ (void) (*(int (*)[1]) p)[-__LONG_LONG_MAX__]; /* { dg-error "array subscript is negative" } */
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__LONG_LONG_MAX__ + 2];
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ /* Likewise, this is only an arithmetic constant expression, not an integer
+ constant expression. */
+ (void) a[(int)-1.0];
+}
--- /dev/null
+/* Test C2y register array element access. Execution tests. */
+/* { dg-do run } */
+/* { dg-options "-std=c2y -pedantic-errors" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0;
+ for (int i = 0; i < n; i++)
+ c[i] = i;
+ for (int i = 0; i < 20; i++)
+ b[i] = i;
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i;
+ for (int i = 0; i < n; i++)
+ if (c[i] != i)
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i)
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i)
+ abort ();
+ if (a[0] != 0)
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3)
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2)
+ abort ();
+ if (false)
+ (void) a[12345];
+ if (false)
+ (void) b[23456];
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2];
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}
--- /dev/null
+/* Test C2y register array element access. Test warnings with
+ -Wc23-c2y-compat. */
+/* { dg-do run } */
+/* { dg-options "-std=c2y -pedantic-errors -Wc23-c2y-compat" } */
+
+extern void abort ();
+extern void exit (int);
+
+struct s { int a[10]; };
+
+int
+main ()
+{
+ int n = 10;
+ register int a[1], b[20], c[n];
+ register struct s v;
+ a[0] = 0; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ c[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 20; i++)
+ b[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < 10; i++)
+ v.a[i] = i; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ for (int i = 0; i < n; i++)
+ if (c[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 20; i++)
+ if (b[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ for (int i = 0; i < 10; i++)
+ if (v.a[i] != i) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (a[0] != 0) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register int[2]) { 2, 3 }[n / 10] != 3) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if ((register struct s) { 1, 2 }.a[n / 10] != 2) /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ abort ();
+ if (false)
+ (void) a[12345]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ (void) b[23456]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ if (false)
+ /* This index is not an integer constant expression, so the constraint
+ against negative indices does not apply. */
+ (void) a[__INT_MAX__ + 2]; /* { dg-warning "ISO C forbids subscripting 'register' array before C2Y" } */
+ /* { dg-warning "integer overflow in expression" "overflow" { target *-*-* } .-1 } */
+ exit (0);
+}