view gcc/testsuite/gcc.dg/Wstringop-overflow-11.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
line wrap: on
line source

/* PR tree-optimization/89350 - Wrong -Wstringop-overflow warning
   on a variable offset from the end of an array
   Test exercising -Wstringop-truncation with -Wall.
   -Wstringop-truncation is disabled to avoid warnings for strncpy
   calls whose bound matches the size of the destination getting
   in the way of -Wstringop-overflow.
   { dg-do compile }
   { dg-options "-O2 -Wall -Wno-stringop-truncation -ftrack-macro-expansion=0" }  */

#include "range.h"

extern void* memcpy (void*, const void*, size_t);
extern void* memset (void*, int, size_t);
extern char* strcpy (char*, const char*);
extern char* strncpy (char*, const char*, size_t);

void sink (void*);

#define CAT(pfx, line) pfx ## line
#define CONCAT(pfx, line) CAT (pfx, line)
#define UNIQ_NAME(pfx) CONCAT (pfx, __LINE__)

/* Exercise a call to memset with a distinct destination object each
   time to prevent GCC from reusing the destination pointer in later
   tests.  */
#define T(off1, off2, n)			\
  do {						\
    extern char UNIQ_NAME (ga)[7];		\
    char *d = UNIQ_NAME (ga) + off1;		\
    d += off2;					\
    memset (d, 0, n);				\
    sink (d);					\
  } while (0)


/* Exercise calls to memset with a destination pointer pointing to
   an array plus constant offset plus variable offset, in that order.  */

void test_memset_array_cst_range_off (void)
{
  T (1, SR (-7, 7), 7);
  T (1, SR (-1, 1), 7);
  T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (1, SR ( 1, 2), 1);
  T (1, SR ( 1, 2), 5);

  T (1, SR ( 0, 1), 6);
  T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR (-7, 7), 7);
  T (2, SR (-2, 7), 7);
  T (2, SR (-1, 1), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR ( 1, 2), 1);
  T (2, SR ( 1, 2), 3);
  T (2, SR ( 1, 2), 4);
  T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
  T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-7, 0), 7);
  T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-3, 2), 3);
  T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


/* Exercise calls to memset with a destination pointer pointing to
   an array plus variable offset plus constant offset.  */

