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)
      {

Reply via email to