Viewing file: strlenopt-71.c (4.48 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* PR tree-optimization/91183 - strlen of a strcpy result with a conditional source not folded Runtime test to verify that multibyte stores are handled correctly. { dg-do run } { dg-options "-O2 -Wall" } */
#include "strlenopt.h"
#define CHAR_BIT __CHAR_BIT__
typedef __UINT16_TYPE__ uint16_t; typedef __UINT32_TYPE__ uint32_t;
#define NOIPA __attribute__ ((noclone, noinline, noipa))
/* Prevent the optimizer from detemining invariants from prior tests. */ NOIPA void terminate (void) { __builtin_abort (); }
#define VERIFY(expr, str) \ do { \ const unsigned expect = strlen (str); \ const unsigned len = strlen (expr); \ if (len != expect) \ { \ __builtin_printf ("line %i: strlen(%s) == %u failed: " \ "got %u with a = \"%.*s\"\n", \ __LINE__, #expr, expect, len, \ (int)sizeof a, a); \ terminate (); \ } \ if (memcmp (a, str, expect + 1)) \ { \ __builtin_printf ("line %i: expected string \"%s\", " \ "got a = \"%.*s\"\n", \ __LINE__, str, (int)sizeof a, a); \ terminate (); \ } \ } while (0)
#define ELT(s, i) ((s "\0\0\0\0")[i])
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ # define I16(s) (((uint16_t)ELT (s, 0) << 8) + (uint16_t)ELT (s, 1)) # define I32(s) \ (((uint32_t)ELT (s, 0) << 24) \ + ((uint32_t)ELT (s, 1) << 16) \ + ((uint32_t)ELT (s, 2) << 8) \ + (uint32_t)ELT (s, 3)) #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ # define I16(s) (((uint16_t)ELT (s, 1) << 8) + (uint16_t)ELT (s, 0)) # define I32(s) \ (((uint32_t)ELT (s, 3) << 24) \ + ((uint32_t)ELT (s, 2) << 16) \ + ((uint32_t)ELT (s, 1) << 8) \ + (uint32_t)ELT (s, 0)) #endif
char a[32];
NOIPA void i16_1 (void) { *(uint16_t*)a = I16 ("12"); *(uint16_t*)(a + 2) = I16 ("3"); VERIFY (a, "123");
*(uint16_t*)(a + 1) = I16 ("23"); VERIFY (a, "123");
*(uint16_t*)(a) = I16 ("12"); VERIFY (a, "123");
*(uint16_t*)(a + 1) = I16 ("2"); VERIFY (a, "12");
*(uint16_t*)(a + 3) = I16 ("45"); *(uint16_t*)(a + 2) = I16 ("34"); VERIFY (a, "12345"); }
NOIPA void i16_2 (void) { strcpy (a, "12"); strcat (a, "34");
*(uint16_t*)a = I16 ("12"); VERIFY (a, "1234");
*(uint16_t*)(a + 1) = I16 ("12"); VERIFY (a, "1124");
*(uint16_t*)(a + 2) = I16 ("12"); VERIFY (a, "1112");
*(uint16_t*)(a + 3) = I16 ("12"); VERIFY (a, "11112");
*(uint16_t*)(a + 4) = I16 ("12"); VERIFY (a, "111112"); }
NOIPA void i32_1 (void) { *(uint32_t*)a = I32 ("1234"); VERIFY (a, "1234");
*(uint32_t*)(a + 1) = I32 ("2345"); VERIFY (a, "12345"); }
NOIPA void i32_2 (void) { strcpy (a, "12"); strcat (a, "34");
*(uint32_t*)a = I32 ("1234"); VERIFY (a, "1234");
*(uint32_t*)(a + 4) = I32 ("567"); VERIFY (a, "1234567");
*(uint32_t*)(a + 7) = I32 ("89\0"); VERIFY (a, "123456789");
*(uint32_t*)(a + 3) = I32 ("4567"); VERIFY (a, "123456789");
*(uint32_t*)(a + 2) = I32 ("3456"); VERIFY (a, "123456789");
*(uint32_t*)(a + 1) = I32 ("2345"); VERIFY (a, "123456789"); }
NOIPA void i32_3 (void) { strcpy (a, "1234"); strcat (a, "5678");
*(uint32_t*)a = I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)(a + 1) = I32 ("234"); VERIFY (a, "1234");
*(uint32_t*)(a + 2) = I32 ("3456"); VERIFY (a, "12345678");
*(uint32_t*)(a + 3) = I32 ("4567"); VERIFY (a, "12345678");
*(uint32_t*)(a + 4) = I32 ("5678"); VERIFY (a, "12345678");
*(uint32_t*)(a + 5) = I32 ("6789"); VERIFY (a, "123456789");
*(uint32_t*)(a + 6) = I32 ("789A"); VERIFY (a, "123456789A"); }
volatile int vzero = 0;
NOIPA void i32_4 (void) { strcpy (a, "1234"); strcat (a, "5678");
*(uint32_t*)a = vzero ? I32 ("1\0\0\0") : I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)a = vzero ? I32 ("12\0\0") : I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)a = vzero ? I32 ("123\0") : I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)a = vzero ? I32 ("1234") : I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)a = vzero ? I32 ("1235") : I32 ("1234"); VERIFY (a, "12345678");
*(uint32_t*)a = vzero ? I32 ("1234") : I32 ("123\0"); VERIFY (a, "123");
*(uint32_t*)(a + 3) = vzero ? I32 ("456\0") : I32 ("4567"); VERIFY (a, "12345678"); }
int main () { memset (a, 0, sizeof a); i16_1 ();
memset (a, 0, sizeof a); i16_2 ();
memset (a, 0, sizeof a); i32_1 ();
memset (a, 0, sizeof a); i32_2 ();
memset (a, 0, sizeof a); i32_3 ();
memset (a, 0, sizeof a); i32_4 (); }
|