blob: 239bbfe5148372e8e733635254cc7a911a4c26bd [file] [log] [blame]
/* PR tree-optimization/90879 - fold zero-equality of strcmp between
a longer string and a smaller array
{ dg-do compile }
{ dg-options "-O2 -Wall -Wextra -ftrack-macro-expansion=0" } */
#include "strlenopt.h"
#define T(a, b) sink (0 == strcmp (a, b), a, b)
void sink (int, ...);
struct S { char a4[4], c; };
extern char a4[4];
extern char a5[5];
extern char b4[4];
/* Verify that comparison of string literals with arrays with unknown
content but size that prevents them from comparing equal is diagnosed. */
void strcmp_array_lit (void)
{
if (strcmp (a4, "1234")) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
// { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 }
sink (0, a4);
int cmp;
cmp = strcmp (a4, "1234"); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
if (cmp) // { dg-message "in this expression" }
sink (0, a4);
T (a4, "4321"); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero " }
T (a4, "12345"); // { dg-warning "length 5 and an array of size 4 " }
T (a4, "123456"); // { dg-warning "length 6 and an array of size 4 " }
T ("1234", a4); // { dg-warning "length 4 and an array of size 4 " }
T ("12345", a4); // { dg-warning "length 5 and an array of size 4 " }
T ("123456", a4); // { dg-warning "length 6 and an array of size 4 " }
}
void strcmp_array_pstr (void)
{
const char *s4 = "1234";
{
if (strcmp (a4, s4)) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
// { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 }
sink (1, a4);
else
sink (0, a4);
}
{
int c;
c = strcmp (a4, s4); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
if (c) // { dg-message "in this expression" }
sink (1, a4);
else
sink (0, a4);
}
const char *t4 = "4321";
const char *s5 = "12345";
const char *s6 = "123456";
T (a4, t4); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero " }
T (a4, s5); // { dg-warning "length 5 and an array of size 4 " }
T (a4, s6); // { dg-warning "length 6 and an array of size 4 " }
T (s4, a4); // { dg-warning "length 4 and an array of size 4 " }
T (s5, a4); // { dg-warning "length 5 and an array of size 4 " }
T (s6, a4); // { dg-warning "length 6 and an array of size 4 " }
}
void strcmp_array_cond_pstr (int i)
{
const char *s4 = i ? "1234" : "4321";
T (a4, s4); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero " }
T (a5, s4);
}
void strcmp_array_copy (void)
{
char s[8];
{
strcpy (s, "1234");
if (strcmp (a4, s)) // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
// { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 }
sink (1, a4);
else
sink (0, a4);
}
{
strcpy (s, "1234");
int c;
c = strcmp (a4, s); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero" }
if (c) // { dg-message "in this expression" }
sink (1, a4);
else
sink (0, a4);
}
strcpy (s, "4321");
T (a4, s); // { dg-warning "'strcmp' of a string of length 4 and an array of size 4 evaluates to nonzero " }
strcpy (s, "12345");
T (a4, s); // { dg-warning "length 5 and an array of size 4 " }
strcpy (s, "123456");
T (a4, s); // { dg-warning "length 6 and an array of size 4 " }
strcpy (s, "4321");
T (s, a4); // { dg-warning "length 4 and an array of size 4 " }
strcpy (s, "54321");
T (s, a4); // { dg-warning "length 5 and an array of size 4 " }
strcpy (s, "654321");
T (s, a4); // { dg-warning "length 6 and an array of size 4 " }
}
void strcmp_member_array_lit (const struct S *p)
{
// Not handled due to the fix for PR 92756.
T (p->a4, "1234"); // { dg-warning "length 4 and an array of size 4 " "pr92765" { xfail *-*-* } }
}
#undef T
#define T(a, b, n) sink (0 == strncmp (a, b, n), a, b)
void strncmp_array_lit (void)
{
if (strncmp (a4, "12345", 5)) // { dg-warning "'strncmp' of a string of length 5, an array of size 4 and bound of 5 evaluates to nonzero" }
// { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 }
sink (0, a4);
int cmp;
cmp = strncmp (a4, "54321", 5); // { dg-warning "'strncmp' of a string of length 5, an array of size 4 and bound of 5 evaluates to nonzero" }
if (cmp) // { dg-message "in this expression" }
sink (0, a4);
// Verify no warning when the bound is the same as the array size.
T (a4, "4321", 4);
T (a4, "654321", 4);
T (a4, "12345", 5); // { dg-warning "length 5, an array of size 4 and bound of 5 " }
T (a4, "123456", 6); // { dg-warning "length 6, an array of size 4 and bound of 6" }
T ("1234", a4, 4);
T ("12345", a4, 4);
T ("12345", a4, 5); // { dg-warning "length 5, an array of size 4 and bound of 5 " }
T ("123456", a4, 6); // { dg-warning "length 6, an array of size 4 and bound of 6 " }
}
void strncmp_strarray_copy (void)
{
{
char a[] = "1234";
char b[6];
strcpy (b, "12345");
if (strncmp (a, b, 5)) // { dg-warning "'strncmp' of strings of length 4 and 5 and bound of 5 evaluates to nonzero" }
// { dg-bogus "in this expression" "unwanted note" { target *-*-* } .-1 }
sink (0, a, b);
}
{
char a[] = "4321";
char b[6];
strcpy (b, "54321");
int cmp;
cmp = strncmp (a, b, 5); // { dg-warning "'strncmp' of strings of length 4 and 5 and bound of 5 evaluates to nonzero" }
if (cmp) // { dg-message "in this expression" }
sink (0, a, b);
}
strcpy (a4, "abc");
T (a4, "54321", 5); // { dg-warning "'strncmp' of strings of length 3 and 5 and bound of 5 evaluates to nonzero " }
}