(root)/
gcc-13.2.0/
gcc/
testsuite/
c-c++-common/
builtin-arith-overflow-1.c
       1  /* Test exercising invalid calls to arithmetic overflow checking built-ins,
       2     including PR c/71392 - SEGV calling integer overflow built-ins with a null
       3     pointer, (issuing a warning for such invocations).  */
       4  /* { dg-do compile } */
       5  /* { dg-additional-options "-Wnonnull" }
       6  
       7  /* Verify that calls with fewer or more than 3 arguments to the generic
       8     __builtin_op_overflow functions are rejected.  */
       9  
      10  #ifndef __cplusplus
      11  #define bool _Bool
      12  #endif
      13  
      14  int
      15  generic_0 (void)
      16  {
      17    int x = __builtin_add_overflow ();	/* { dg-error "too few arguments to function" } */
      18    x += __builtin_sub_overflow ();	/* { dg-error "too few arguments to function" } */
      19    x += __builtin_mul_overflow ();	/* { dg-error "too few arguments to function" } */
      20    x += __builtin_add_overflow_p ();	/* { dg-error "too few arguments to function" } */
      21    x += __builtin_sub_overflow_p ();	/* { dg-error "too few arguments to function" } */
      22    x += __builtin_mul_overflow_p ();	/* { dg-error "too few arguments to function" } */
      23    return x;
      24  }
      25  
      26  int
      27  generic_1 (int a)
      28  {
      29    int x = __builtin_add_overflow (a);	/* { dg-error "too few arguments to function" } */
      30    x += __builtin_sub_overflow (a);	/* { dg-error "too few arguments to function" } */
      31    x += __builtin_mul_overflow (a);	/* { dg-error "too few arguments to function" } */
      32  
      33    /* Literal argument.  */
      34    x += __builtin_add_overflow (1);	/* { dg-error "too few arguments to function" } */
      35    x += __builtin_sub_overflow (2);	/* { dg-error "too few arguments to function" } */
      36    x += __builtin_mul_overflow (3);	/* { dg-error "too few arguments to function" } */
      37    return x;
      38  }
      39  
      40  int
      41  generic_2 (int a, int b)
      42  {
      43    int x = __builtin_add_overflow (a, b);/* { dg-error "too few arguments to function" } */
      44    x += __builtin_sub_overflow (a, b);	/* { dg-error "too few arguments to function" } */
      45    x += __builtin_mul_overflow (a, b);	/* { dg-error "too few arguments to function" } */
      46    x += __builtin_add_overflow (a, 1);	/* { dg-error "too few arguments to function" } */
      47    x += __builtin_sub_overflow (a, 2);	/* { dg-error "too few arguments to function" } */
      48    x += __builtin_mul_overflow (a, 3);	/* { dg-error "too few arguments to function" } */
      49    x += __builtin_add_overflow (4, b);	/* { dg-error "too few arguments to function" } */
      50    x += __builtin_sub_overflow (5, b);	/* { dg-error "too few arguments to function" } */
      51    x += __builtin_mul_overflow (6, b);	/* { dg-error "too few arguments to function" } */
      52    return x;
      53  }
      54  
      55  /* Verify that calls with the correct number of arguments to the generic
      56     __builtin_op_overflow functions are accepted.  */
      57  
      58  int
      59  generic_3 (int a, int b, int c)
      60  {
      61    int x = __builtin_add_overflow (a, b, &c);
      62    x += __builtin_sub_overflow (a, b, &c);
      63    x += __builtin_mul_overflow (a, b, &c);
      64    x += __builtin_add_overflow (a, 1, &c);
      65    x += __builtin_sub_overflow (a, 2, &c);
      66    x += __builtin_mul_overflow (a, 3, &c);
      67    x += __builtin_add_overflow (4, b, &c);
      68    x += __builtin_sub_overflow (5, b, &c);
      69    x += __builtin_mul_overflow (6, b, &c);
      70    x += __builtin_add_overflow (7, 8, &c);
      71    x += __builtin_sub_overflow (9, 10, &c);
      72    x += __builtin_mul_overflow (11, 12, &c);
      73  
      74    /* Verify that a null pointer to an integer is diagnosed.  */
      75  
      76    /* The following two are rejected due to c/71479 - error on
      77       __builtin_add_overflow with bool or enum pointer as last argument.
      78  
      79      x += __builtin_add_overflow (0, 0, (bool *)0);
      80  
      81      enum E { e0 };
      82      x += __builtin_add_overflow (0, 0, (enum E *)0);  */
      83  
      84    x += __builtin_sub_overflow (0, 0, (char *)0);   /* { dg-warning "argument 3 null" } */
      85    x += __builtin_add_overflow (0, 0, (short *)0);   /* { dg-warning "argument 3 null" } */
      86    x += __builtin_add_overflow (a, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      87    x += __builtin_sub_overflow (a, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      88    x += __builtin_mul_overflow (a, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      89    x += __builtin_add_overflow (a, 1, (int *)0);   /* { dg-warning "argument 3 null" } */
      90    x += __builtin_sub_overflow (a, 2, (int *)0);   /* { dg-warning "argument 3 null" } */
      91    x += __builtin_mul_overflow (a, 3, (int *)0);   /* { dg-warning "argument 3 null" } */
      92    x += __builtin_add_overflow (4, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      93    x += __builtin_sub_overflow (5, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      94    x += __builtin_mul_overflow (6, b, (int *)0);   /* { dg-warning "argument 3 null" } */
      95    x += __builtin_add_overflow (7, 8, (int *)0);   /* { dg-warning "argument 3 null" } */
      96    x += __builtin_sub_overflow (9, 10, (int *)0);   /* { dg-warning "argument 3 null" } */
      97    x += __builtin_mul_overflow (11, 12, (int *)0);   /* { dg-warning "argument 3 null" } */
      98  
      99    return x;
     100  }
     101  
     102  int
     103  generic_4 (int a, int b, int *c, int d)
     104  {
     105    int x = __builtin_add_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     106    x += __builtin_sub_overflow (a, b, c, d, d, d);	/* { dg-error "too many arguments to function" } */
     107    x += __builtin_sub_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     108    x += __builtin_mul_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     109    return x;
     110  }
     111  
     112  /* Verify that calls with fewer or more than 3 arguments to the type
     113     specific forms of the __builtin_op_overflow functions are rejected.  */
     114  
     115  int
     116  generic_wrong_type (int a, int b)
     117  {
     118    void *p = 0;
     119    double d = 0;
     120    int x = __builtin_add_overflow (a, b, p);   /* { dg-error "does not have pointer to integral type" } */
     121    x += __builtin_sub_overflow (a, b, &p);     /* { dg-error "does not have pointer to integral type" } */
     122    x += __builtin_mul_overflow (a, b, &d);     /* { dg-error "does not have pointer to integral type" } */
     123  
     124    /* Also verify literal arguments.  */
     125    x += __builtin_add_overflow (1, 1, p);   /* { dg-error "does not have pointer to integral type" } */
     126    x += __builtin_sub_overflow (1, 1, &p);     /* { dg-error "does not have pointer to integral type" } */
     127    x += __builtin_mul_overflow (1, 1, &d);     /* { dg-error "does not have pointer to integral type" } */
     128    return x;
     129  }
     130  
     131  /* Verify that calls with fewer than 2 or more than 3 arguments to
     132     the typed __builtin_op_overflow functions are rejected.  */
     133  int
     134  typed_0 (void)
     135  {
     136    int x = __builtin_add_overflow ();	/* { dg-error "too few arguments to function" } */
     137    x += __builtin_sub_overflow ();	/* { dg-error "too few arguments to function" } */
     138    x += __builtin_mul_overflow ();	/* { dg-error "too few arguments to function" } */
     139    return x;
     140  }
     141  
     142  int
     143  typed_1 (int a)
     144  {
     145    int x = __builtin_sadd_overflow (a);	/* { dg-error "too few arguments to function" } */
     146    x += __builtin_ssub_overflow (a);	/* { dg-error "too few arguments to function" } */
     147    x += __builtin_smul_overflow (a);	/* { dg-error "too few arguments to function" } */
     148    return x;
     149  }
     150  
     151  int
     152  typed_2 (int a, int b)
     153  {
     154    int x = __builtin_sadd_overflow (a, b);  /* { dg-error "too few arguments to function" } */
     155    x += __builtin_ssub_overflow (a, b);	   /* { dg-error "too few arguments to function" } */
     156    x += __builtin_smul_overflow (a, b);	   /* { dg-error "too few arguments to function" } */
     157    return x;
     158  }
     159  
     160  /* Exercise PR c/71392 - SEGV calling integer overflow built-ins with
     161     a null pointer.  Verify that calls with a null argument are diagnosed
     162     with -Wnonnull.  */
     163  
     164  int
     165  typed_3_null (int a, int b)
     166  {
     167    int x = 0;
     168  
     169    x += __builtin_sadd_overflow (a, b, (int *)0); /* { dg-warning "argument 3 null" } */
     170    x += __builtin_uadd_overflow (a, b, (unsigned *)0); /* { dg-warning "argument 3 null" } */
     171  
     172    x += __builtin_saddl_overflow (a, b, (long *)0); /* { dg-warning "argument 3 null" } */
     173    x += __builtin_uaddl_overflow (a, b, (unsigned long *)0); /* { dg-warning "argument 3 null" } */
     174  
     175    x += __builtin_saddll_overflow (a, b, (long long *)0); /* { dg-warning "argument 3 null" } */
     176    x += __builtin_uaddll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "argument 3 null" } */
     177  
     178  
     179    x += __builtin_ssub_overflow (a, b, (int *)0); /* { dg-warning "argument 3 null" } */
     180    x += __builtin_usub_overflow (a, b, (unsigned *)0); /* { dg-warning "argument 3 null" } */
     181  
     182    x += __builtin_ssubl_overflow (a, b, (long *)0); /* { dg-warning "argument 3 null" } */
     183    x += __builtin_usubl_overflow (a, b, (unsigned long *)0); /* { dg-warning "argument 3 null" } */
     184  
     185    x += __builtin_ssubll_overflow (a, b, (long long *)0); /* { dg-warning "argument 3 null" } */
     186    x += __builtin_usubll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "argument 3 null" } */
     187  
     188  
     189    x += __builtin_smul_overflow (a, b, (int *)0); /* { dg-warning "argument 3 null" } */
     190    x += __builtin_umul_overflow (a, b, (unsigned *)0); /* { dg-warning "argument 3 null" } */
     191  
     192    x += __builtin_smull_overflow (a, b, (long *)0); /* { dg-warning "argument 3 null" } */
     193    x += __builtin_umull_overflow (a, b, (unsigned long *)0); /* { dg-warning "argument 3 null" } */
     194  
     195    x += __builtin_smulll_overflow (a, b, (long long *)0); /* { dg-warning "argument 3 null" } */
     196    x += __builtin_umulll_overflow (a, b, (unsigned long long *)0); /* { dg-warning "argument 3 null" } */
     197  
     198    return x;
     199  }
     200  
     201  int
     202  typed_4 (int a, int b, int *c, int d)
     203  {
     204    int x = __builtin_sadd_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     205    x += __builtin_ssub_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     206    x += __builtin_smul_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     207    return x;
     208  }
     209  
     210  int
     211  f2 (int a, int b, int *c, int d)
     212  {
     213    int x = __builtin_add_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     214    x += __builtin_sub_overflow (a, b, c, d, d, d);	/* { dg-error "too many arguments to function" } */
     215    x += __builtin_mul_overflow (a, b, c, d);	/* { dg-error "too many arguments to function" } */
     216    x += __builtin_add_overflow_p (a, b, d, d);	/* { dg-error "too many arguments to function" } */
     217    x += __builtin_sub_overflow_p (a, b, d, d, 1, d);	/* { dg-error "too many arguments to function" } */
     218    x += __builtin_mul_overflow_p (a, b, d, d);	/* { dg-error "too many arguments to function" } */
     219  
     220    return x;
     221  }
     222  
     223  enum E { e0 = 0, e1 = 1 };
     224  
     225  int
     226  f3 (float fa, int a, _Complex long int ca, double fb, void *pb, int b, enum E eb, bool bb, int *c)
     227  {
     228    int x = __builtin_add_overflow (fa, b, c);	/* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */
     229    x += __builtin_sub_overflow (ca, b, c);	/* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */
     230    x += __builtin_mul_overflow (a, fb, c);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
     231    x += __builtin_add_overflow (a, pb, c);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
     232    x += __builtin_sub_overflow (a, eb, c);
     233    x += __builtin_mul_overflow (a, bb, c);
     234    x += __builtin_add_overflow_p (fa, b, a);	/* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */
     235    x += __builtin_sub_overflow_p (ca, b, eb);	/* { dg-error "argument 1 in call to function\[^\n\r]*does not have integral type" } */
     236    x += __builtin_mul_overflow_p (a, fb, bb);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
     237    x += __builtin_add_overflow_p (a, pb, a);	/* { dg-error "argument 2 in call to function\[^\n\r]*does not have integral type" } */
     238    x += __builtin_sub_overflow_p (a, eb, eb);	/* { dg-error "argument 3 in call to function\[^\n\r]*has enumerated type" } */
     239    x += __builtin_mul_overflow_p (a, bb, bb);	/* { dg-error "argument 3 in call to function\[^\n\r]*has boolean type" } */
     240    x += __builtin_add_overflow_p (a, b, fa);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
     241    x += __builtin_sub_overflow_p (a, b, ca);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
     242    x += __builtin_mul_overflow_p (a, b, c);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have integral type" } */
     243    return x;
     244  }
     245  
     246  int
     247  f4 (float *fp, double *dp, _Complex int *cp, enum E *ep, bool *bp, long long int *llp)
     248  {
     249    int x = __builtin_add_overflow (1, 2, fp);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have pointer to integral type" } */
     250    x += __builtin_sub_overflow (1, 2, dp);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have pointer to integral type" } */
     251    x += __builtin_mul_overflow (1, 2, cp);	/* { dg-error "argument 3 in call to function\[^\n\r]*does not have pointer to integral type" } */
     252    x += __builtin_add_overflow (1, 2, ep);	/* { dg-error "argument 3 in call to function\[^\n\r]*has pointer to enumerated type" } */
     253    x += __builtin_sub_overflow (1, 2, bp);	/* { dg-error "argument 3 in call to function\[^\n\r]*has pointer to boolean type" } */
     254    x += __builtin_mul_overflow (1, 2, llp);
     255    return x;
     256  }