void test_memset_array_range_cst_off (void)
{
  T (SR (-7, 7), 1, 7);
  T (SR (-1, 1), 1, 7);
  T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
  T (SR ( 1, 2), 1, 1);
  T (SR ( 1, 2), 1, 5);

  T (SR ( 0, 1), 1, 6);
  T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR (-7, 7), 2, 7);
  T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR ( 1, 2), 2, 1);
  T (SR ( 1, 2), 2, 3);
  T (SR ( 1, 2), 2, 4);
  T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_memset_array_range_range_off (void)
{
  T (UR (0, 1), UR (0, 1), 7);
  T (UR (3, 5), UR (2, 7), 1);
  T (UR (3, 7), UR (2, 9), 2);
  T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


#undef T
#define T(off1, off2, n)			\
  do {						\
    extern char UNIQ_NAME (ga)[7];		\
    char *d = UNIQ_NAME (ga) + off1;		\
    d += off2;					\
    memcpy (d, s, n);				\
    sink (d);					\
  } while (0)


void test_memcpy_array_cst_range_off (const void *s)
{
  T (1, SR (-7, 7), 7);
  T (1, SR (-1, 1), 7);
  T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (1, SR ( 1, 2), 1);
  T (1, SR ( 1, 2), 5);

  T (1, SR ( 0, 1), 6);
  T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR (-7, 7), 7);
  T (2, SR (-2, 7), 7);
  T (2, SR (-1, 1), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR ( 1, 2), 1);
  T (2, SR ( 1, 2), 3);
  T (2, SR ( 1, 2), 4);
  T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
  T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-7, 0), 7);
  T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-3, 2), 3);
  T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_memcpy_array_range_cst_off (const void *s)
{
  T (SR (-7, 7), 1, 7);
  T (SR (-1, 1), 1, 7);
  T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
  T (SR ( 1, 2), 1, 1);
  T (SR ( 1, 2), 1, 5);

  T (SR ( 0, 1), 1, 6);
  T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR (-7, 7), 2, 7);
  T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR ( 1, 2), 2, 1);
  T (SR ( 1, 2), 2, 3);
  T (SR ( 1, 2), 2, 4);
  T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_memcpy_array_range_range_off (const void *s)
{
  T (UR (0, 1), UR (0, 1), 7);
  T (UR (3, 5), UR (2, 7), 1);
  T (UR (3, 7), UR (2, 9), 2);
  T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


#undef T
#define T(off1, off2, n)			\
  do {						\
    extern char UNIQ_NAME (ga)[7];		\
    char *d = UNIQ_NAME (ga) + off1;		\
    d += off2;					\
    const char str[] = "0123456789";		\
    const char *s = str + sizeof str - 1 - n;   \
    strcpy (d, s);				\
    sink (d);					\
  } while (0)


void test_strcpy_array_cst_range_off (void)
{
  T (1, SR (-7, 7), 6);
  T (1, SR (-1, 1), 6);
  T (1, SR (-1, 1), 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (1, SR ( 1, 2), 0);
  T (1, SR ( 1, 2), 4);

  T (1, SR ( 0, 1), 5);
  T (1, UR ( 1, 2), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR (-7, 7), 6);
  T (2, SR (-2, 7), 6);
  T (2, SR (-1, 1), 6);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR (-1, 1), 8);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR ( 1, 2), 0);
  T (2, SR ( 1, 2), 2);
  T (2, SR ( 1, 2), 3);
  T (2, SR ( 1, 2), 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR ( 0, 1), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
  T (2, UR ( 1, 2), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-7, 0), 6);
  T (7, UR (-7, 0), 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-3, 2), 2);
  T (7, UR (-2, 2), 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_strcpy_array_range_cst_off (const char *s)
{
  T (SR (-7, 7), 1, 6);
  T (SR (-1, 1), 1, 6);
  T (SR (-1, 1), 1, 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
  T (SR ( 1, 2), 1, 0);
  T (SR ( 1, 2), 1, 1);
  T (SR ( 1, 2), 1, 4);

  T (SR ( 0, 1), 1, 5);
  T (UR ( 1, 2), 1, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR (-7, 7), 2, 6);
  T (SR (-1, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR (-1, 1), 2, 8);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR ( 1, 2), 2, 0);
  T (SR ( 1, 2), 2, 1);
  T (SR ( 1, 2), 2, 2);
  T (SR ( 1, 2), 2, 3);
  T (SR ( 1, 2), 2, 4);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR ( 0, 1), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (UR ( 1, 2), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


#undef T
#define T(off1, off2, n)			\
  do {						\
    extern char UNIQ_NAME (ga)[7];		\
    char *d = UNIQ_NAME (ga) + off1;		\
    d += off2;					\
    strncpy (d, s, n);				\
    sink (d);					\
  } while (0)


void test_strncpy_array_cst_range_off (const char *s)
{
  T (1, SR (-7, 7), 7);
  T (1, SR (-1, 1), 7);
  T (1, SR (-1, 1), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (1, SR ( 1, 2), 1);
  T (1, SR ( 1, 2), 5);

  T (1, SR ( 0, 1), 6);
  T (1, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR ( -7, 7), 7);
  T (2, SR ( -1, 1), 7);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR ( -1, 1), 9);      /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (2, SR ( 1, 2), 1);
  T (2, SR ( 1, 2), 3);
  T (2, SR ( 1, 2), 4);
  T (2, SR ( 1, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (2, SR ( 0, 1), 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-* } } */
  T (2, UR ( 1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-7, 0), 7);
  T (7, UR (-7, 0), 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (7, UR (-3, 2), 3);
  T (7, UR (-2, 2), 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_strncpy_array_range_cst_off (const char *s)
{
  T (SR (-7, 7), 1, 7);
  T (SR (-1, 1), 1, 7);
  T (SR (-1, 1), 1, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
  T (SR ( 1, 2), 1, 1);
  T (SR ( 1, 2), 1, 5);

  T (SR ( 0, 1), 1, 6);
  T (UR ( 1, 2), 1, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR (-7, 7), 2, 7);
  T (SR (-1, 1), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR (-1, 1), 2, 9);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (SR ( 1, 2), 2, 1);
  T (SR ( 1, 2), 2, 3);
  T (SR ( 1, 2), 2, 4);
  T (SR ( 1, 2), 2, 5);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (SR ( 0, 1), 2, 6);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */

  T (UR ( 1, 2), 2, 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}


void test_strncpy_array_range_range_off (const char *s)
{
  T (UR (0, 1), UR (0, 1), 7);
  T (UR (3, 5), UR (2, 7), 1);
  T (UR (3, 7), UR (2, 9), 2);
  T (UR (3, 9), UR (2, 9), 3);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
  T (UR (0, 1), UR (1, 2), 7);       /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
}