PR 51256 points out that
void *p;
__atomic_compare_exchange(p, p, p, 0, 0, 0);
results in an ICE.
This patch reports the error that a generic function call must not have
a void pointer for the first argument, or a size of the object cannot be
determined. It also now returns error_mark_node whenever there was a
parameter error for better handling.
Bootstrapped on x86_64-unknown-linux-gnu with no new regressions. OK
for mainline?
Andrew
PR c/51256
* c-common.c (get_atomic_generic_size): First parameter must not be
a void pointer.
(resolve_overloaded_atomic_exchange,
resolve_overloaded_atomic_compare_exchange,
resolve_overloaded_atomic_load, resolve_overloaded_atomic_store): Return
error_mark_node for error conditions.
Index: c-family/c-common.c
===================================================================
*** c-family/c-common.c (revision 181350)
--- c-family/c-common.c (working copy)
*************** get_atomic_generic_size (location_t loc,
*** 9403,9411 ****
/* Get type of first parameter, and determine its size. */
type_0 = TREE_TYPE (VEC_index (tree, params, 0));
! if (TREE_CODE (type_0) != POINTER_TYPE)
{
! error_at (loc, "argument 1 of %qE must be a pointer type", function);
return 0;
}
size_0 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type_0)), 1);
--- 9403,9412 ----
/* Get type of first parameter, and determine its size. */
type_0 = TREE_TYPE (VEC_index (tree, params, 0));
! if (TREE_CODE (type_0) != POINTER_TYPE || VOID_TYPE_P (TREE_TYPE (type_0)))
{
! error_at (loc, "argument 1 of %qE must be a non-void pointer type",
! function);
return 0;
}
size_0 = tree_low_cst (TYPE_SIZE_UNIT (TREE_TYPE (type_0)), 1);
*************** resolve_overloaded_atomic_exchange (loca
*** 9515,9520 ****
--- 9516,9528 ----
tree I_type, I_type_ptr;
int n = get_atomic_generic_size (loc, function, params);
+ /* Size of 0 is an error condition. */
+ if (n == 0)
+ {
+ *new_return = error_mark_node;
+ return true;
+ }
+
/* If not a lock-free size, change to the library generic format. */
if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
{
*************** resolve_overloaded_atomic_exchange (loca
*** 9538,9545 ****
/* Convert object pointer to required type. */
p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
! VEC_replace (tree, params, 0, p0);
!
/* Convert new value to required type, and dereference it. */
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1);
--- 9546,9552 ----
/* Convert object pointer to required type. */
p0 = build1 (VIEW_CONVERT_EXPR, I_type_ptr, p0);
! VEC_replace (tree, params, 0, p0);
/* Convert new value to required type, and dereference it. */
p1 = build_indirect_ref (loc, p1, RO_UNARY_STAR);
p1 = build1 (VIEW_CONVERT_EXPR, I_type, p1);
*************** resolve_overloaded_atomic_compare_exchan
*** 9574,9579 ****
--- 9581,9593 ----
tree I_type, I_type_ptr;
int n = get_atomic_generic_size (loc, function, params);
+ /* Size of 0 is an error condition. */
+ if (n == 0)
+ {
+ *new_return = error_mark_node;
+ return true;
+ }
+
/* If not a lock-free size, change to the library generic format. */
if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
{
*************** resolve_overloaded_atomic_load (location
*** 9643,9648 ****
--- 9657,9669 ----
tree I_type, I_type_ptr;
int n = get_atomic_generic_size (loc, function, params);
+ /* Size of 0 is an error condition. */
+ if (n == 0)
+ {
+ *new_return = error_mark_node;
+ return true;
+ }
+
/* If not a lock-free size, change to the library generic format. */
if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
{
*************** resolve_overloaded_atomic_store (locatio
*** 9696,9701 ****
--- 9717,9729 ----
tree I_type, I_type_ptr;
int n = get_atomic_generic_size (loc, function, params);
+ /* Size of 0 is an error condition. */
+ if (n == 0)
+ {
+ *new_return = error_mark_node;
+ return true;
+ }
+
/* If not a lock-free size, change to the library generic format. */
if (n != 1 && n != 2 && n != 4 && n != 8 && n != 16)
{