/* Verify that strcmp and strncmp calls with mixed constant and non-constant strings are evaluated correctly. { dg-do run } { dg-options "-O2" } */ #include "strlenopt.h" #define A(expr) \ ((expr) \ ? (void)0 \ : (__builtin_printf ("assertion failed on line %i: %s\n", \ __LINE__, #expr), \ __builtin_abort ())) __attribute__ ((noclone, noinline)) int test_strlen_gt2_strcmp_abcd (const char *s) { if (strlen (s) < 3) return -1; return strcmp (s, "abcd") == 0; } __attribute__ ((noclone, noinline)) int test_strlen_lt6_strcmp_abcd (const char *s) { if (strlen (s) > 5) return -1; return strcmp (s, "abcd") == 0; } __attribute__ ((noclone, noinline)) int test_strcpy_strcmp_abc (const char *s) { char a[4]; strcpy (a, s); return strcmp (a, "abc") == 0; } __attribute__ ((noclone, noinline)) int test_strcpy_abc_strcmp (const char *s) { char a[4], b[6]; strcpy (a, "abc"); strcpy (b, s); return strcmp (a, b) == 0; } /* Exercise strcmp of two strings between 1 and 3 characters long stored in arrays of the same known size. */ char ga4[4], gb4[4]; __attribute__ ((noclone, noinline)) int test_store_0_nulterm_strcmp_same_size_arrays (void) { ga4[0] = gb4[0] = 'x'; ga4[3] = gb4[3] = '\0'; return strcmp (ga4, gb4) == 0; } __attribute__ ((noclone, noinline)) int test_store_0_nulterm_strncmp_bound_2_same_size_arrays (void) { ga4[0] = gb4[0] = 'x'; ga4[3] = gb4[3] = '\0'; return strncmp (ga4, gb4, 2) == 0; } __attribute__ ((noclone, noinline)) int test_store_0_nulterm_strncmp_bound_equal_same_size_arrays (void) { ga4[0] = gb4[0] = 'x'; ga4[3] = gb4[3] = '\0'; return strncmp (ga4, gb4, 4) == 0; } /* Exercise strcmp of two strings between 0 and 3 characters long stored in arrays of the same known size. */ __attribute__ ((noclone, noinline)) int test_nulterm_strcmp_same_size_arrays (void) { ga4[3] = gb4[3] = '\0'; return strcmp (ga4, gb4) == 0; } /* Exercise strcmp of two strings between 1 and 3 and 1 and 4 characters long, respectively, stored in arrays of known but different sizes. */ char gc5[5]; __attribute__ ((noclone, noinline)) int test_store_0_nulterm_strcmp_arrays (void) { ga4[0] = gc5[0] = 'x'; ga4[3] = gc5[4] = '\0'; return strcmp (ga4, gc5) == 0; } /* Exercise strcmp of two strings between 0 and 3 and 1 and 4 characters long, respectively, stored in arrays of known but different sizes. */ __attribute__ ((noclone, noinline)) int test_nulterm_strcmp_arrays (void) { ga4[3] = gc5[4] = '\0'; return strcmp (ga4, gc5) == 0; } __attribute__ ((noclone, noinline)) int test_strcpy_strncmp_abcd (const char *s) { char a[6]; strcpy (a, s); return strcmp (a, "abcd") == 0; } __attribute__ ((noclone, noinline)) int test_strcpy_abcd_strncmp_3 (const char *s) { char a[6], b[8]; strcpy (a, "abcd"); strcpy (b, s); return strncmp (a, b, 3) == 0; } __attribute__ ((noclone, noinline)) int test_strcpy_abcd_strncmp_4 (const char *s) { char a[6], b[8]; strcpy (a, "abcd"); strcpy (b, s); return strncmp (a, b, 4) == 0; } int main (void) { test_strlen_gt2_strcmp_abcd ("abcd"); test_strlen_lt6_strcmp_abcd ("abcd"); A (0 == test_strcpy_strcmp_abc ("ab")); A (0 != test_strcpy_strcmp_abc ("abc")); A (0 == test_strcpy_strcmp_abc ("abcd")); A (0 == test_strcpy_abc_strcmp ("ab")); A (0 != test_strcpy_abc_strcmp ("abc")); A (0 == test_strcpy_abc_strcmp ("abcd")); strcpy (ga4, "abc"); strcpy (gb4, "abd"); A (0 == test_store_0_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abd"); strcpy (gb4, "abc"); A (0 == test_store_0_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abc"); A (0 != test_store_0_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "acd"); A (0 == test_store_0_nulterm_strncmp_bound_2_same_size_arrays ()); strcpy (ga4, "acd"); strcpy (gb4, "abc"); A (0 == test_store_0_nulterm_strncmp_bound_2_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abc"); A (0 != test_store_0_nulterm_strncmp_bound_2_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abd"); A (0 == test_store_0_nulterm_strncmp_bound_equal_same_size_arrays ()); strcpy (ga4, "abd"); strcpy (gb4, "abc"); A (0 == test_store_0_nulterm_strncmp_bound_equal_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abc"); A (0 != test_store_0_nulterm_strncmp_bound_equal_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abd"); A (0 == test_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abd"); strcpy (gb4, "abc"); A (0 == test_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gb4, "abc"); A (0 != test_nulterm_strcmp_same_size_arrays ()); strcpy (ga4, "abc"); strcpy (gc5, "abcd"); A (0 == test_store_0_nulterm_strcmp_arrays ()); strcpy (ga4, "abd"); strcpy (gc5, "abcd"); A (0 == test_store_0_nulterm_strcmp_arrays ()); strcpy (ga4, "abc"); strcpy (gc5, "abc"); A (0 != test_store_0_nulterm_strcmp_arrays ()); strcpy (ga4, "abc"); strcpy (gc5, "abcd"); A (0 == test_nulterm_strcmp_arrays ()); strcpy (ga4, "abd"); strcpy (gc5, "abc"); A (0 == test_nulterm_strcmp_arrays ()); strcpy (ga4, "abc"); strcpy (gc5, "abc"); A (0 != test_nulterm_strcmp_arrays ()); A (0 == test_strcpy_strncmp_abcd ("ab")); A (0 == test_strcpy_strncmp_abcd ("abc")); A (0 != test_strcpy_strncmp_abcd ("abcd")); A (0 == test_strcpy_strncmp_abcd ("abcde")); A (0 == test_strcpy_abcd_strncmp_3 ("ab")); A (0 != test_strcpy_abcd_strncmp_3 ("abc")); A (0 != test_strcpy_abcd_strncmp_3 ("abcd")); A (0 != test_strcpy_abcd_strncmp_3 ("abcde")); A (0 == test_strcpy_abcd_strncmp_4 ("ab")); A (0 == test_strcpy_abcd_strncmp_4 ("abc")); A (0 != test_strcpy_abcd_strncmp_4 ("abcd")); A (0 != test_strcpy_abcd_strncmp_4 ("abcde")); }