diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-07-27 10:15:41 -0700 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-07-27 10:15:41 -0700 |
commit | 9f62ed218fa656607740b386c0caa03e65dcd283 (patch) | |
tree | 6bde49bc5e4c4241266b108e4277baef4b85535d /gcc/testsuite/gcc.dg | |
parent | 71e955da39cea0ebffcfee3432effa622d14ca99 (diff) | |
parent | 5eb9f117a361538834b9740d59219911680717d1 (diff) | |
download | gcc-9f62ed218fa656607740b386c0caa03e65dcd283.zip gcc-9f62ed218fa656607740b386c0caa03e65dcd283.tar.gz gcc-9f62ed218fa656607740b386c0caa03e65dcd283.tar.bz2 |
Merge from trunk revision 5eb9f117a361538834b9740d59219911680717d1.
Diffstat (limited to 'gcc/testsuite/gcc.dg')
508 files changed, 13017 insertions, 393 deletions
diff --git a/gcc/testsuite/gcc.dg/20020312-2.c b/gcc/testsuite/gcc.dg/20020312-2.c index 52c33d0..92bc150 100644 --- a/gcc/testsuite/gcc.dg/20020312-2.c +++ b/gcc/testsuite/gcc.dg/20020312-2.c @@ -37,6 +37,8 @@ extern void abort (void); /* PIC register is r1, but is used even without -fpic. */ #elif defined(__lm32__) /* No pic register. */ +#elif defined(__loongarch__) +/* No pic register. */ #elif defined(__M32R__) /* No pic register. */ #elif defined(__m68k__) diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c index da179a2..5cae856 100644 --- a/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c +++ b/gcc/testsuite/gcc.dg/Warray-bounds-48-novec.c @@ -238,15 +238,17 @@ static void warn_a1_init (struct A1 *p) static void warn_a1_local_buf (struct A1 *p) { - p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; + p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; + p->a1[3] = 3; // { dg-warning "\\\[-Warray-bounds" "" { target default_packed } } p->a1[4] = 4; // { dg-warning "\\\[-Warray-bounds" } } static void warn_a1_extern_buf (struct A1 *p) { - p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; p->a1[4] = 4; + p->a1[0] = 0; p->a1[1] = 1; p->a1[2] = 2; p->a1[3] = 3; + p->a1[4] = 4; // { dg-warning "\\\[-Warray-bounds" "" { target default_packed } } p->a1[5] = 5; // { dg-warning "\\\[-Warray-bounds" } } diff --git a/gcc/testsuite/gcc.dg/Wattributes-8.c b/gcc/testsuite/gcc.dg/Wattributes-8.c index a4b4c00..8f5483e 100644 --- a/gcc/testsuite/gcc.dg/Wattributes-8.c +++ b/gcc/testsuite/gcc.dg/Wattributes-8.c @@ -24,8 +24,10 @@ int c ATTR ((aligned (2))); // okay (reduces alignment) ASSERT (_Alignof (c) == 2); struct { - int a ATTR ((packed, aligned (2))); /* { dg-bogus "\\\[-Wattributes" } */ - int b ATTR ((aligned (2), packed)); /* { dg-bogus "\\\[-Wattributes" } */ + int a ATTR ((packed, aligned (2))); /* { dg-bogus "\\\[-Wattributes" "" { target { ! default_packed } } } */ + /* { dg-warning "attribute ignored" "" { target { default_packed } } .-1 } */ + int b ATTR ((aligned (2), packed)); /* { dg-bogus "\\\[-Wattributes" "" { target { ! default_packed } } } */ + /* { dg-warning "attribute ignored" "" { target { default_packed } } .-1 } */ /* Avoid exercising this since the attribute has no effect yet there is no warning. diff --git a/gcc/testsuite/gcc.dg/Wdangling-pointer-3.c b/gcc/testsuite/gcc.dg/Wdangling-pointer-3.c new file mode 100644 index 0000000..0185930 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wdangling-pointer-3.c @@ -0,0 +1,92 @@ +/* PR tree-optimization/104715 - false dangling pointer with strstr + Vertify that using pointers that have become dangling after they were + passed to and returned from strstr is diagnosed. + { dg-do compile } + { dg-options "-Wall" } */ + +extern char* strstr (const char*, const char*); + +void sink (const void*); + +void nowarn_strstr_static (const char *s) +{ + char *t1; + + { + static const char a[] = "abc"; + t1 = strstr (a, s); + sink (t1); + } + + sink (t1); +} + + +void nowarn_strstr_lit (const char *s) +{ + char *t2; + + { + t2 = strstr ("def", s); + sink (t2); + } + + sink (t2); +} + + +void warn_strstr_comp_lit (const char *s) +{ + char *t3; + + { + const char *a = + (char[]){ '1', '\0' }; // { dg-message "unnamed temporary defined here" } + t3 = strstr (a, s); + sink (t3); + } + + sink (t3); // { dg-warning "using dangling pointer 't3' to an unnamed temporary" } +} + + +void warn_strstr_arg (const char *s) +{ + char *t4; + + { + char a[] = "1"; // { dg-message "'a' declared here" } + t4 = strstr (a, s); + sink (t4); + } + + sink (t4); // { dg-warning "using dangling pointer 't4' to 'a'" } +} + + +void warn_strstr_arg_plus_cst (const char *s) +{ + char *t5; + + { + char a[] = "12"; // { dg-message "'a' declared here" } + t5 = strstr (a + 1, s); + sink (t5); + } + + sink (t5); // { dg-warning "using dangling pointer 't5' to 'a'" } +} + + +void warn_strstr_arg_plus_var (const char *s, int i) +{ + char *t6; + + { + char a[] = "123"; // { dg-message "'a' declared here" } + t6 = strstr (a + i, s); + sink (t6++); + } + + sink (t6); // { dg-warning "using dangling pointer 't6' to 'a'" } +} diff --git a/gcc/testsuite/gcc.dg/Wdangling-pointer-4.c b/gcc/testsuite/gcc.dg/Wdangling-pointer-4.c new file mode 100644 index 0000000..36c8da5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wdangling-pointer-4.c @@ -0,0 +1,22 @@ +/* PR middle-end/104761 - bogus -Wdangling-pointer with cleanup and infinite loop + { dg-do compile } + { dg-options "-O -Wall" } */ + +typedef struct { int i; } S; + +void f (S **); + +int g (int); + +void nowarn (int x) +{ + S s = { 0 }; + + __attribute__((__cleanup__ (f))) S *p = 0; + + if (x) + { + g (s.i); // { dg-bogus "-Wdangling-pointer" } + for ( ; ; ); + } +} diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c new file mode 100644 index 0000000..6298018 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-1.c @@ -0,0 +1,43 @@ +/* PR c/105131 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -fno-short-enums" } */ + +enum E { E1 = -1, E2 = 0, E3 = 1 }; + +int foo(void); /* { dg-message "previous declaration" } */ +enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */ + +void bar(int); /* { dg-message "previous declaration" } */ +void bar(enum E); /* { dg-warning "conflicting types" } */ + +extern int arr[10]; /* { dg-message "previous declaration" } */ +extern enum E arr[10]; /* { dg-warning "conflicting types" } */ + +extern int i; /* { dg-message "previous declaration" } */ +extern enum E i; /* { dg-warning "conflicting types" } */ + +extern int *p; /* { dg-message "previous declaration" } */ +extern enum E *p; /* { dg-warning "conflicting types" } */ + +enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */ +int foo2(void); /* { dg-warning "conflicting types" } */ + +void bar2(enum E); /* { dg-message "previous declaration" } */ +void bar2(int); /* { dg-warning "conflicting types" } */ + +extern enum E arr2[10]; /* { dg-message "previous declaration" } */ +extern int arr2[10]; /* { dg-warning "conflicting types" } */ + +extern enum E i2; /* { dg-message "previous declaration" } */ +extern int i2; /* { dg-warning "conflicting types" } */ + +extern enum E *p2; /* { dg-message "previous declaration" } */ +extern int *p2; /* { dg-warning "conflicting types" } */ + +enum F { F1 = -1, F2, F3 } __attribute__ ((__packed__)); + +enum F fn1(void); /* { dg-message "previous declaration" } */ +signed char fn1(void); /* { dg-warning "conflicting types" } */ + +signed char fn2(void); /* { dg-message "previous declaration" } */ +enum F fn2(void); /* { dg-warning "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c new file mode 100644 index 0000000..e5f7500 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-2.c @@ -0,0 +1,43 @@ +/* PR c/105131 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -fno-short-enums" } */ + +enum E { E1 = 0, E2, E3 }; + +unsigned int foo(void); /* { dg-message "previous declaration" } */ +enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */ + +void bar(unsigned int); /* { dg-message "previous declaration" } */ +void bar(enum E); /* { dg-warning "conflicting types" } */ + +extern enum E arr[10]; /* { dg-message "previous declaration" } */ +extern unsigned int arr[10]; /* { dg-warning "conflicting types" } */ + +extern unsigned int i; /* { dg-message "previous declaration" } */ +extern enum E i; /* { dg-warning "conflicting types" } */ + +extern unsigned int *p; /* { dg-message "previous declaration" } */ +extern enum E *p; /* { dg-warning "conflicting types" } */ + +enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */ +unsigned int foo2(void); /* { dg-warning "conflicting types" } */ + +void bar2(enum E); /* { dg-message "previous declaration" } */ +void bar2(unsigned int); /* { dg-warning "conflicting types" } */ + +extern unsigned int arr2[10]; /* { dg-message "previous declaration" } */ +extern enum E arr2[10]; /* { dg-warning "conflicting types" } */ + +extern enum E i2; /* { dg-message "previous declaration" } */ +extern unsigned int i2; /* { dg-warning "conflicting types" } */ + +extern enum E *p2; /* { dg-message "previous declaration" } */ +extern unsigned int *p2; /* { dg-warning "conflicting types" } */ + +enum F { F1 = 1u, F2, F3 } __attribute__ ((__packed__)); + +enum F fn1(void); /* { dg-message "previous declaration" } */ +unsigned char fn1(void); /* { dg-warning "conflicting types" } */ + +unsigned char fn2(void); /* { dg-message "previous declaration" } */ +enum F fn2(void); /* { dg-warning "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c new file mode 100644 index 0000000..4ddbeb1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-3.c @@ -0,0 +1,43 @@ +/* PR c/105131 */ +/* { dg-do compile } */ +/* { dg-options "-Wc++-compat -fno-short-enums" } */ + +enum E { E1 = -1, E2 = 0, E3 = 1 }; + +int foo(void); /* { dg-message "previous declaration" } */ +enum E foo(void) { return E2; } /* { dg-warning "conflicting types" } */ + +void bar(int); /* { dg-message "previous declaration" } */ +void bar(enum E); /* { dg-warning "conflicting types" } */ + +extern int arr[10]; /* { dg-message "previous declaration" } */ +extern enum E arr[10]; /* { dg-warning "conflicting types" } */ + +extern int i; /* { dg-message "previous declaration" } */ +extern enum E i; /* { dg-warning "conflicting types" } */ + +extern int *p; /* { dg-message "previous declaration" } */ +extern enum E *p; /* { dg-warning "conflicting types" } */ + +enum E foo2(void) { return E2; } /* { dg-message "previous definition" } */ +int foo2(void); /* { dg-warning "conflicting types" } */ + +void bar2(enum E); /* { dg-message "previous declaration" } */ +void bar2(int); /* { dg-warning "conflicting types" } */ + +extern enum E arr2[10]; /* { dg-message "previous declaration" } */ +extern int arr2[10]; /* { dg-warning "conflicting types" } */ + +extern enum E i2; /* { dg-message "previous declaration" } */ +extern int i2; /* { dg-warning "conflicting types" } */ + +extern enum E *p2; /* { dg-message "previous declaration" } */ +extern int *p2; /* { dg-warning "conflicting types" } */ + +enum F { F1 = -1, F2, F3 } __attribute__ ((__packed__)); + +enum F fn1(void); /* { dg-message "previous declaration" } */ +signed char fn1(void); /* { dg-warning "conflicting types" } */ + +signed char fn2(void); /* { dg-message "previous declaration" } */ +enum F fn2(void); /* { dg-warning "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c new file mode 100644 index 0000000..fcaca28 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-4.c @@ -0,0 +1,5 @@ +/* PR c/105131 */ +/* { dg-do compile } */ +/* { dg-options "-fno-short-enums" } */ + +#include "Wenum-int-mismatch-1.c" diff --git a/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c new file mode 100644 index 0000000..db24fd32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wenum-int-mismatch-5.c @@ -0,0 +1,5 @@ +/* PR c/105131 */ +/* { dg-do compile } */ +/* { dg-options "-fno-short-enums" } */ + +#include "Wenum-int-mismatch-2.c" diff --git a/gcc/testsuite/gcc.dg/Winfinite-recursion-3.c b/gcc/testsuite/gcc.dg/Winfinite-recursion-3.c new file mode 100644 index 0000000..9205422 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Winfinite-recursion-3.c @@ -0,0 +1,18 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */ +{ + return __builtin_memcmp (p, q, size); /* { dg-bogus "recursive call" } */ +} + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +} diff --git a/gcc/testsuite/gcc.dg/Winfinite-recursion-4.c b/gcc/testsuite/gcc.dg/Winfinite-recursion-4.c new file mode 100644 index 0000000..e9a2bb6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Winfinite-recursion-4.c @@ -0,0 +1,19 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); +__typeof (memcmp) __memcmp_alias __asm ("memcmp"); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-bogus "infinite recursion detected" } */ +{ + return __memcmp_alias (p, q, size); /* { dg-bogus "recursive call" } */ +} + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +} diff --git a/gcc/testsuite/gcc.dg/Winfinite-recursion-5.c b/gcc/testsuite/gcc.dg/Winfinite-recursion-5.c new file mode 100644 index 0000000..1c3d1b4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Winfinite-recursion-5.c @@ -0,0 +1,18 @@ +/* PR c/104633 */ +/* { dg-do compile } */ +/* { dg-options "-Winfinite-recursion" } */ + +typedef __SIZE_TYPE__ size_t; +int memcmp (const void *, const void *, size_t); + +extern inline __attribute__((always_inline, gnu_inline)) int +memcmp (const void *p, const void *q, size_t size) /* { dg-warning "infinite recursion detected" } */ +{ /* { dg-error "inlining failed in call to" "" { target *-*-* } .-1 } */ + return memcmp (p, q, size); /* { dg-message "recursive call" } */ +} /* { dg-message "called from here" "" { target *-*-* } .-1 } */ + +int +foo (const void *p, const void *q, size_t size) +{ + return memcmp (p, q, size); +} diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c new file mode 100644 index 0000000..fbcca44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-1.c @@ -0,0 +1,22 @@ +/* PR c/82283 */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-field-initializers" } */ + +struct A { + int *a; + int b; +}; + +struct B { + struct A a; +}; + +struct B data1 = { + .a.a = &(int){ 0 }, + .a.b = 13 /* { dg-bogus "missing initializer" } */ +}; + +struct B data2 = { + .a.b = 0, + .a.a = & (int) { 0 } +}; diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c new file mode 100644 index 0000000..cb42968 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-2.c @@ -0,0 +1,11 @@ +/* PR c/84685 */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-field-initializers" } */ + +struct T { + int a; + int *b; + int c; +}; + +struct T t = { .b = (int[]){1} }; /* { dg-bogus "missing initializer" } */ diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c new file mode 100644 index 0000000..5512d97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-3.c @@ -0,0 +1,24 @@ +/* PR c/84685 */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-field-initializers" } */ + +struct T +{ + int a; + int *b; + int c; + int d; + int *e; + int f; + int g; + int h; +}; + +struct T foo(int bar); + +struct T foo(int bar) +{ + struct T t = { .b = (int[]){ 1 }, .e = (int[]){ 2 } }; /* { dg-bogus "missing initializer" } */ + t.c = bar; + return t; +} diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c new file mode 100644 index 0000000..57e4e4d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-4.c @@ -0,0 +1,43 @@ +/* PR c/82283 */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-field-initializers" } */ + +struct a { + int b; +}; + +struct c { + struct a d; + int e; +}; + +void f (struct c *); + +void +g (void) +{ + struct c h = {.d = (struct a){0}}; /* { dg-bogus "missing initializer" } */ + f(&h); +} + +struct { + struct { + int a; + int b; + } c[1]; +} d = { + .c[0].a = 1, + .c[0].b = 1, /* { dg-bogus "missing initializer" } */ +}; + +struct test_t { + int value1; + int value2; +}; + +struct test_t test[] = { + [0].value1 = 1, + [0].value2 = 2, /* { dg-bogus "missing initializer" } */ + [1].value1 = 10, + [1].value2 = 20 /* { dg-bogus "missing initializer" } */ +}; diff --git a/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c new file mode 100644 index 0000000..7cf5df1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wmissing-field-initializers-5.c @@ -0,0 +1,22 @@ +/* PR c/82283 */ +/* { dg-do compile } */ +/* { dg-options "-Wmissing-field-initializers" } */ + +struct foo { + const char *a1; + const char * const *a2; + void *a3; + void *a4; +}; + +const char *aux[] = { "y", 0 }; + +struct foo a = { + .a1 = "x", + .a2 = (const char * const []){ "y", 0 }, +}; /* { dg-bogus "missing initializer" } */ + +struct foo b = { + .a2 = (const char * const []){ "y", 0 }, + .a1 = "x", +}; diff --git a/gcc/testsuite/gcc.dg/Wno-frame-address.c b/gcc/testsuite/gcc.dg/Wno-frame-address.c index 13c42b2..a97ec40 100644 --- a/gcc/testsuite/gcc.dg/Wno-frame-address.c +++ b/gcc/testsuite/gcc.dg/Wno-frame-address.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-skip-if "Cannot access arbitrary stack frames" { arm*-*-* amdgpu-*-* avr-*-* hppa*-*-* ia64-*-* visium-*-* csky-*-* msp430-*-* cris-*-* mmix-*-* } } */ +/* { dg-skip-if "Cannot access arbitrary stack frames" { arm*-*-* amdgpu-*-* avr-*-* hppa*-*-* ia64-*-* visium-*-* csky-*-* msp430-*-* cris-*-* mmix-*-* pru-*-* } } */ /* { dg-options "-Werror" } */ /* { dg-additional-options "-mbackchain" { target { s390*-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/Wrestrict-24.c b/gcc/testsuite/gcc.dg/Wrestrict-24.c new file mode 100644 index 0000000..d224d80 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wrestrict-24.c @@ -0,0 +1,35 @@ +/* PR tree-optimization/105604 - ICE: in tree_to_shwi with vla in struct + and sprintf + { dg-do compile } + { dg-options "-O2 -Wall -Wrestrict" } */ + +extern int sprintf (char*, const char*, ...); + +extern void* sink (void*, ...); + +struct { + long users; + long size; + char *data; +} * main_trans; + +void *main___trans_tmp_1; + +int users = 0; + +void test (void) +{ + struct { + long users; + long size; + char *data; + int links[users]; + char buf[]; + } *trans = sink (0); + + trans->data = trans->buf; + main___trans_tmp_1 = trans; + main_trans = main___trans_tmp_1; + sprintf (main_trans->data, "test"); + sink (main_trans->data); +} diff --git a/gcc/testsuite/gcc.dg/Wrestrict-25.c b/gcc/testsuite/gcc.dg/Wrestrict-25.c new file mode 100644 index 0000000..a15f56d --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wrestrict-25.c @@ -0,0 +1,165 @@ +/* PR tree-optimization/105604 - ICE: in tree_to_shwi with vla in struct + and sprintf + { dg-do compile } + { dg-options "-O2 -Wall -Wrestrict" } */ + +extern int sprintf (char*, const char*, ...); + +void* sink (void*); + + +void sprintf_S_a8_an_bn (int n, int i, int j) +{ + struct { + char a8[8], an[n], bn[n]; + } *p = sink (0); + + { + char *d = p->a8 + i; + char *s = p->a8; + sprintf (d, "%s", s); // { dg-warning "argument 3 may overlap" } + sink (p); + } + + { + char *d = p->a8; + char *s = p->a8 + j; + sprintf (d, "%s", s); // { dg-warning "argument 3 may overlap" } + sink (p); + } + + { + char *d = p->a8 + i; + char *s = p->a8 + j; + sprintf (d, "%s", s); // { dg-warning "argument 3 may overlap" } + sink (p); + } + + { + char *d = p->a8 + i; + char *s = p->an; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->a8; + char *s = p->an + j; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->a8 + i; + char *s = p->an + j; + sprintf (d, "%s", s); + sink (p); + } + + { + /* The IL makes it impossible to rule out an overlap between + p->a8 + i and p->bn + i so the "may overlap" warning triggers. */ + char *d = p->a8 + i; + char *s = p->bn; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->a8; + char *s = p->bn + j; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->a8 + i; + char *s = p->bn + j; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->an + i; + char *s = p->bn; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->an; + char *s = p->bn + j; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->an + i; + char *s = p->bn + j; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->an + i; + char *s = p->a8; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->an; + char *s = p->a8 + j; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->an + i; + char *s = p->a8 + j; + sprintf (d, "%s", s); + sink (p); + } + + { + char *d = p->bn + i; + char *s = p->a8; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->bn; + char *s = p->a8 + j; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->bn + i; + char *s = p->a8 + j; + sprintf (d, "%s", s); // { dg-bogus "-Wrestrict" "pr??????" { xfail *-*-* } } + sink (p); + } + + { + char *d = p->bn + i; + char *s = p->bn; + sprintf (d, "%s", s); // { dg-warning "may overlap" } + sink (p); + } + + { + char *d = p->bn; + char *s = p->bn + j; + sprintf (d, "%s", s); // { dg-warning "may overlap" } + sink (p); + } + + { + char *d = p->bn + i; + char *s = p->bn + j; + sprintf (d, "%s", s); // { dg-warning "may overlap" } + sink (p); + } +} diff --git a/gcc/testsuite/gcc.dg/Wrestrict-26.c b/gcc/testsuite/gcc.dg/Wrestrict-26.c new file mode 100644 index 0000000..a10c426 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wrestrict-26.c @@ -0,0 +1,114 @@ +/* Verify that sprintf calls with arrays or struct of arrays don't + cause -Wrestrict false positives. + { dg-do compile } + { dg-options "-O2 -Wall -Wrestrict -ftrack-macro-expansion=0" } */ + +#define sprintf(d, f, ...) (sprintf (d, f, __VA_ARGS__), sink (d)) + +extern void sink (void*, ...); +extern int (sprintf) (char*, const char*, ...); + +extern char ca[][2][8]; + +void test_array_of_arrays (void) +{ + sprintf (ca[0][0], "%s", ca[0][0]); // { dg-warning "-Wrestrict" } + sprintf (ca[0][0], "%s", ca[0][1]); + sprintf (ca[0][0], "%s", ca[1][0]); + sprintf (ca[0][0], "%s", ca[1][1]); + + sprintf (ca[0][1], "%s", ca[0][0]); + sprintf (ca[0][1], "%s", ca[0][1]); // { dg-warning "-Wrestrict" } + sprintf (ca[0][1], "%s", ca[1][0]); + sprintf (ca[0][1], "%s", ca[1][1]); + + sprintf (ca[1][0], "%s", ca[0][0]); + sprintf (ca[1][0], "%s", ca[0][1]); + sprintf (ca[1][0], "%s", ca[1][0]); // { dg-warning "-Wrestrict" } + sprintf (ca[1][0], "%s", ca[1][1]); + + sprintf (ca[1][1], "%s", ca[0][0]); + sprintf (ca[1][1], "%s", ca[0][1]); + sprintf (ca[1][1], "%s", ca[1][0]); + sprintf (ca[1][1], "%s", ca[1][1]); // { dg-warning "-Wrestrict" } +} + + +struct A +{ + char a[2][2][8]; + char b[2][2][8]; + char c[2][2][8]; +}; + +extern struct A aa[][2]; + +void test_array_of_structs (void) +{ + // Verify that calls with the same elements of the same array trigger + // warnings as expected. + sprintf (aa[0][0].a[0][0], "%s", aa[0][0].a[0][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][0].a[0][1], "%s", aa[0][0].a[0][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][0].a[1][0], "%s", aa[0][0].a[1][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][0].a[1][1], "%s", aa[0][0].a[1][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][1].a[0][0], "%s", aa[0][1].a[0][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][1].a[0][1], "%s", aa[0][1].a[0][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][1].a[1][0], "%s", aa[0][1].a[1][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[0][1].a[1][1], "%s", aa[0][1].a[1][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][0].a[0][0], "%s", aa[1][0].a[0][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][0].a[0][1], "%s", aa[1][0].a[0][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][0].a[1][0], "%s", aa[1][0].a[1][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][0].a[1][1], "%s", aa[1][0].a[1][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][1].a[0][0], "%s", aa[1][1].a[0][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][1].a[0][1], "%s", aa[1][1].a[0][1]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][1].a[1][0], "%s", aa[1][1].a[1][0]); // { dg-warning "-Wrestrict" } + sprintf (aa[1][1].a[1][1], "%s", aa[1][1].a[1][1]); // { dg-warning "-Wrestrict" } + +#define NOWARN() + + // Exhaustively verify that calls with different elements of the same + // array don't cause false positives. +#undef NOWARN +#define NOWARN(D, S) \ + sprintf (D[0][0], "%s", S[0][0]); \ + sprintf (D[0][0], "%s", S[0][1]); \ + sprintf (D[0][0], "%s", S[1][0]); \ + sprintf (D[0][0], "%s", S[1][1]); \ + sprintf (D[0][1], "%s", S[0][0]); \ + sprintf (D[0][1], "%s", S[0][1]); \ + sprintf (D[0][1], "%s", S[1][0]); \ + sprintf (D[0][1], "%s", S[1][1]); \ + sprintf (D[1][0], "%s", S[0][0]); \ + sprintf (D[1][0], "%s", S[0][1]); \ + sprintf (D[1][0], "%s", S[1][0]); \ + sprintf (D[1][0], "%s", S[1][1]); \ + sprintf (D[1][1], "%s", S[0][0]); \ + sprintf (D[1][1], "%s", S[0][1]); \ + sprintf (D[1][1], "%s", S[1][0]); \ + sprintf (D[1][1], "%s", S[1][1]) + + NOWARN (aa[0][0].a, aa[0][1].a); + NOWARN (aa[0][0].a, aa[1][0].a); + NOWARN (aa[0][0].a, aa[1][1].a); + + NOWARN (aa[0][1].a, aa[0][0].a); + NOWARN (aa[0][1].a, aa[1][0].a); + NOWARN (aa[0][1].a, aa[1][1].a); + + NOWARN (aa[1][0].a, aa[0][0].a); + NOWARN (aa[1][0].a, aa[0][1].a); + NOWARN (aa[1][0].a, aa[1][1].a); + +#define NOWARN_MEM(M1, M2) \ + NOWARN (aa[0][0].M1, aa[0][0].M2); \ + NOWARN (aa[0][0].M1, aa[0][1].M2); \ + NOWARN (aa[0][0].M1, aa[1][0].M2); \ + NOWARN (aa[0][0].M1, aa[1][1].M2) + + NOWARN_MEM (a, b); + NOWARN_MEM (a, c); + NOWARN_MEM (b, a); + NOWARN_MEM (b, c); + NOWARN_MEM (c, a); + NOWARN_MEM (c, b); +} diff --git a/gcc/testsuite/gcc.dg/Wuse-after-free-2.c b/gcc/testsuite/gcc.dg/Wuse-after-free-2.c index 9f7ed45..68ec758 100644 --- a/gcc/testsuite/gcc.dg/Wuse-after-free-2.c +++ b/gcc/testsuite/gcc.dg/Wuse-after-free-2.c @@ -1,6 +1,6 @@ /* PR middle-end/104232 - spurious -Wuse-after-free after conditional free { dg-do compile } - { dg-options "-O2 -Wall" } */ + { dg-options "-O2 -Wall -fno-tree-loop-distribute-patterns" } */ void free (void*); @@ -107,6 +107,8 @@ int warn_cond_loop (char *p) { char *q = p; + /* -fno-tree-loop-distribute-patterns ensures this does not get converted + into rawmemchr (making q and p unrelated). */ while (*q) ++q; diff --git a/gcc/testsuite/gcc.dg/alias-10.c b/gcc/testsuite/gcc.dg/alias-10.c index 95d8b19..8472d30 100644 --- a/gcc/testsuite/gcc.dg/alias-10.c +++ b/gcc/testsuite/gcc.dg/alias-10.c @@ -28,4 +28,4 @@ void foo (bitmap head, bitmap_element *elt) } -/* { dg-final { scan-tree-dump-times "Unswitching" 1 "unswitch"} } */ +/* { dg-final { scan-tree-dump-times "unswitching" 1 "unswitch"} } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c new file mode 100644 index 0000000..b5bed53 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-1.c @@ -0,0 +1,117 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +/* Tests with constant buffer sizes. */ + +void test_1 (void) +{ + int16_t *ptr = malloc (21 * sizeof (int16_t)); + free (ptr); +} + +void test_2 (void) +{ + int32_t *ptr = malloc (21 * sizeof (int16_t)); /* { dg-line malloc2 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ + /* { dg-message "42 bytes" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ +} + +void test_3 (void) +{ + void *ptr = malloc (21 * sizeof (int16_t)); + int16_t *sptr = (int16_t *)ptr; + free (sptr); +} + +void test_4 (void) +{ + void *ptr = malloc (21 * sizeof (int16_t)); /* { dg-message "42 bytes" } */ + int32_t *iptr = (int32_t *)ptr; /* { dg-line assign4 } */ + free (iptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign4 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign4 } */ +} + +void test_5 (void) +{ + int32_t user_input; + scanf("%i", &user_input); + int32_t n; + if (user_input == 0) + n = 21 * sizeof (int16_t); + else + n = 42 * sizeof (int16_t); + void *ptr = malloc (n); + int16_t *sptr = (int16_t *)ptr; + free (sptr); +} + +void test_6 (void) +{ + int32_t user_input; + scanf("%i", &user_input); + int32_t n; + if (user_input == 0) + n = 21 * sizeof (int16_t); + else + n = 42 * sizeof (int16_t); + void *ptr = malloc (n); /* { dg-message "" "note" } */ + /* ^^^ on widening_svalues no expr is returned + by get_representative_tree at the moment. */ + int32_t *iptr = (int32_t *)ptr; /* { dg-line assign6 } */ + free (iptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign6 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign6 } */ +} + +void test_7 (void) +{ + int32_t user_input; + scanf("%i", &user_input); + int32_t n; + if (user_input == 0) + n = 1; + else if (user_input == 2) + n = 5; + else + n = 7; + /* n is an unknown_svalue at this point. */ + void *ptr = malloc (n); + int32_t *iptr = (int32_t *)ptr; + free (iptr); +} + +void *create_buffer (int32_t n) +{ + return malloc(n); +} + +void test_8 (void) +{ + int32_t *buf = create_buffer(4 * sizeof (int)); + free (buf); +} + +void test_9 (void) +{ + /* FIXME: At the moment, region_model::set_value (lhs, <return_value>) + is called at the src_node of the return edge. This edge has no stmts + associated with it, leading to a rejection of the warning inside + impl_region_model_context::warn. To ensure that the indentation + in the diagnostic is right, the warning has to be emitted on an EN + that is after the return edge. */ + int32_t *buf = create_buffer(42); /* { dg-warning "" "" { xfail *-*-* } } */ + free (buf); +} + +void test_10 (int32_t n) +{ + char *ptr = malloc (7 * n); + free (ptr); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c new file mode 100644 index 0000000..42c39e2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-2.c @@ -0,0 +1,156 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +/* Tests with symbolic buffer sizes. */ + +void test_1 (int32_t n) +{ + int16_t *ptr = malloc (n * sizeof (int16_t)); + free (ptr); +} + +void test_2 (int32_t n) +{ + int32_t *ptr = malloc (n * sizeof (int16_t)); /* { dg-line malloc2 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ + /* { dg-message "'\[a-z0-9\\*\\(\\)\\s\]*' bytes" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4" "note" { target *-*-* } malloc2 } */ +} + +void test_3 (int32_t n) +{ + void *ptr = malloc (n * sizeof (int16_t)); + int16_t *sptr = (int16_t *)ptr; + free (sptr); +} + +void test_4 (int32_t n) +{ + void *ptr = malloc (n * sizeof (int16_t)); /* { dg-message "'\[a-z0-9\\*\\(\\)\\s\]*'" "note" } */ + int32_t *iptr = (int32_t *)ptr; /* { dg-line assign4 } */ + free (iptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign4 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign4 } */ +} + +void test_5 (void) +{ + int32_t user_input; + scanf("%i", &user_input); + int32_t n; + if (user_input == 0) + n = 3 * user_input * sizeof (int16_t); + else + n = 5 * user_input * sizeof (int16_t); + void *ptr = malloc (n); + int16_t *sptr = (int16_t *)ptr; + free (sptr); +} + +void test_6 (void) +{ + int32_t user_input; + scanf("%i", &user_input); + int32_t n; + if (user_input == 0) + n = user_input; + else if (user_input == 2) + n = user_input * 3; + else + n = user_input * 5; + /* n is an unknown_svalue at this point. */ + void *ptr = malloc (n); + int32_t *iptr = (int32_t *)ptr; + free (iptr); +} + +void *create_buffer(int32_t n) +{ + return malloc(n); +} + +void test_7(int32_t n) +{ + int32_t *buf = create_buffer(n * sizeof (int32_t)); + free (buf); +} + +void test_8(int32_t n) +{ + /* FIXME: At the moment, region_model::set_value (lhs, <return_value>) + is called at the src_node of the return edge. This edge has no stmts + associated with it, leading to a rejection of the warning inside + impl_region_model_context::warn. To ensure that the indentation + in the diagnostic is right, the warning has to be emitted on an EN + that is after the return edge. */ + int32_t *buf = create_buffer(n * sizeof(int16_t)); /* { dg-warning "" "" { xfail *-*-* } } */ + free (buf); +} + +void test_9 (void) +{ + int32_t n; + scanf("%i", &n); + /* n is a conjured_svalue. */ + void *ptr = malloc (n); /* { dg-message "'n' bytes" "note" } */ + int32_t *iptr = (int32_t *)ptr; /* { dg-line assign9 } */ + free (iptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign9 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign9 } */ +} + +void test_11 (void) +{ + int32_t n; + scanf("%i", &n); + void *ptr = malloc (n); + if (n == sizeof (int32_t)) + { + /* n is a conjured_svalue but guarded such that we + know the value is a multiple of sizeof (*iptr). */ + int32_t *iptr = (int32_t *)ptr; + free (iptr); + } + else + free (ptr); +} + +void test_12 (void) +{ + int32_t n; + scanf("%i", &n); + void *ptr = malloc (n); /* { dg-message "'n' bytes" } */ + if (n == 5) + { + /* n is a conjured_svalue but guarded such that we + know the value isn't a multiple of sizeof (*iptr). */ + int32_t *iptr = (int32_t *)ptr; /* { dg-line assign12 } */ + free (iptr); + } + else + free (ptr); + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign12 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign12 } */ +} + +void test_13 (void) +{ + int32_t n; + scanf("%i", &n); + void *ptr = malloc (n); + if (n == n * n) + { + /* n is a conjured_svalue but guarded such that we don't have an + equivalence class for it. In such cases, we assume that the + condition ensures that the value is okay. */ + int32_t *iptr = (int32_t *)ptr; + free (iptr); + } + else + free (ptr); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c new file mode 100644 index 0000000..0c86f09 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-3.c @@ -0,0 +1,46 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +/* CWE-131 example 5 */ +void test_1 (void) +{ + int32_t *id_sequence = (int32_t *) malloc (3); /* { dg-line malloc1 } */ + if (id_sequence == NULL) exit (1); + + id_sequence[0] = 13579; + id_sequence[1] = 24680; + id_sequence[2] = 97531; + + free (id_sequence); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc1 } */ + /* { dg-message "3 bytes" "note" { target *-*-* } malloc1 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc1 } */ +} + +void test_2 (void) +{ + int32_t *ptr = malloc (10 + sizeof(int32_t)); /* { dg-line malloc2 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ + /* { dg-message "14 bytes" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ +} + +void test_3 (int32_t n) +{ + int32_t *ptr = malloc (n + sizeof (int32_t)); /* { dg-line malloc3 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc3 } */ + /* { dg-message "'\[a-z0-9\\+\\(\\)\\s\]*' bytes" "note" { target *-*-* } malloc3 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc3 } */ +} + +void test_4 (int32_t n, int32_t m) +{ + int32_t *ptr = malloc ((n + m) * sizeof (int32_t)); + free (ptr); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c new file mode 100644 index 0000000..235c156 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-4.c @@ -0,0 +1,61 @@ +#include <stdlib.h> +#include <stdint.h> + +/* Tests related to structs. */ + +struct base { + int16_t i; +}; + +struct sub { + struct base b; + int16_t j; +}; + +struct var_len { + int16_t i; + char arr[]; +}; + + +void test_1 (void) +{ + struct base *ptr = malloc (5 * sizeof (struct base)); + free (ptr); +} + +void test_2 (void) +{ + int32_t *ptr = malloc (5 * sizeof (struct base)); /* { dg-line malloc2 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc2 } */ + /* { dg-message "\\d+ bytes" "note" { target *-*-* } malloc2 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } malloc2 } */ +} + +void test_3 (void) +{ + /* Even though 10 bytes is not a multiple of 4, we do not warn to prevent + a false positive in case s is the base struct of a struct inheritance. */ + struct base *ptr = malloc (10); + free (ptr); +} + +void test_4 (void) +{ + struct var_len *ptr = malloc (10); + free (ptr); +} + +void test_5 (void) +{ + /* For constant sizes, we warn if the buffer + is too small to hold a single struct. */ + struct base *ptr = malloc (1); /* { dg-line malloc5 } */ + free (ptr); + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } malloc5 } */ + /* { dg-message "1 bytes" "note" { target *-*-* } malloc5 } */ + /* { dg-message "'struct base \\*' here; 'sizeof \\(struct base\\)' is '\\d+'" "note" { target *-*-* } malloc5 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-5.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-5.c new file mode 100644 index 0000000..a15e18d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/allocation-size-5.c @@ -0,0 +1,37 @@ +#include <stdlib.h> +#include <stdio.h> +#include <stdint.h> + +/* Tests related to statically allocated buffers. */ + +typedef struct a { + int16_t s; +} a; + +int32_t *test_1 (void) +{ + a A; /* { dg-message "\\d+ bytes" "note" } */ + A.s = 1; + int32_t *ptr = (int32_t *) &A; /* { dg-line assign1 } */ + return ptr; + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign1 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign1 } */ +} + +int32_t *test2 (void) +{ + char arr[sizeof (int32_t)]; + int32_t *ptr = (int32_t *)arr; + return ptr; +} + +int32_t *test3 (void) +{ + char arr[sizeof (int16_t)]; /* { dg-message "\\d+ bytes" "note" } */ + int32_t *ptr = (int32_t *)arr; /* { dg-line assign3 } */ + return ptr; + + /* { dg-warning "allocated buffer size is not a multiple of the pointee's size \\\[CWE-131\\\]" "warning" { target *-*-* } assign3 } */ + /* { dg-message "'int32_t \\*' (\\\{aka '(long )?int \\*'\\\})? here; 'sizeof \\(int32_t (\\\{aka (long )?int\\\})?\\)' is '4'" "note" { target *-*-* } assign3 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-1.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-1.c new file mode 100644 index 0000000..cce3f6b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-1.c @@ -0,0 +1,126 @@ +/* Test reduced from use of dynamic_pr_debug on Linux kernel, to verify that + we treat the static struct _ddebug as not needing to be tracked by the + analyzer, thus optimizing away bloat in the analyzer's state tracking. */ + +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +/* Adapted from various files in the Linux kernel, all of which have: */ +/* SPDX-License-Identifier: GPL-2.0 */ + +typedef _Bool bool; +#define true 1 +#define false 0 + +typedef struct { + int counter; +} atomic_t; + +/* Adapted from include/linux/compiler_attributes.h */ +#define __always_inline inline __attribute__((__always_inline__)) + +/* Adapted from include/linux/compiler-gcc.h */ +#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) + +/* Adapted from include/linux/jump_label.h, which has: */ + +struct static_key { + atomic_t enabled; + union { + /* [...snip...] */ + struct jump_entry *entries; + /* [...snip...] */ + }; +}; + +struct static_key_true { + struct static_key key; +}; + +struct static_key_false { + struct static_key key; +}; + +extern bool ____wrong_branch_error(void); + +/* Adapted from arch/x86/include/asm/jump_label.h */ + +#define JUMP_TABLE_ENTRY \ + ".pushsection __jump_table, \"aw\" \n\t" \ + /*_ASM_ALIGN*/ "\n\t" \ + ".long 1b - . \n\t" \ + ".long %l[l_yes] - . \n\t" \ + /*_ASM_PTR*/ "%c0 + %c1 - .\n\t" \ + ".popsection \n\t" + +static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + /*".byte " __stringify(BYTES_NOP5) "\n\t" */ + JUMP_TABLE_ENTRY + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + "jmp %l[l_yes]\n\t" + JUMP_TABLE_ENTRY + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +/* Adapted from include/linux/dynamic_debug.h */ + +struct _ddebug { + /* [...snip...] */ + const char *function; + const char *filename; + const char *format; + unsigned int lineno:18; + /* [...snip...] */ + unsigned int flags:8; + union { + struct static_key_true dd_key_true; + struct static_key_false dd_key_false; + } key; +} __attribute__((aligned(8))); + +extern void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); + +static void expanded_dynamic_pr_debug(void) { + do { + static struct _ddebug __attribute__((__aligned__(8))) + __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = { /* { dg-warning "track '__UNIQUE_ID_ddebug277': no" } */ + .function = __func__, + .filename = __FILE__, + .format = ("hello world"), + .lineno = __LINE__, + .flags = 0}; + if (({ + bool branch; + if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug277.key.dd_key_false), + struct static_key_true)) + branch = arch_static_branch_jump( + &(&__UNIQUE_ID_ddebug277.key.dd_key_false)->key, false); + else if (__builtin_types_compatible_p( + typeof(*&__UNIQUE_ID_ddebug277.key.dd_key_false), + struct static_key_false)) + branch = arch_static_branch( + &(&__UNIQUE_ID_ddebug277.key.dd_key_false)->key, false); + else + branch = ____wrong_branch_error(); + __builtin_expect(!!(branch), 0); + })) + __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, + "hello world"); + } while (0); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c new file mode 100644 index 0000000..8111709 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c @@ -0,0 +1,77 @@ +/* Test reduced from use of dynamic_pr_debug on Linux kernel, to verify that + we treat the static struct _ddebug as not needing to be tracked by the + analyzer, thus optimizing away bloat in the analyzer's state tracking. */ + +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +/* Adapted from various files in the Linux kernel, all of which have: */ +/* SPDX-License-Identifier: GPL-2.0 */ + +typedef _Bool bool; +#define true 1 +#define false 0 + +typedef struct {} atomic_t; + +/* Adapted from include/linux/compiler_attributes.h */ +#define __always_inline inline __attribute__((__always_inline__)) + +/* Adapted from include/linux/compiler-gcc.h */ +#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) + +/* Adapted from include/linux/jump_label.h, which has: */ + +struct static_key {}; + +/* Adapted from arch/x86/include/asm/jump_label.h */ + +static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +/* Adapted from include/linux/dynamic_debug.h */ + +struct _ddebug { + /* [...snip...] */ + const char *function; + const char *filename; + const char *format; + unsigned int lineno:18; + /* [...snip...] */ + unsigned int flags:8; + struct static_key key; +} __attribute__((aligned(8))); + +extern void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); + +static void expanded_dynamic_pr_debug(void) { + do { + static struct _ddebug __attribute__((__aligned__(8))) + __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = { /* { dg-warning "track '__UNIQUE_ID_ddebug277': no" } */ + .function = __func__, + .filename = __FILE__, + .format = ("hello world"), + .lineno = __LINE__, + .flags = 0}; + if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false)) + __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, + "hello world"); + } while (0); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-const-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-const-1.c new file mode 100644 index 0000000..39e813f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/attr-const-1.c @@ -0,0 +1,152 @@ +/* Verify that we handle functions with __attribute__ ((const)) correctly. */ + +#include "analyzer-decls.h" + +extern int nonconst_fn (int); + +extern int const_fn_0 () __attribute__ ((const)); +extern int const_fn_1 (int) __attribute__ ((const)); +extern int const_fn_2 (int, int) __attribute__ ((const)); +extern int const_fn_3 (int, int, int) __attribute__ ((const)); +extern int const_fn_variadic (int, ...) __attribute__ ((const)); + +/* Verify that functions without __attribute__ ((const)) have a different + result each time. */ + +void test_nonconst_fn (int x, int y) +{ + int x_1 = nonconst_fn (x); + int x_2 = nonconst_fn (x); + int y_1 = nonconst_fn (y); + int y_2 = nonconst_fn (y); + __analyzer_eval (x_1 == x_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (y_1 == y_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */ +} + +/* Verify functions with __attribute__ ((const)) have the same result + for the same arguments. */ + + /* 0 args. */ + +extern int other_const_fn_0 () __attribute__ ((const)); + +void test_const_fn_0 (void) +{ + int a = const_fn_0 (); + int b = const_fn_0 (); + int c = other_const_fn_0 (); + int d = other_const_fn_0 (); + __analyzer_eval (a == b); /* { dg-warning "TRUE" } */ + __analyzer_eval (c == d); /* { dg-warning "TRUE" } */ + __analyzer_eval (a == c); /* { dg-warning "UNKNOWN" } */ +} + +/* 1 arg. */ + +void test_const_fn_1 (int x, int y) +{ + int x_1 = const_fn_1 (x); + int x_2 = const_fn_1 (x); + int y_1 = const_fn_1 (y); + int y_2 = const_fn_1 (y); + __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */ +} + +/* 2 args. */ + +void test_const_fn_2 (int x, int y, int p, int q) +{ + int xy_1 = const_fn_2 (x, y); + int xy_2 = const_fn_2 (x, y); + int pq_1 = const_fn_2 (p, q); + int pq_2 = const_fn_2 (p, q); + __analyzer_eval (xy_1 == xy_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (pq_1 == pq_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (xy_1 == pq_1); /* { dg-warning "UNKNOWN" } */ +} + +/* We don't handle above 2 args. */ + +void test_const_fn_3 (int x, int y, int z, int p, int q, int r) +{ + int xyz_1 = const_fn_3 (x, y, z); + int xyz_2 = const_fn_3 (x, y, z); + int pqr_1 = const_fn_3 (p, q, r); + int pqr_2 = const_fn_3 (p, q, r); + __analyzer_eval (xyz_1 == xyz_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (pqr_1 == pqr_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (xyz_1 == pqr_1); /* { dg-warning "UNKNOWN" } */ +} + +/* Variadic fn, with various numbers of extra args. */ + +void test_const_fn_variadic (int x, int y, int z, int p, int q, int r) +{ + /* 0 extra args, for 1 arg in total. */ + int x_1 = const_fn_variadic (x); + int x_2 = const_fn_variadic (x); + int p_1 = const_fn_variadic (p); + int p_2 = const_fn_variadic (p); + __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (p_1 == p_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (x_1 == p_1); /* { dg-warning "UNKNOWN" } */ + + /* 1 extra arg, for 2 args in total. */ + int xy_1 = const_fn_variadic (x, y); + int xy_2 = const_fn_variadic (x, y); + int pq_1 = const_fn_variadic (p, q); + int pq_2 = const_fn_variadic (p, q); + __analyzer_eval (xy_1 == xy_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (pq_1 == pq_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (xy_1 == pq_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (x_1 == xy_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (p_1 == pq_1); /* { dg-warning "UNKNOWN" } */ + + /* Above that, we don't track results. */ + int xyz_1 = const_fn_variadic (x, y, z); + int xyz_2 = const_fn_variadic (x, y, z); + int pqr_1 = const_fn_variadic (p, q, r); + int pqr_2 = const_fn_variadic (p, q, r); + __analyzer_eval (xyz_1 == xyz_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (pqr_1 == pqr_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (xyz_1 == x_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (xyz_1 == xy_1); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (xyz_1 == pqr_1); /* { dg-warning "UNKNOWN" } */ +} + +/* Builtins with __attribute__ ((const)). */ + +void test_builtin_isascii (int x, int y) +{ + int x_1 = __builtin_isascii (x); + int x_2 = __builtin_isascii (x); + int y_1 = __builtin_isascii (y); + int y_2 = __builtin_isascii (y); + __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */ +} + +void test_builtin_popcount (unsigned x, unsigned y) +{ + unsigned x_1 = __builtin_popcount (x); + unsigned x_2 = __builtin_popcount (x); + unsigned y_1 = __builtin_popcount (y); + unsigned y_2 = __builtin_popcount (y); + __analyzer_eval (x_1 == x_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (y_1 == y_2); /* { dg-warning "TRUE" } */ + __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */ +} + +void test_loop (void) +{ + for (int i = 0; i < 100; i++) + { + int iter_val_a = const_fn_1 (i); + int iter_val_b = const_fn_1 (i); + __analyzer_eval (iter_val_a == iter_val_b); /* { dg-warning "TRUE" } */ + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-const-2.c b/gcc/testsuite/gcc.dg/analyzer/attr-const-2.c new file mode 100644 index 0000000..ab79514 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/attr-const-2.c @@ -0,0 +1,16 @@ +extern int const_p (int) __attribute__((const)); +extern void do_stuff (void); + +void test (int a) +{ + void *p; + if (const_p (a)) + { + p = __builtin_malloc (1024); + if (!p) + return; + } + do_stuff (); + if (const_p (a)) + __builtin_free (p); /* { dg-bogus "uninit" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c new file mode 100644 index 0000000..2e6ccda --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/attr-const-3.c @@ -0,0 +1,26 @@ +/* Verify that we handle unknown values passed to __attribute__ ((const)) + (by imposing a complexity limit). */ + +/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */ + +#include "analyzer-decls.h" + +extern int const_fn_1 (int) __attribute__ ((const)); + +void test_const_fn_1 (int x, int y) +{ + int x_1 = const_fn_1 (x); + int x_2 = const_fn_1 (x); + int y_1 = const_fn_1 (y); + int y_2 = const_fn_1 (y); + __analyzer_eval (x_1 == x_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (y_1 == y_2); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (x_1 == y_1); /* { dg-warning "UNKNOWN" } */ +} + +void test_2 (int x) +{ + int once = const_fn_1 (x); + int again = const_fn_1 (once); + __analyzer_eval (once == again); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/boxed-malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/boxed-malloc-1.c new file mode 100644 index 0000000..435fb4f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/boxed-malloc-1.c @@ -0,0 +1,485 @@ +/* Adapted from malloc-1.c, but wrapping the pointers in a struct. */ + +/* { dg-require-effective-target alloca } */ + +#include <stdlib.h> + +extern int foo (void); +extern int bar (void); +extern void could_free (void *); +extern void cant_free (const void *); /* since it's a const void *. */ + +typedef struct boxed_ptr { void *value; } boxed_ptr; + +boxed_ptr +boxed_malloc (size_t sz) +{ + boxed_ptr result; + result.value = malloc (sz); + return result; +} + +boxed_ptr +boxed_free (boxed_ptr ptr) +{ + free (ptr.value); +} + +const boxed_ptr boxed_null = {NULL}; + +void test_1 (void) +{ + boxed_ptr ptr; + ptr.value = malloc (1024); + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +void test_2 (boxed_ptr ptr) +{ + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +boxed_ptr +test_3 (void) +{ + boxed_ptr ptr; + ptr.value = malloc (sizeof (int)); + *(int *)ptr.value = 42; /* { dg-warning "dereference of possibly-NULL 'ptr.value' \\\[CWE-690\\\]" } */ + return ptr; +} + +boxed_ptr +test_4 (void) +{ + boxed_ptr ptr; + ptr.value = malloc (sizeof (int)); + int *iptr = (int *)ptr.value; + if (iptr) + *iptr = 42; + else + *iptr = 43; /* { dg-warning "dereference of NULL 'iptr' \\\[CWE-476\\\]" } */ + return ptr; +} + +int test_5 (boxed_ptr ptr) +{ + free (ptr.value); + return *(int *)ptr.value; /* { dg-warning "use after 'free' of 'ptr.value'" } */ +} + +void test_6 (void *ptr) +{ + boxed_ptr q; + q.value = ptr; + free (ptr); + free (q.value); /* { dg-warning "double-'free' of 'ptr'" } */ +} + +void test_6a (boxed_ptr ptr) +{ + boxed_ptr q; + q = ptr; + boxed_free (ptr); + free (q.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +void test_7 (void) +{ + boxed_ptr ptr = boxed_malloc(4096); + if (!ptr.value) + return; + __builtin_memset(ptr.value, 0, 4096); + boxed_free(ptr); +} + +boxed_ptr test_8 (void) +{ + boxed_ptr ptr = boxed_malloc(4096); + if (!ptr.value) + return boxed_null; + __builtin_memset(ptr.value, 0, 4096); + return ptr; +} + +void test_9 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + + int i; + for (i = 0; i < 1024; i++) + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +void test_10 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + + int i; + for (i = 0; i < 1024; i++) + foo (); + + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +void test_11 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + + while (foo ()) + bar (); + + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +void test_12 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + + while (1) + { + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ + } +} + +void test_13 (void) +{ + boxed_ptr p = boxed_malloc (1024); + boxed_ptr q = boxed_malloc (1024); + + foo (); + if (!q.value) + { + boxed_free (q); + return; /* { dg-warning "leak of 'p.value'" } */ + } + bar (); + boxed_free (q); + boxed_free (p); +} + +void test_14 (void) +{ + boxed_ptr p, q; + p = boxed_malloc (1024); + if (!p.value) + return; + + q = boxed_malloc (1024); + if (!q.value) + { + boxed_free (p); + boxed_free (q); + /* oops: missing "return". */ + } + bar (); + boxed_free (q); /* Although this looks like a double-'free' of q, + it's known to be NULL for the case where free is + called twice on it. */ + free (p.value); /* { dg-warning "double-'free' of 'p.value'" } */ +} + +void test_15 (void) +{ + boxed_ptr p, q; + p.value = NULL; + q.value = NULL; + + p = boxed_malloc (1024); + if (!p.value) + goto fail; + + foo (); + + q = boxed_malloc (1024); + if (!q.value) + goto fail; + + bar (); + + fail: + boxed_free (q); + boxed_free (p); +} + +void test_16 (void) +{ + boxed_ptr p, q; /* { dg-message "region created on stack here" } */ + + p = boxed_malloc (1024); + if (!p.value) + goto fail; + + foo (); + + q = boxed_malloc (1024); + if (!q.value) + goto fail; + + bar (); + + fail: + boxed_free (q); /* { dg-warning "use of uninitialized value 'q'" } */ + boxed_free (p); +} + +void test_17 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); +} /* { dg-warning "leak of 'ptr.value'" } */ + +void test_18 (void) +{ + boxed_ptr ptr = boxed_malloc (64); + ptr = boxed_null; /* { dg-warning "leak of 'ptr.value'" } */ +} + +void test_18a (void) +{ + boxed_ptr ptr = boxed_malloc (64); + ptr.value = NULL; /* { dg-warning "leak of 'ptr.value'" } */ +} + +void test_19 (void) +{ + boxed_ptr ptr = boxed_malloc (64); + free (ptr.value); + ptr.value = NULL; + free (ptr.value); +} + +boxed_ptr global_ptr_20; + +void test_20 (void) +{ + global_ptr_20 = boxed_malloc (1024); +} + +int *test_21 (int i) +{ + boxed_ptr ptr = boxed_malloc (sizeof (int)); + if (!ptr.value) + abort (); + *(int *)ptr.value = i; + return ptr.value; +} + +boxed_ptr test_21a (int i) +{ + boxed_ptr ptr = boxed_malloc (sizeof (int)); + if (!ptr.value) + abort (); + *(int *)ptr.value = i; + return ptr; +} + +void test_22 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + + int i; + for (i = 5; i < 10; i++) + foo (); + + free (ptr.value); + free (ptr.value); /* { dg-warning "double-'free' of 'ptr.value'" } */ +} + +int test_24 (void) +{ + boxed_ptr ptr; + ptr.value = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */ + free (ptr.value); /* { dg-warning "'free' of 'ptr.value' which points to memory on the stack \\\[CWE-590\\\]" } */ +} + +int test_25 (void) +{ + char tmp[100]; /* { dg-message "region created on stack here" } */ + boxed_ptr p; + p.value = tmp; + free (p.value); /* { dg-warning "'free' of '&tmp' which points to memory on the stack \\\[CWE-590\\\]" } */ +} + +char global_buffer[100]; /* { dg-message "region created here" } */ + +int test_26 (void) +{ + boxed_ptr p; + p.value = global_buffer; + free (p.value); /* { dg-warning "'free' of '&global_buffer' which points to memory not on the heap \\\[CWE-590\\\]" } */ +} + +struct coord { + float x; + float y; +}; + +boxed_ptr test_27 (void) +{ + boxed_ptr p = boxed_malloc (sizeof (struct coord)); + ((struct coord *)p.value)->x = 0.f; /* { dg-warning "dereference of possibly-NULL 'p.value' \\\[CWE-690\\\]" } */ + + /* Only the first such usage should be reported: */ + ((struct coord *)p.value)->y = 0.f; + + return p; +} + +struct link +{ + boxed_ptr m_ptr; +}; + +boxed_ptr test_29 (void) +{ + boxed_ptr res = boxed_malloc (sizeof (struct link)); + if (!res.value) + return boxed_null; + ((struct link *)res.value)->m_ptr = boxed_malloc (sizeof (struct link)); + return res; +} + +void test_31 (void) +{ + struct link tmp; + boxed_ptr ptr = boxed_malloc (sizeof (struct link)); + tmp.m_ptr = ptr; +} /* { dg-warning "leak" } */ + +void test_32 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + could_free (ptr.value); +} /* { dg-bogus "leak" } */ + +void test_33 (void) +{ + boxed_ptr ptr = boxed_malloc (1024); + cant_free (ptr.value); +} /* { dg-warning "leak of 'ptr.value'" } */ + +void test_34 (void) +{ + float *q; + boxed_ptr p = boxed_malloc (sizeof (struct coord)); + if (!p.value) + return; + ((struct coord *)p.value)->x = 0.0f; + q = &((struct coord *)p.value)->x; + boxed_free (p); + *q = 1.0f; /* { dg-warning "use after 'free' of 'q'" } */ +}; + +int test_35 (void) +{ + boxed_ptr ptr = boxed_malloc(4096); + if (!ptr.value) + return -1; + __builtin_memset(ptr.value, 0, 4096); + boxed_free(ptr); + return 0; +} + +void test_36 (void) +{ + boxed_ptr ptr = boxed_malloc(4096); + if (!ptr.value) + return; + __builtin_memset(ptr.value, 0, 4096); + boxed_free(ptr); +} + +boxed_ptr test_37a (void) +{ + boxed_ptr ptr = boxed_malloc(4096); + __builtin_memset(ptr.value, 0, 4096); /* { dg-warning "use of possibly-NULL 'ptr.value' where non-null expected \\\[CWE-690\\\]" } */ + return ptr; +} + +int test_37b (void) +{ + boxed_ptr p = boxed_malloc(4096); + boxed_ptr q = boxed_malloc(4096); + if (p.value) { + __builtin_memset(p.value, 0, 4096); /* Not a bug: checked */ + } else { + __builtin_memset(q.value, 0, 4096); /* { dg-warning "use of possibly-NULL 'q.value' where non-null expected \\\[CWE-690\\\]" } */ + } + boxed_free(p); + boxed_free(q); + return 0; +} + +extern void might_use_ptr (void *ptr); + +void test_38(int i) +{ + boxed_ptr p; + + p = boxed_malloc(1024); + if (p.value) { + boxed_free(p); + might_use_ptr(p.value); /* { dg-warning "use after 'free' of 'p.value'" "" { xfail *-*-* } } */ + // TODO: xfail + } +} + +boxed_ptr +test_39 (int i) +{ + boxed_ptr p = boxed_malloc(sizeof(int*)); + *(int *)p.value = i; /* { dg-warning "dereference of possibly-NULL 'p.value' \\\[CWE-690\\\]" } */ + return p; +} + +boxed_ptr +test_41 (int flag) +{ + boxed_ptr buffer; + + if (flag) { + buffer = boxed_malloc(4096); + } else { + buffer = boxed_null; + } + + ((char *)buffer.value)[0] = 'a'; /* { dg-warning "dereference of possibly-NULL 'buffer.value' \\\[CWE-690\\\]" "possibly-NULL" } */ + /* { dg-warning "dereference of NULL" "NULL" { target *-*-* } .-1 } */ + + return buffer; +} + +extern void might_take_ownership (boxed_ptr ptr); + +void test_45 (void) +{ + boxed_ptr p = boxed_malloc (1024); + might_take_ownership (p); +} + +/* Free of function, and of label within function. */ + +void test_50a (void) +{ +} + +void test_50b (void) +{ + boxed_ptr ptr; + ptr.value = test_50a; + free (ptr.value); /* { dg-warning "'free' of '&test_50a' which points to memory not on the heap \\\[CWE-590\\\]" } */ +} + +void test_50c (void) +{ + my_label: + boxed_ptr ptr; + ptr.value = &&my_label; + free (ptr.value); /* { dg-warning "'free' of '&my_label' which points to memory not on the heap \\\[CWE-590\\\]" } */ +} + +/* { dg-prune-output "\\\[-Wfree-nonheap-object" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-1.c b/gcc/testsuite/gcc.dg/analyzer/fd-1.c new file mode 100644 index 0000000..8a72e63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-1.c @@ -0,0 +1,39 @@ +int open(const char *, int mode); +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +void +test_1 (const char *path) +{ + int fd = open (path, O_RDONLY); /* { dg-message "\\(1\\) opened here" } */ + return; /* { dg-warning "leak of file descriptor 'fd' \\\[CWE-775\\\]" "warning" } */ + /* { dg-message "\\(2\\) 'fd' leaks here; was opened at \\(1\\)" "event" { target *-*-* } .-1 } */ +} + +void +test_2 (const char *path) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + if (fd >= 0) /* { dg-message "\\(2\\) assuming 'fd' is a valid file descriptor" "event1" } */ + /* { dg-message "\\(3\\) following 'true' branch \\(when 'fd >= 0'\\)..." "event2" { target *-*-* } .-1 } */ + { + return; /* { dg-warning "leak of file descriptor 'fd' \\\[CWE-775\\\]" "warning" } */ + /* { dg-message "\\(4\\) ...to here" "event1" { target *-*-* } .-1 } */ + /* { dg-message "\\(5\\) 'fd' leaks here; was opened at \\(1\\)" "event2" { target *-*-* } .-2 } */ + } +} + +void +test_3 (const char *path) +{ + int fd = open (path, O_WRONLY); /* { dg-message "\\(1\\) opened here" } */ + return; /* { dg-warning "leak of file descriptor 'fd' \\\[CWE-775\\\]" "warning" } */ +} + +void test_4 (const char *path) +{ + open(path, O_RDONLY); /* { dg-warning "leak of file descriptor \\\[CWE-775\\\]" } */ + /* { dg-message "\\(1\\) leaks here" "" { target *-*-* } .-1 } */ +} + diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-2.c b/gcc/testsuite/gcc.dg/analyzer/fd-2.c new file mode 100644 index 0000000..d794b46 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-2.c @@ -0,0 +1,49 @@ +int open(const char *, int mode); +void close(int fd); +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define STDIN 0 + +void +test_1 (const char *path) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + close (fd); /* { dg-message "\\(2\\) first 'close' here" "event1" } */ + close (fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" "warning" } */ + /* { dg-message "\\(3\\) second 'close' here; first 'close' was at \\(2\\)" "event2" { target *-*-* } .-1 } */ +} + +void +test_2 (const char *path) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + if (fd < 0) /* { dg-message "\\(2\\) assuming 'fd' is a valid file descriptor \\(>= 0\\)" "event1" } */ + /* { dg-message "\\(3\\) following 'false' branch \\(when 'fd >= 0'\\)..." "event2" { target *-*-* } .-1 } */ + return; + close (fd); /* { dg-message "\\(4\\) ...to here" "event1" } */ + /* { dg-message "\\(5\\) first 'close' here" "event2" { target *-*-* } .-1 } */ + close (fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" "warning" } */ + /* {dg-message "\\(6\\) second 'close' here; first was at \\(5\\)" "" { target *-*-* } .-1 } */ +} + +void +test_3 () +{ + /* FD 0 is stdin at the entry to "main" and thus read-only, but we have no + guarantees here that it hasn't been closed and then reopened for + writing, so we can't issue a warning */ + + int fd = STDIN; + close(fd); /* { dg-message "\\(1\\) first 'close' here" } */ + close(fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" "warning" } */ + /* { dg-message "\\(2\\) second 'close' here; first 'close' was at \\(1\\)" "event2" { target *-*-* } .-1 } */ +} + +void +test_4 () +{ + int fd = -1; + close(fd); + close(fd); +}
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-3.c b/gcc/testsuite/gcc.dg/analyzer/fd-3.c new file mode 100644 index 0000000..55e84e3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-3.c @@ -0,0 +1,85 @@ +int open(const char *, int mode); +void close(int fd); +int write (int fd, void *buf, int nbytes); +int read (int fd, void *buf, int nbytes); +int some_condition(); + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 +#define STDIN 0 +#define O_NOATIME 262144 + +void +test_1 (const char *path, void *buf) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + write (fd, buf, 1); /* { dg-message "\\(2\\) 'fd' could be invalid: unchecked value from \\(1\\)" } */ + /* { dg-warning "'write' on possibly invalid file descriptor 'fd'" "warning" { target *-*-* } .-1 } */ + close(fd); +} + +void +test_2 (const char *path, void *buf) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + read (fd, buf, 1); /* { dg-message "\\(2\\) 'fd' could be invalid: unchecked value from \\(1\\)" } */ + /* { dg-warning "'read' on possibly invalid file descriptor 'fd'" "warning" { target *-*-* } .-1 } */ + close (fd); +} + +void +test_3 (void *buf) +{ + int fd = -1; + read (fd, buf, 1); /* { dg-warning "'read' on possibly invalid file descriptor 'fd'" } */ + /* { dg-message "\\(1\\) 'fd' could be invalid" "" { target *-*-* } .-1 } */ +} + +void +test_4 (void *buf) +{ + int fd = STDIN; + read (fd, buf, 1); + close(fd); +} + +void +test_5 (char *path, void *buf) +{ + int flags = O_RDONLY; + if (some_condition()) + flags |= O_NOATIME; + int fd = open (path, flags); + read (fd, buf, 1); /* { dg-warning "'read' on possibly invalid file descriptor 'fd'" } */ + /* { dg-message "\\(1\\) 'fd' could be invalid" "" { target *-*-* } .-1 } */ + close (fd); +} + + +void +test_6 (char *path, void *buf) +{ + int fd = open (path, O_RDONLY); + if (fd != -1) + { + read (fd, buf, 1); + } + close (fd); +} + + +void +test_7 (char *path, void *buf) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + if (fd != -1) /* { dg-message "\\(2\\) assuming 'fd' is an invalid file descriptor \\(< 0\\)" } */ + { + read (fd, buf, 1); + } else + { + write (fd, buf, 1); /* { dg-warning "'write' on possibly invalid file descriptor 'fd'" } */ + + } + close(fd); +}
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-4.c b/gcc/testsuite/gcc.dg/analyzer/fd-4.c new file mode 100644 index 0000000..ecd787c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-4.c @@ -0,0 +1,72 @@ +#include <stdio.h> + +int open(const char *, int mode); +void close(int fd); +int write (int fd, void *buf, int nbytes); +int read (int fd, void *buf, int nbytes); + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + + +void +test_1 (const char *path, void *buf) +{ + int fd = open (path, O_RDONLY); /* { dg-message "opened here as read-only" } */ + if (fd >= 0) /* { dg-message "assuming 'fd' is a valid file descriptor \\(>= 0\\)" "event1" } */ + /* { dg-message "following 'true' branch \\(when 'fd >= 0'\\)..." "event2" { target *-*-* } .-1 } */ + { + write (fd, buf, 1); /* { dg-warning "'write' on read-only file descriptor 'fd'" "warning" } */ + /* { dg-message "\\(4\\) ...to here" "event1" { target *-*-* } .-1 } */ + /* { dg-message "\\(5\\) 'write' on read-only file descriptor 'fd'" "event2" { target *-*-* } .-2 } */ + close (fd); + } +} + +void +test_2 (const char *path, void *buf) +{ + int fd = open (path, O_WRONLY); /* { dg-message "opened here as write-only" } */ + if (fd >= 0) /* { dg-message "assuming 'fd' is a valid file descriptor \\(>= 0\\)" "event1" } */ + /* { dg-message "following 'true' branch \\(when 'fd >= 0'\\)..." "event2" { target *-*-* } .-1 } */ + { + read (fd, buf, 1); /* { dg-warning "'read' on write-only file descriptor 'fd'" "warning" } */ + /* { dg-message "\\(4\\) ...to here" "event1" { target *-*-* } .-1 } */ + /* { dg-message "\\(5\\) 'read' on write-only file descriptor 'fd'" "event2" { target *-*-* } .-2 } */ + close (fd); + } +} + + +void +test_3 (const char *path, void *buf) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + if (fd >= 0) + { + close(fd); /* {dg-message "\\(2\\) closed here"} */ + read(fd, buf, 1); /* { dg-warning "'read' on closed file descriptor 'fd'" } */ + /* {dg-message "\\(3\\) 'read' on closed file descriptor 'fd'; 'close' was at \\(2\\)" "" {target *-*-*} .-1 } */ + } +} + +void +test_4 (const char *path, void *buf) +{ + int fd = open (path, O_RDWR); /* { dg-message "\\(1\\) opened here" } */ + if (fd >= 0) + { + close(fd); /* {dg-message "\\(2\\) closed here"} */ + write(fd, buf, 1); /* { dg-warning "'write' on closed file descriptor 'fd'" } */ + /* {dg-message "\\(3\\) 'write' on closed file descriptor 'fd'; 'close' was at \\(2\\)" "" {target *-*-*} .-1 } */ + } +} + +void +test_5 (const char *path) +{ + int fd = open (path, O_RDWR); + close(fd); + printf("%d", fd); /* { dg-bogus "'printf' on a closed file descriptor 'fd'" } */ +}
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-5.c b/gcc/testsuite/gcc.dg/analyzer/fd-5.c new file mode 100644 index 0000000..c18b2ad --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-5.c @@ -0,0 +1,53 @@ +int open(const char *, int mode); +void close(int fd); +int write (int fd, void *buf, int nbytes); +int read (int fd, void *buf, int nbytes); + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +void f (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'f' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */ + +void +test_1 (const char *path) +{ + int fd = open (path, O_RDWR); + close(fd); + f(fd); /* { dg-warning "'f' on closed file descriptor 'fd'" } */ + /* { dg-message "\\(3\\) 'f' on closed file descriptor 'fd'; 'close' was at \\(2\\)" "" { target *-*-* } .-1 } */ +} + +void g (int fd) __attribute__((fd_arg_read(1))); /* { dg-message "argument 1 of 'g' must be a readable file descriptor, due to '__attribute__\\(\\(fd_arg_read\\(1\\)\\)\\)'" } */ + +void +test_2 (const char *path) +{ + int fd = open (path, O_WRONLY); + if (fd != -1) + { + g (fd); /* { dg-warning "'g' on write-only file descriptor 'fd'" } */ + } + close (fd); +} + +void h (int fd) __attribute__((fd_arg_write(1))); /* { dg-message "argument 1 of 'h' must be a writable file descriptor, due to '__attribute__\\(\\(fd_arg_write\\(1\\)\\)\\)'" } */ +void +test_3 (const char *path) +{ + int fd = open (path, O_RDONLY); + if (fd != -1) + { + h (fd); /* { dg-warning "'h' on read-only file descriptor 'fd'" } */ + } + close(fd); +} + +void ff (int fd) __attribute__((fd_arg(1))); /* { dg-message "argument 1 of 'ff' must be an open file descriptor, due to '__attribute__\\(\\(fd_arg\\(1\\)\\)\\)'" } */ + +void test_4 (const char *path) +{ + int fd = open (path, O_RDWR); + ff (fd); /* { dg-warning "'ff' on possibly invalid file descriptor 'fd'" } */ + close(fd); +}
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/fd-meaning.c b/gcc/testsuite/gcc.dg/analyzer/fd-meaning.c new file mode 100644 index 0000000..6a9ec92 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fd-meaning.c @@ -0,0 +1,37 @@ + /* { dg-additional-options "-fanalyzer-verbose-state-changes" } */ +int open(const char *, int mode); +void close(int fd); + +#define O_RDONLY 0 +#define O_WRONLY 1 +#define O_RDWR 2 + +void test_1 (const char* path) +{ + int fd = open (path, O_RDWR); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */ + if (fd != -1) + { + close(fd); /* { dg-message "meaning: \\{verb: 'release', noun: 'resource'\\}" } */ + close(fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" } */ + } +} + +void test_2 (const char* path) +{ + int fd = open (path, O_RDONLY); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */ + if (fd != -1) + { + close(fd); /* { dg-message "meaning: \\{verb: 'release', noun: 'resource'\\}" } */ + close(fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" } */ + } +} + +void test_3 (const char* path) +{ + int fd = open (path, O_WRONLY); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */ + if (fd != -1) + { + close(fd); /* { dg-message "meaning: \\{verb: 'release', noun: 'resource'\\}" } */ + close(fd); /* { dg-warning "double 'close' of file descriptor 'fd' \\\[CWE-1341\\\]" } */ + } +}
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/analyzer/file-1.c b/gcc/testsuite/gcc.dg/analyzer/file-1.c index e8d9343..316cbb3 100644 --- a/gcc/testsuite/gcc.dg/analyzer/file-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/file-1.c @@ -14,7 +14,7 @@ test_1 (const char *path) fclose (f); /* { dg-message "\\(4\\) \\.\\.\\.to here" "to here" } */ /* { dg-message "\\(5\\) first 'fclose' here" "first fclose" { target *-*-* } .-1 } */ - fclose (f); /* { dg-warning "double 'fclose' of FILE 'f'" "warning" } */ + fclose (f); /* { dg-warning "double 'fclose' of FILE 'f' \\\[CWE-1341\\\]" "warning" } */ /* { dg-message "second 'fclose' here; first 'fclose' was at \\(5\\)" "second fclose" { target *-*-* } .-1 } */ } diff --git a/gcc/testsuite/gcc.dg/analyzer/file-meaning-1.c b/gcc/testsuite/gcc.dg/analyzer/file-meaning-1.c new file mode 100644 index 0000000..66b72a7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/file-meaning-1.c @@ -0,0 +1,15 @@ +/* { dg-additional-options "-fanalyzer-verbose-state-changes" } */ + +typedef struct FILE FILE; +FILE* fopen (const char*, const char*); +int fclose (FILE*); + +void test_1 (const char *path) +{ + FILE *f = fopen (path, "r"); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'resource'\\}" } */ + if (!f) + return; + + fclose (f); /* { dg-message "meaning: \\{verb: 'release', noun: 'resource'\\}" } */ + fclose (f); /* { dg-warning "double 'fclose' of FILE 'f'" "warning" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/fread-2.c b/gcc/testsuite/gcc.dg/analyzer/fread-2.c new file mode 100644 index 0000000..02a5e31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/fread-2.c @@ -0,0 +1,31 @@ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +#include "analyzer-decls.h" + +struct S +{ + int i; +}; + +typedef __SIZE_TYPE__ size_t; + +extern size_t fread (void *, size_t, size_t, void *); + +/* fread of a static struct that never gets used. */ + +void +test_1 (void *fp) +{ + static struct S s; /* { dg-warning "track 's': no" } */ + fread (&s, sizeof (s), 1, fp); +} + +/* fread of a static struct that later gets used. */ + +int +test_2 (void *fp) +{ + static struct S s; /* { dg-warning "track 's': yes" } */ + fread (&s, sizeof (s), 1, fp); + return s.i; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-1-multiline.c new file mode 100644 index 0000000..79621f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-1-multiline.c @@ -0,0 +1,56 @@ +/* As per inlining-1.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +void foo (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ +} + +void bar (void *q) +{ + foo (q); + foo (q); +} + +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ^~~~~~~~~~~~~~~~~~ + 'bar': events 1-2 (depth 1) + | + | void bar (void *q) + | ^~~ + | | + | (1) entry to 'bar' + | + | foo (q); + | ~ + | | + | (2) inlined call to 'foo' from 'bar' + | + +--> 'foo': event 3 (depth 2) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (3) first 'free' here + | + <------+ + | + 'bar': event 4 (depth 1) + | + | foo (q); + | ^ + | | + | (4) inlined call to 'foo' from 'bar' + | + +--> 'foo': event 5 (depth 2) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (5) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1-no-undo.c b/gcc/testsuite/gcc.dg/analyzer/inlining-1-no-undo.c new file mode 100644 index 0000000..bad0f68 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-1-no-undo.c @@ -0,0 +1,18 @@ +/* Test for -fno-analyzer-undo-inlining. + Verify that we can disable reconstruction of fndecl and stack depth + information. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths -fno-analyzer-undo-inlining" } */ + +void foo (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ + /* { dg-message "\\(1\\) first 'free' here \\(fndecl 'bar', depth 1\\)" "1st free message" { target *-*-* } .-1 } */ + /* { dg-message "\\(2\\) second 'free' here; first 'free' was at \\(1\\) \\(fndecl 'bar', depth 1\\)" "2nd free message" { target *-*-* } .-2 } */ +} + +void bar (void *q) +{ + foo (q); + foo (q); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-1.c b/gcc/testsuite/gcc.dg/analyzer/inlining-1.c new file mode 100644 index 0000000..a9797ea --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-1.c @@ -0,0 +1,17 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +void foo (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ + /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'foo', depth 2\\)" "1st free message" { target *-*-* } .-1 } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'foo', depth 2\\)" "2nd free message" { target *-*-* } .-2 } */ +} + +void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" } */ +{ + foo (q); /* { dg-message "\\(2\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ + foo (q); /* { dg-message "\\(4\\) inlined call to 'foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-2-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-2-multiline.c new file mode 100644 index 0000000..0a006b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-2-multiline.c @@ -0,0 +1,46 @@ +/* As per inlining-2.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +static void __analyzer_foo (void *p) +{ + __builtin_free (p); + + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ +} + +void bar (void *q) +{ + __analyzer_foo (q); +} + +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ^~~~~~~~~~~~~~~~~~ + 'bar': events 1-2 (depth 1) + | + | void bar (void *q) + | ^~~ + | | + | (1) entry to 'bar' + | + | __analyzer_foo (q); + | ~ + | | + | (2) inlined call to '__analyzer_foo' from 'bar' + | + +--> '__analyzer_foo': events 3-4 (depth 2) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (3) first 'free' here + | + | __builtin_free (p); + | ~~~~~~~~~~~~~~~~~~ + | | + | (4) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-2.c b/gcc/testsuite/gcc.dg/analyzer/inlining-2.c new file mode 100644 index 0000000..da06fa2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-2.c @@ -0,0 +1,17 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +static void __analyzer_foo (void *p) +{ + __builtin_free (p); /* { dg-message "\\(3\\) first 'free' here \\(fndecl '__analyzer_foo', depth 2\\)" "1st free message" } */ + + __builtin_free (p); /* { dg-warning "double-'free' of 'q'" "warning" } */ + /* { dg-message "\\(4\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl '__analyzer_foo', depth 2\\)" "2nd free message" { target *-*-* } .-1 } */ +} + +void bar (void *q) /* { dg-message "\\(1\\) entry to 'bar' \\(fndecl 'bar', depth 1\\)" } */ +{ + __analyzer_foo (q); /* { dg-message "\\(2\\) inlined call to '__analyzer_foo' from 'bar' \\(fndecl 'bar', depth 1\\)" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c new file mode 100644 index 0000000..15a2dd8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c @@ -0,0 +1,64 @@ +/* As per inlining-3.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *)0) + +struct input_file_st +{ + char inpname[1]; +}; + +typedef struct input_file_st input_file; + +static inline const char* +get_input_file_name (const input_file *inpf) +{ + if (inpf) + return inpf->inpname; + return NULL; +} + +size_t +test (const input_file *inpf) +{ + const char *f = get_input_file_name (inpf); + return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ +} + +/* { dg-begin-multiline-output "" } + return __builtin_strlen (f); + ^~~~~~~~~~~~~~~~~~~~ + 'test': events 1-2 (depth 1) + | + | test (const input_file *inpf) + | ^~~~ + | | + | (1) entry to 'test' + | + | const char *f = get_input_file_name (inpf); + | ~ + | | + | (2) inlined call to 'get_input_file_name' from 'test' + | + +--> 'get_input_file_name': event 3 (depth 2) + | + | if (inpf) + | ^ + | | + | (3) following 'false' branch (when 'inpf' is NULL)... + | + <------+ + | + 'test': events 4-5 (depth 1) + | + | return __builtin_strlen (f); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (4) ...to here + | (5) argument 1 ('<unknown>') NULL where non-null expected + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-3.c b/gcc/testsuite/gcc.dg/analyzer/inlining-3.c new file mode 100644 index 0000000..7a292ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-3.c @@ -0,0 +1,30 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *)0) + +struct input_file_st +{ + char inpname[1]; +}; + +typedef struct input_file_st input_file; + +static inline const char* +get_input_file_name (const input_file *inpf) +{ + if (inpf) /* { dg-message "following 'false' branch \\(when 'inpf' is NULL\\)\\.\\.\\. \\(fndecl 'get_input_file_name', depth 2\\)" } */ + return inpf->inpname; + return NULL; +} + +size_t +test (const input_file *inpf) +{ + const char *f = get_input_file_name (inpf); + return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ + /* { dg-message "NULL where non-null expected \\(fndecl 'test', depth 1\\)" "message" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c new file mode 100644 index 0000000..0413c39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c @@ -0,0 +1,72 @@ +/* As per inlining-4.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +#define NULL ((void *)0) + +static inline const char* +inner (int flag) +{ + if (flag) + return NULL; + return "foo"; +} + +static inline const char* +middle (int flag) +{ + return inner (flag); +} + +char +outer (int flag) +{ + return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ +} + +/* { dg-begin-multiline-output "" } + return *middle (flag); + ^~~~~~~~~~~~~~ + 'outer': events 1-2 (depth 1) + | + | outer (int flag) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | return *middle (flag); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'middle': event 3 (depth 2) + | + | return inner (flag); + | ^ + | | + | (3) inlined call to 'inner' from 'middle' + | + +--> 'inner': event 4 (depth 3) + | + | if (flag) + | ^ + | | + | (4) following 'true' branch (when 'flag != 0')... + | + <-------------+ + | + 'outer': event 5 (depth 1) + | + |cc1: + | (5): ...to here + | + 'outer': event 6 (depth 1) + | + | return *middle (flag); + | ^~~~~~~~~~~~~~ + | | + | (6) dereference of NULL '<unknown>' + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-4.c b/gcc/testsuite/gcc.dg/analyzer/inlining-4.c new file mode 100644 index 0000000..f4e4208 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-4.c @@ -0,0 +1,27 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +#define NULL ((void *)0) + +static inline const char* +inner (int flag) +{ + if (flag) /* { dg-message "following 'true' branch \\(when 'flag != 0'\\)\\.\\.\\. \\(fndecl 'inner', depth 3\\)" } */ + return NULL; + return "foo"; +} + +static inline const char* +middle (int flag) +{ + return inner (flag); +} + +char +outer (int flag) +{ + return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ + /* { dg-message "\\(fndecl 'outer', depth 1\\)" "message" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-5-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-5-multiline.c new file mode 100644 index 0000000..21b8fb9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-5-multiline.c @@ -0,0 +1,59 @@ +/* As per inlining-5.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +static inline void +inner (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'r'" } */ +} + +static inline void +middle (void *q) +{ + __builtin_free (q); + inner (q); +} + +void +outer (void *r) +{ + middle (r); +} + +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ^~~~~~~~~~~~~~~~~~ + 'outer': events 1-2 (depth 1) + | + | outer (void *r) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | middle (r); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'middle': events 3-4 (depth 2) + | + | __builtin_free (q); + | ^~~~~~~~~~~~~~~~~~ + | | + | (3) first 'free' here + | inner (q); + | ~ + | | + | (4) inlined call to 'inner' from 'middle' + | + +--> 'inner': event 5 (depth 3) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (5) second 'free' here; first 'free' was at (3) + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-5.c b/gcc/testsuite/gcc.dg/analyzer/inlining-5.c new file mode 100644 index 0000000..5104be0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-5.c @@ -0,0 +1,24 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +static inline void +inner (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'r'" } */ + /* { dg-message "\\(5\\) second 'free' here; first 'free' was at \\(3\\) \\(fndecl 'inner', depth 3\\)" "2nd free message" { target *-*-* } .-1 } */ +} + +static inline void +middle (void *q) +{ + __builtin_free (q); /* { dg-message "\\(3\\) first 'free' here \\(fndecl 'middle', depth 2\\)" "1st free message" } */ + inner (q); /* { dg-message "\\(4\\) inlined call to 'inner' from 'middle' \\(fndecl 'middle', depth 2\\)" } */ +} + +void +outer (void *r) /* { dg-message "\\(1\\) entry to 'outer' \\(fndecl 'outer', depth 1\\)" } */ +{ + middle (r); /* { dg-message "\\(2\\) inlined call to 'middle' from 'outer' \\(fndecl 'outer', depth 1\\)" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-6-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-6-multiline.c new file mode 100644 index 0000000..9cec614 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-6-multiline.c @@ -0,0 +1,64 @@ +/* As per inlining-6.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +static inline void +inner (void *p) +{ + __builtin_free (p); +} + +static inline void +middle (void *q) +{ + inner (q); + __builtin_free (q); /* { dg-warning "double-'free' of 'r'" } */ +} + +void +outer (void *r) +{ + middle (r); +} + +/* { dg-begin-multiline-output "" } + __builtin_free (q); + ^~~~~~~~~~~~~~~~~~ + 'outer': events 1-2 (depth 1) + | + | outer (void *r) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | middle (r); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'middle': event 3 (depth 2) + | + | inner (q); + | ^ + | | + | (3) inlined call to 'inner' from 'middle' + | + +--> 'inner': event 4 (depth 3) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (4) first 'free' here + | + <------+ + | + 'middle': event 5 (depth 2) + | + | __builtin_free (q); + | ^~~~~~~~~~~~~~~~~~ + | | + | (5) second 'free' here; first 'free' was at (4) + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-6.c b/gcc/testsuite/gcc.dg/analyzer/inlining-6.c new file mode 100644 index 0000000..e19e85a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-6.c @@ -0,0 +1,23 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +static inline void +inner (void *p) +{ + __builtin_free (p); +} + +static inline void +middle (void *q) +{ + inner (q); + __builtin_free (q); /* { dg-warning "double-'free' of 'r'" "warning" } */ +} + +void +outer (void *r) +{ + middle (r); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-7-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-7-multiline.c new file mode 100644 index 0000000..956c6b9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-7-multiline.c @@ -0,0 +1,128 @@ +/* As per inlining-7.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +static inline void +depth_6 (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'p1'" "warning" } */ +} + +static inline void +depth_5 (void *p5) +{ + depth_6 (p5); +} + +static inline void +depth_4 (void *p4) +{ + depth_5 (p4); +} + +static inline void +depth_3 (void *p3) +{ + depth_4 (p3); + depth_4 (p3); +} + +static inline void +depth_2 (void *p2) +{ + depth_3 (p2); +} + +void +depth_1 (void *p1) +{ + depth_2 (p1); +} + +/* We want the reconstructed call/return hierarchy to show + that two calls happen at depth_3, without popping the stack + back any further. */ + +/* { dg-begin-multiline-output "" } + __builtin_free (p); + ^~~~~~~~~~~~~~~~~~ + 'depth_1': events 1-2 (depth 1) + | + | depth_1 (void *p1) + | ^~~~~~~ + | | + | (1) entry to 'depth_1' + | + | depth_2 (p1); + | ~ + | | + | (2) inlined call to 'depth_2' from 'depth_1' + | + +--> 'depth_2': event 3 (depth 2) + | + | depth_3 (p2); + | ^ + | | + | (3) inlined call to 'depth_3' from 'depth_2' + | + +--> 'depth_3': event 4 (depth 3) + | + | depth_4 (p3); + | ^ + | | + | (4) inlined call to 'depth_4' from 'depth_3' + | + +--> 'depth_4': event 5 (depth 4) + | + | depth_5 (p4); + | ^ + | | + | (5) inlined call to 'depth_5' from 'depth_4' + | + +--> 'depth_5': event 6 (depth 5) + | + | depth_6 (p5); + | ^ + | | + | (6) inlined call to 'depth_6' from 'depth_5' + | + +--> 'depth_6': event 7 (depth 6) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (7) first 'free' here + | + <--------------------+ + | + 'depth_3': event 8 (depth 3) + | + | depth_4 (p3); + | ^ + | | + | (8) inlined call to 'depth_4' from 'depth_3' + | + +--> 'depth_4': event 9 (depth 4) + | + | depth_5 (p4); + | ^ + | | + | (9) inlined call to 'depth_5' from 'depth_4' + | + +--> 'depth_5': event 10 (depth 5) + | + | depth_6 (p5); + | ^ + | | + | (10) inlined call to 'depth_6' from 'depth_5' + | + +--> 'depth_6': event 11 (depth 6) + | + | __builtin_free (p); + | ^~~~~~~~~~~~~~~~~~ + | | + | (11) second 'free' here; first 'free' was at (7) + | + { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-7.c b/gcc/testsuite/gcc.dg/analyzer/inlining-7.c new file mode 100644 index 0000000..fe04042 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/inlining-7.c @@ -0,0 +1,49 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +/* We want the reconstructed call/return hierarchy to show + that two calls happen at depth_3, without any spurious events + popping the stack back any further. */ + +static inline void +depth_6 (void *p) +{ + __builtin_free (p); /* { dg-warning "double-'free' of 'p1'" "warning" } */ + /* { dg-message "\\(7\\) first 'free' here \\(fndecl 'depth_6', depth 6\\)" "1st free message" { target *-*-* } .-1 } */ + /* { dg-message "\\(11\\) second 'free' here; first 'free' was at \\(7\\) \\(fndecl 'depth_6', depth 6\\)" "2nd free message" { target *-*-* } .-2 } */ +} + +static inline void +depth_5 (void *p5) +{ + depth_6 (p5); /* { dg-message "\\(6\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 6" } */ + /* { dg-message "\\(10\\) inlined call to 'depth_6' from 'depth_5' \\(fndecl 'depth_5', depth 5\\)" "event 10" { target *-*-* } .-1 } */ +} + +static inline void +depth_4 (void *p4) +{ + depth_5 (p4); /* { dg-message "\\(5\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 5" } */ + /* { dg-message "\\(9\\) inlined call to 'depth_5' from 'depth_4' \\(fndecl 'depth_4', depth 4\\)" "event 9" { target *-*-* } .-1 } */ +} + +static inline void +depth_3 (void *p3) +{ + depth_4 (p3); /* { dg-message "\\(4\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" } */ + depth_4 (p3); /* { dg-message "\\(8\\) inlined call to 'depth_4' from 'depth_3' \\(fndecl 'depth_3', depth 3\\)" } */ +} + +static inline void +depth_2 (void *p2) +{ + depth_3 (p2); /* { dg-message "\\(3\\) inlined call to 'depth_3' from 'depth_2' \\(fndecl 'depth_2', depth 2\\)" } */ +} + +void +depth_1 (void *p1) /* { dg-message "\\(1\\) entry to 'depth_1' \\(fndecl 'depth_1', depth 1\\)" } */ +{ + depth_2 (p1); /* { dg-message "\\(2\\) inlined call to 'depth_2' from 'depth_1' \\(fndecl 'depth_1', depth 1\\)" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-4.c b/gcc/testsuite/gcc.dg/analyzer/leak-4.c new file mode 100644 index 0000000..75090e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/leak-4.c @@ -0,0 +1,103 @@ +/* Various tests of memory leak detection. */ + +#include <stdlib.h> + +/* Example of an leak due to incomplete cleanup when freeing a struct. */ + +struct s1 +{ + void *ptr; +}; + +void test_1 (void) +{ + struct s1 *a = malloc (sizeof (struct s1)); + if (!a) + return; + a->ptr = malloc (1024); /* { dg-message "allocated here" } */ + free (a); /* { dg-warning "leak of '<unknown>'" } */ + /* TODO: we should print "a->ptr' here, rather than '<unknown>' + (PR analyzer/99771). */ +} + + +/* Examples involving arrays. */ + +struct s2 +{ + void *m_arr[10]; +}; + +void test_2a (void) +{ + struct s2 arr[5]; + arr[3].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[4\\\]'" } */ + +void test_2b (int i) +{ + struct s2 arr[5]; + arr[3].m_arr[i] = malloc (1024); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'arr\\\[3\\\].m_arr\\\[i\\\]'" } */ + +void test_2c (int i) +{ + struct s2 arr[5]; + arr[i].m_arr[4] = malloc (1024); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[4\\\]'" } */ + +void test_2d (int i, int j) +{ + struct s2 arr[5]; + arr[i].m_arr[j] = malloc (1024); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'arr\\\[i\\\].m_arr\\\[j\\\]'" } */ + + +/* Example involving fields. */ + +struct s3 +{ + struct s3 *m_left; + struct s3 *m_right; +}; + +void test_3 (void) +{ + struct s3 *a = malloc (sizeof (struct s3)); + a->m_right = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL 'a'" } */ + a->m_right->m_left = malloc (sizeof (struct s3)); /* { dg-warning "dereference of possibly-NULL '\\*a.m_right'" } */ +} /* { dg-warning "leak of 'a'" "leak of a" } */ +/* { dg-warning "leak of '<unknown>'" "leak of unknown" { target *-*-* } .-1 } */ +/* TODO: rather than '<unknown>', we should print 'a->m_right' + and 'a->m_right->m_left' (PR analyzer/99771). */ + + +/* Example involving faking inheritance via casts. */ + +struct s4_base +{ + int m_placeholder; +}; + +struct s4_sub +{ + void *m_buffer; +}; + +static struct s4_sub * +make_s4_sub (void) +{ + struct s4_sub *sub = malloc (sizeof (struct s4_sub)); /* { dg-message "allocated here" } */ + if (!sub) + return NULL; + sub->m_buffer = malloc (1024); /* { dg-message "allocated here" } */ + return sub; +} + +void test_4 (void) +{ + struct s4_base *base = (struct s4_base *)make_s4_sub (); +} /* { dg-warning "leak of 'base'" "leak of base" } */ +/* { dg-warning "leak of '<unknown>'" "leak of sub buffer" { target *-*-* } .-1 } */ +/* TODO: rather than 'unknown', we should print something + like '((struct s4_sub *)base)->m_buffer' (PR analyzer/99771). */ diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-meaning-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-meaning-1.c new file mode 100644 index 0000000..4964e25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-meaning-1.c @@ -0,0 +1,10 @@ +/* { dg-additional-options "-fanalyzer-verbose-state-changes" } */ + +#include <stdlib.h> + +void test_1 (void) +{ + void *ptr = malloc (1024); /* { dg-message "meaning: \\{verb: 'acquire', noun: 'memory'\\}" } */ + free (ptr); /* { dg-message "meaning: \\{verb: 'release', noun: 'memory'\\}" } */ + free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-sarif-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-sarif-1.c new file mode 100644 index 0000000..3d141b5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/malloc-sarif-1.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fdiagnostics-format=sarif-file" } */ + +#include <stdlib.h> + +void test_1 (void) +{ + void *ptr = malloc (1024); + free (ptr); + free (ptr); +} + +/* Verify SARIF output. + + The threadFlowLocation objects should have "kinds" properties + reflecting the meanings of the events: + { dg-final { scan-sarif-file "\"kinds\": \\\[\"acquire\", \"memory\"\\\]" } } + { dg-final { scan-sarif-file "\"kinds\": \\\[\"release\", \"memory\"\\\]" } } + { dg-final { scan-sarif-file "\"kinds\": \\\[\"danger\"\\\]" } } +*/ diff --git a/gcc/testsuite/gcc.dg/analyzer/many-disabled-diagnostics.c b/gcc/testsuite/gcc.dg/analyzer/many-disabled-diagnostics.c new file mode 100644 index 0000000..48d4023 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/many-disabled-diagnostics.c @@ -0,0 +1,55 @@ +/* { dg-additional-options "-Wno-analyzer-double-free" } */ + +#define DOUBLE_FREE() \ + do { \ + void *p = __builtin_malloc (1024); \ + __builtin_free (p); \ + __builtin_free (p); \ + } while (0) + +#define DOUBLE_FREE_x_10() \ + do { \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + DOUBLE_FREE(); \ + } while (0) + +#define DOUBLE_FREE_x_100() \ + do { \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + DOUBLE_FREE_x_10(); \ + } while (0) + +#define DOUBLE_FREE_x_1000() \ + do { \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + DOUBLE_FREE_x_100(); \ + } while (0) + +void test_1 (void) +{ + DOUBLE_FREE_x_1000 (); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/many-unused-locals.c b/gcc/testsuite/gcc.dg/analyzer/many-unused-locals.c new file mode 100644 index 0000000..6b5c855 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/many-unused-locals.c @@ -0,0 +1,69 @@ +struct st +{ + const char *m_filename; + int m_line; + const char *m_function; +}; + +extern void debug (struct st *); + +#define TEST_x_1(NAME) \ + do \ + { \ + static struct st NAME = { __FILE__, __LINE__, __func__ }; \ + debug (&NAME); \ + } \ + while (0) + +#define TEST_x_10(PREFIX) \ + do \ + { \ + TEST_x_1(PREFIX ## _1); \ + TEST_x_1(PREFIX ## _2); \ + TEST_x_1(PREFIX ## _3); \ + TEST_x_1(PREFIX ## _4); \ + TEST_x_1(PREFIX ## _5); \ + TEST_x_1(PREFIX ## _6); \ + TEST_x_1(PREFIX ## _7); \ + TEST_x_1(PREFIX ## _8); \ + TEST_x_1(PREFIX ## _9); \ + TEST_x_1(PREFIX ## _10); \ + } \ + while(0) + +#define TEST_x_100(PREFIX) \ + do \ + { \ + TEST_x_10(PREFIX ## _1); \ + TEST_x_10(PREFIX ## _2); \ + TEST_x_10(PREFIX ## _3); \ + TEST_x_10(PREFIX ## _4); \ + TEST_x_10(PREFIX ## _5); \ + TEST_x_10(PREFIX ## _6); \ + TEST_x_10(PREFIX ## _7); \ + TEST_x_10(PREFIX ## _8); \ + TEST_x_10(PREFIX ## _9); \ + TEST_x_10(PREFIX ## _10); \ + } \ + while(0) + +#define TEST_x_1000(PREFIX) \ + do \ + { \ + TEST_x_100(PREFIX ## _1); \ + TEST_x_100(PREFIX ## _2); \ + TEST_x_100(PREFIX ## _3); \ + TEST_x_100(PREFIX ## _4); \ + TEST_x_100(PREFIX ## _5); \ + TEST_x_100(PREFIX ## _6); \ + TEST_x_100(PREFIX ## _7); \ + TEST_x_100(PREFIX ## _8); \ + TEST_x_100(PREFIX ## _9); \ + TEST_x_100(PREFIX ## _10); \ + } \ + while(0) + +void test_many (void) +{ + TEST_x_1000(s); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c b/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c new file mode 100644 index 0000000..88ec84c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c @@ -0,0 +1,8 @@ +/* { dg-additional-options "-Wno-stringop-overflow" } */ + +void +main (int c, void *v) +{ + static char a[] = ""; + __builtin_memcpy (v, a, -1); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-2.c b/gcc/testsuite/gcc.dg/analyzer/memset-2.c new file mode 100644 index 0000000..de7c973 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/memset-2.c @@ -0,0 +1,27 @@ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +#include "analyzer-decls.h" + +struct S +{ + int i; +}; + +/* memset of a static struct that never gets used. */ + +void +test_1 (void) +{ + static struct S s; /* { dg-warning "track 's': no" } */ + __builtin_memset (&s, 0, sizeof (s)); +} + +/* memset of a static struct that later gets used. */ + +void +test_2 (void) +{ + static struct S s; /* { dg-warning "track 's': yes" } */ + __builtin_memset (&s, 0, sizeof (s)); + __analyzer_eval (s.i == 0); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101983-main.c b/gcc/testsuite/gcc.dg/analyzer/pr101983-main.c new file mode 100644 index 0000000..a84353b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101983-main.c @@ -0,0 +1,38 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex -fno-analyzer-call-summaries" } */ + +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> + +struct list { + struct list* next; + void *a; +}; + +void func(struct list **res) +{ + struct list *cur = NULL; + do { + struct list *n = malloc(sizeof(struct list)); + void *a = malloc(1); + if (n == NULL || a == NULL) { + if (n != NULL) free(n); + if (a != NULL) free(a); + break; + } + + if (cur == NULL) { + *res = cur = n; + } else { + cur->next = n; + cur = n; + } + n->a = a; + } while (true); +} + +int main() +{ + struct list *res; + func(&res); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101983-not-main.c b/gcc/testsuite/gcc.dg/analyzer/pr101983-not-main.c new file mode 100644 index 0000000..fbf3a39 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr101983-not-main.c @@ -0,0 +1,40 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex -fno-analyzer-call-summaries" } */ + +#include <stdbool.h> +#include <stddef.h> +#include <stdlib.h> + +struct list { + struct list* next; + void *a; +}; + +void func(struct list **res) +{ + struct list *cur = NULL; + do { + struct list *n = malloc(sizeof(struct list)); + void *a = malloc(1); + if (n == NULL || a == NULL) { + if (n != NULL) free(n); + if (a != NULL) free(a); + break; + } + + if (cur == NULL) { + *res = cur = n; + } else { + cur->next = n; + cur = n; + } + n->a = a; + } while (true); +} + +int not_main() +{ + struct list *res; + func(&res); +} /* { dg-warning "leak of 'res'" "leak of res" } */ +/* { dg-warning "leak of '<unknown>'" "leak of res->a" { target *-*-* } .-1 } */ +/* TODO: we should emit 'res->a' rather than '<unknown>' here. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103892.c b/gcc/testsuite/gcc.dg/analyzer/pr103892.c new file mode 100644 index 0000000..e9775b6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr103892.c @@ -0,0 +1,75 @@ +/* { dg-additional-options "-O2" } */ + +extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); + +enum pipecmd_tag +{ + PIPECMD_PROCESS, + PIPECMD_SEQUENCE +}; + +struct pipecmd { + enum pipecmd_tag tag; + union { + struct pipecmd_process { + int argc; + int argv_max; + char **argv; + } process; + struct pipecmd_sequence { + int ncommands; + int commands_max; + struct pipecmd **commands; + } sequence; + } u; +}; + +static char *argstr_get_word (const char **argstr) +{ + while (**argstr) { + switch (**argstr) { + case ' ': + case '\t': + return (void *) 0; + } + } + return (void *) 0; +} + +struct pipecmd *pipecmd_new_argstr (const char *argstr) +{ + argstr_get_word (&argstr); + return (void *) 0; +} + +void pipecmd_free (struct pipecmd *cmd) +{ + int i; + + if (!cmd) + return; + + switch (cmd->tag) { + case PIPECMD_PROCESS: { + struct pipecmd_process *cmdp = &cmd->u.process; + + for (i = 0; i < cmdp->argc; ++i) + free (cmdp->argv[i]); + free (cmdp->argv); + + break; + } + + case PIPECMD_SEQUENCE: { + struct pipecmd_sequence *cmds = &cmd->u.sequence; + + for (i = 0; i < cmds->ncommands; ++i) + pipecmd_free (cmds->commands[i]); + free (cmds->commands); + + break; + } + } + + free (cmd); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104308.c b/gcc/testsuite/gcc.dg/analyzer/pr104308.c new file mode 100644 index 0000000..a3a0cbb --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104308.c @@ -0,0 +1,19 @@ +/* Verify that we have source locations for + -Wanalyzer-use-of-uninitialized-value warnings involving folded + memory ops. */ + +#include <string.h> + +int test_memmove_within_uninit (void) +{ + char s[5]; /* { dg-message "region created on stack here" } */ + memmove(s, s + 1, 2); /* { dg-warning "use of uninitialized value" } */ + return 0; +} + +int test_memcpy_from_uninit (void) +{ + char a1[5]; + char a2[5]; /* { dg-message "region created on stack here" } */ + return (memcpy(a1, a2, 5) == a1); /* { dg-warning "use of uninitialized value" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104434-const.c b/gcc/testsuite/gcc.dg/analyzer/pr104434-const.c new file mode 100644 index 0000000..eacf3f6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104434-const.c @@ -0,0 +1,173 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include "pr104434.h" + +/* Declare LAPACKE_lsame with __attribute__((const)). */ +int LAPACKE_lsame( char ca, char cb ) __attribute__((const)); + +/* Testcase adapted/reduced from + https://github.com/xianyi/OpenBLAS/blob/c5f280a7f0e875d83833d895b2b8b0e341efabf4/lapack-netlib/LAPACKE/src/lapacke_cgbbrd_work.c + which has this license text. */ + +/***************************************************************************** + Copyright (c) 2014, Intel Corp. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** +* Contents: Native middle-level C interface to LAPACK function cgbbrd +* Author: Intel Corporation +* Generated November 2015 +*****************************************************************************/ + +lapack_int LAPACKE_cgbbrd_work( int matrix_layout, char vect, lapack_int m, + lapack_int n, lapack_int ncc, lapack_int kl, + lapack_int ku, lapack_complex_float* ab, + lapack_int ldab, float* d, float* e, + lapack_complex_float* q, lapack_int ldq, + lapack_complex_float* pt, lapack_int ldpt, + lapack_complex_float* c, lapack_int ldc, + lapack_complex_float* work, float* rwork ) +{ + lapack_int info = 0; + if( matrix_layout == LAPACK_COL_MAJOR ) { + /* Call LAPACK function and adjust info */ + LAPACK_cgbbrd( &vect, &m, &n, &ncc, &kl, &ku, ab, &ldab, d, e, q, &ldq, + pt, &ldpt, c, &ldc, work, rwork, &info ); + if( info < 0 ) { + info = info - 1; + } + } else if( matrix_layout == LAPACK_ROW_MAJOR ) { + lapack_int ldab_t = MAX(1,kl+ku+1); + lapack_int ldc_t = MAX(1,m); + lapack_int ldpt_t = MAX(1,n); + lapack_int ldq_t = MAX(1,m); + lapack_complex_float* ab_t = NULL; + lapack_complex_float* q_t = NULL; + lapack_complex_float* pt_t = NULL; + lapack_complex_float* c_t = NULL; + /* Check leading dimension(s) */ + if( ldab < n ) { + info = -9; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldc < ncc ) { + info = -17; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldpt < n ) { + info = -15; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldq < m ) { + info = -13; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + /* Allocate memory for temporary array(s) */ + ab_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * ldab_t * MAX(1,n) ); + if( ab_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_0; + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + q_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldq_t * MAX(1,m) ); + if( q_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_1; + } + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + pt_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldpt_t * MAX(1,n) ); + if( pt_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_2; + } + } + if( ncc != 0 ) { + c_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldc_t * MAX(1,ncc) ); + if( c_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_3; + } + } + /* Transpose input matrices */ + LAPACKE_cgb_trans( matrix_layout, m, n, kl, ku, ab, ldab, ab_t, ldab_t ); + if( ncc != 0 ) { + LAPACKE_cge_trans( matrix_layout, m, ncc, c, ldc, c_t, ldc_t ); + } + /* Call LAPACK function and adjust info */ + LAPACK_cgbbrd( &vect, &m, &n, &ncc, &kl, &ku, ab_t, &ldab_t, d, e, q_t, + &ldq_t, pt_t, &ldpt_t, c_t, &ldc_t, work, rwork, &info ); + if( info < 0 ) { + info = info - 1; + } + /* Transpose output matrices */ + LAPACKE_cgb_trans( LAPACK_COL_MAJOR, m, n, kl, ku, ab_t, ldab_t, ab, + ldab ); + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, m, q_t, ldq_t, q, ldq ); + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, n, n, pt_t, ldpt_t, pt, ldpt ); + } + if( ncc != 0 ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, ncc, c_t, ldc_t, c, ldc ); + } + /* Release memory and exit */ + if( ncc != 0 ) { + LAPACKE_free( c_t ); + } +exit_level_3: + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + LAPACKE_free( pt_t ); + } +exit_level_2: + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + LAPACKE_free( q_t ); + } +exit_level_1: + LAPACKE_free( ab_t ); +exit_level_0: + if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + } + } else { + info = -1; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + } + return info; /* { dg-bogus "leak of 'q_t'" "leak of q_t" } */ + /* { dg-bogus "leak of 'pt_t'" "leak of pt_t" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104434-nonconst.c b/gcc/testsuite/gcc.dg/analyzer/pr104434-nonconst.c new file mode 100644 index 0000000..6bcb5bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104434-nonconst.c @@ -0,0 +1,173 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include "pr104434.h" + +/* Declare LAPACKE_lsame *without* __attribute__((const)). */ +int LAPACKE_lsame( char ca, char cb ); + +/* Testcase adapted/reduced from + https://github.com/xianyi/OpenBLAS/blob/c5f280a7f0e875d83833d895b2b8b0e341efabf4/lapack-netlib/LAPACKE/src/lapacke_cgbbrd_work.c + which has this license text. */ + +/***************************************************************************** + Copyright (c) 2014, Intel Corp. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************** +* Contents: Native middle-level C interface to LAPACK function cgbbrd +* Author: Intel Corporation +* Generated November 2015 +*****************************************************************************/ + +lapack_int LAPACKE_cgbbrd_work( int matrix_layout, char vect, lapack_int m, + lapack_int n, lapack_int ncc, lapack_int kl, + lapack_int ku, lapack_complex_float* ab, + lapack_int ldab, float* d, float* e, + lapack_complex_float* q, lapack_int ldq, + lapack_complex_float* pt, lapack_int ldpt, + lapack_complex_float* c, lapack_int ldc, + lapack_complex_float* work, float* rwork ) +{ + lapack_int info = 0; + if( matrix_layout == LAPACK_COL_MAJOR ) { + /* Call LAPACK function and adjust info */ + LAPACK_cgbbrd( &vect, &m, &n, &ncc, &kl, &ku, ab, &ldab, d, e, q, &ldq, + pt, &ldpt, c, &ldc, work, rwork, &info ); + if( info < 0 ) { + info = info - 1; + } + } else if( matrix_layout == LAPACK_ROW_MAJOR ) { + lapack_int ldab_t = MAX(1,kl+ku+1); + lapack_int ldc_t = MAX(1,m); + lapack_int ldpt_t = MAX(1,n); + lapack_int ldq_t = MAX(1,m); + lapack_complex_float* ab_t = NULL; + lapack_complex_float* q_t = NULL; + lapack_complex_float* pt_t = NULL; + lapack_complex_float* c_t = NULL; + /* Check leading dimension(s) */ + if( ldab < n ) { + info = -9; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldc < ncc ) { + info = -17; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldpt < n ) { + info = -15; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + if( ldq < m ) { + info = -13; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + return info; + } + /* Allocate memory for temporary array(s) */ + ab_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * ldab_t * MAX(1,n) ); + if( ab_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_0; + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + q_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldq_t * MAX(1,m) ); + if( q_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_1; + } + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + pt_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldpt_t * MAX(1,n) ); + if( pt_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_2; + } + } + if( ncc != 0 ) { + c_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldc_t * MAX(1,ncc) ); + if( c_t == NULL ) { + info = LAPACK_TRANSPOSE_MEMORY_ERROR; + goto exit_level_3; + } + } + /* Transpose input matrices */ + LAPACKE_cgb_trans( matrix_layout, m, n, kl, ku, ab, ldab, ab_t, ldab_t ); + if( ncc != 0 ) { + LAPACKE_cge_trans( matrix_layout, m, ncc, c, ldc, c_t, ldc_t ); + } + /* Call LAPACK function and adjust info */ + LAPACK_cgbbrd( &vect, &m, &n, &ncc, &kl, &ku, ab_t, &ldab_t, d, e, q_t, + &ldq_t, pt_t, &ldpt_t, c_t, &ldc_t, work, rwork, &info ); + if( info < 0 ) { + info = info - 1; + } + /* Transpose output matrices */ + LAPACKE_cgb_trans( LAPACK_COL_MAJOR, m, n, kl, ku, ab_t, ldab_t, ab, + ldab ); + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, m, q_t, ldq_t, q, ldq ); + } + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, n, n, pt_t, ldpt_t, pt, ldpt ); + } + if( ncc != 0 ) { + LAPACKE_cge_trans( LAPACK_COL_MAJOR, m, ncc, c_t, ldc_t, c, ldc ); + } + /* Release memory and exit */ + if( ncc != 0 ) { + LAPACKE_free( c_t ); + } +exit_level_3: + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + LAPACKE_free( pt_t ); + } +exit_level_2: + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'q' ) ) { + LAPACKE_free( q_t ); + } +exit_level_1: + LAPACKE_free( ab_t ); +exit_level_0: + if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) { + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + } + } else { + info = -1; + LAPACKE_xerbla( "LAPACKE_cgbbrd_work", info ); + } + return info; /* { dg-warning "leak of 'q_t'" "leak of q_t" } */ + /* { dg-warning "leak of 'pt_t'" "leak of pt_t" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104434.h b/gcc/testsuite/gcc.dg/analyzer/pr104434.h new file mode 100644 index 0000000..473cc67 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr104434.h @@ -0,0 +1,108 @@ +/* Shared header for testing memory leak false positives seen in OpenBLAS, + e.g. in lapacke_cgbbrd_work.c. + + The code is of the form: + + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + pt_t = (lapack_complex_float*) + LAPACKE_malloc( sizeof(lapack_complex_float) * + ldpt_t * MAX(1,n) ); + ...snip... + } + + [...snip lots of code...] + + if( LAPACKE_lsame( vect, 'b' ) || LAPACKE_lsame( vect, 'p' ) ) { + LAPACKE_free( pt_t ); + } + + where LAPACKE_lsame is a case-insensitive comparison, implemented in its + own source file. Without __attribute__((const)) on LAPACKE_lsame, the + analyzer considers the execution paths where the malloc is called, and + then the free is not called. With __attribute__((const)), the analyzer + ought to rule out such paths. */ + +#define NULL ((void *)0) +typedef __SIZE_TYPE__ size_t; + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))) + __attribute__ ((__warn_unused_result__)); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +/* Header adapted/reduced from + https://github.com/xianyi/OpenBLAS/ + which has this license text. */ + +/***************************************************************************** + Copyright (c) 2014, Intel Corp. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Intel Corporation nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. +*****************************************************************************/ + +#define lapack_int int +#define lapack_logical lapack_int + +#define LAPACKE_malloc( size ) malloc( size ) +#define LAPACKE_free( p ) free( p ) + +#define LAPACK_ROW_MAJOR 101 +#define LAPACK_COL_MAJOR 102 + +#define LAPACK_TRANSPOSE_MEMORY_ERROR -1011 + +#define MAX(x,y) (((x) > (y)) ? (x) : (y)) + +#define LAPACK_GLOBAL(lcname,UCNAME) lcname##_ + +typedef float _Complex lapack_complex_float; + +void LAPACKE_xerbla( const char *name, int info ); + +void LAPACKE_cgb_trans( int matrix_layout, int m, int n, + int kl, int ku, + const lapack_complex_float *in, int ldin, + lapack_complex_float *out, int ldout ); +void LAPACKE_cge_trans( int matrix_layout, int m, int n, + const lapack_complex_float* in, int ldin, + lapack_complex_float* out, int ldout ); + +#define LAPACK_cgbbrd LAPACK_GLOBAL(cgbbrd,CGBBRD) +void LAPACK_cgbbrd( + char const* vect, + lapack_int const* m, lapack_int const* n, lapack_int const* ncc, lapack_int const* kl, lapack_int const* ku, + lapack_complex_float* AB, lapack_int const* ldab, + float* D, + float* E, + lapack_complex_float* Q, lapack_int const* ldq, + lapack_complex_float* PT, lapack_int const* ldpt, + lapack_complex_float* C, lapack_int const* ldc, + lapack_complex_float* work, + float* rwork, + lapack_int* info ); diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105074.c b/gcc/testsuite/gcc.dg/analyzer/pr105074.c new file mode 100644 index 0000000..2735854 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105074.c @@ -0,0 +1,9 @@ +/* { dg-additional-options "-O2 -fdump-analyzer-untracked" } */ + +void _gnutls_log(const char *); +static void _gnutls_ocsp_verify_mandatory_stapling(void) { + _gnutls_log(__func__); /* { dg-warning "track '__func__': no" } */ +} +void check_ocsp_response_gnutls_x509_cert_verify_peers(void) { + _gnutls_ocsp_verify_mandatory_stapling(); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105087-1.c b/gcc/testsuite/gcc.dg/analyzer/pr105087-1.c new file mode 100644 index 0000000..c4acf42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105087-1.c @@ -0,0 +1,18 @@ +#include "analyzer-decls.h" + +extern void *inner_alloc (void); + +void * __attribute__((noinline)) +outer_alloc (void) +{ + return inner_alloc (); +} + +void test_1 (void) +{ + void *p, *q; + + p = outer_alloc (); + q = outer_alloc (); + __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105087-2.c b/gcc/testsuite/gcc.dg/analyzer/pr105087-2.c new file mode 100644 index 0000000..7cd6591 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105087-2.c @@ -0,0 +1,20 @@ +#include "analyzer-decls.h" + +extern void inner_alloc (void **); + +void * __attribute__((noinline)) +outer_alloc (void) +{ + void *result; + inner_alloc (&result); + return result; +} + +void test_1 (void) +{ + void *p, *q; + + p = outer_alloc (); + q = outer_alloc (); + __analyzer_eval (p == q); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105252.c b/gcc/testsuite/gcc.dg/analyzer/pr105252.c new file mode 100644 index 0000000..a093eab --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105252.c @@ -0,0 +1,20 @@ +/* { dg-additional-options "-fnon-call-exceptions -O" } */ + +typedef unsigned char C; +typedef unsigned char __attribute__((__vector_size__ (4))) V; + +C m; + +static inline void +bar (C c, V v, V *r) +{ + v %= (c | v) % m; + *r = v; +} + +void +foo (void) +{ + V x; + bar (0, (V){2}, &x); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105365.c b/gcc/testsuite/gcc.dg/analyzer/pr105365.c new file mode 100644 index 0000000..aa576d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105365.c @@ -0,0 +1,17 @@ +/* { dg-require-effective-target int128 } */ + +typedef _Float32 f32; +typedef _Complex _Float32 cf32; +_Float32 g; +__int128 i; + +extern void bar(int); + +void +foo(_Float32 k) { + f32 f = 0; + f /= (_Complex char)__builtin_llround(g); + k /= (cf32)__builtin_copysignf(0, i); + bar(f + k); + foo(0); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105366.c b/gcc/testsuite/gcc.dg/analyzer/pr105366.c new file mode 100644 index 0000000..3dba870 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr105366.c @@ -0,0 +1,19 @@ +/* { dg-require-effective-target int128 } */ +/* { dg-additional-options "-O" } */ + +extern void bar(int); +extern void baz(void); + +typedef unsigned u32; + +void +foo(u32 u, __int128 i) { + baz(); + _Complex int c = i; + c /= (u32)(__UINTPTR_TYPE__)foo; + short s = (short)(__UINTPTR_TYPE__)foo; + u /= (_Complex short)s; + u32 r = u + c; + bar(r); + foo(0, 0); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr106394.c b/gcc/testsuite/gcc.dg/analyzer/pr106394.c new file mode 100644 index 0000000..96bb175 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr106394.c @@ -0,0 +1,19 @@ +struct msm_gpu { + // [...snip...] + const struct msm_gpu_perfcntr *perfcntrs; + // [...snip...] +}; + +struct msm_gpu_perfcntr { + // [...snip...] + const char *name; +}; + +static const struct msm_gpu_perfcntr perfcntrs[] = {}; + +struct msm_gpu *test(struct msm_gpu *gpu) { + // [...snip...] + gpu->perfcntrs = perfcntrs; + // [...snip...] + return gpu; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-signed-char.c index 88ab5bf..1f3df7c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-signed-char.c @@ -4,6 +4,7 @@ removed. */ /* { dg-do "compile" } */ +/* { dg-additional-options "-fsigned-char" } */ /* Minimal replacement of system headers. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-unsigned-char.c b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-unsigned-char.c new file mode 100644 index 0000000..db9678d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-unsigned-char.c @@ -0,0 +1,332 @@ +/* Integration test to ensure we issue FILE * leak diagnostics for + this particular non-trivial case. + Adapted from zlib/contrib/minizip/mztools.c, with all #includes + removed. */ + +/* { dg-do "compile" } */ +/* { dg-additional-options "-funsigned-char" } */ + +/* Minimal replacement of system headers. */ + +typedef __SIZE_TYPE__ size_t; +#define NULL ((void *) 0) + +typedef struct _IO_FILE FILE; +extern FILE *fopen(const char *__restrict __filename, + const char *__restrict __modes); +extern size_t fread (void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __stream); +extern size_t fwrite (const void *__restrict __ptr, size_t __size, + size_t __n, FILE *__restrict __s); +extern int fclose (FILE *__stream); +extern int remove (const char *__filename) + __attribute__ ((__nothrow__ , __leaf__)); + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +extern size_t strlen (const char *__s) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__pure__)) + __attribute__ ((__nonnull__ (1))); + +/* Minimal replacement of zlib headers. */ + +#define ZEXPORT +typedef unsigned long uLong; /* 32 bits or more */ +#define Z_OK 0 +#define Z_ERRNO (-1) +#define Z_STREAM_ERROR (-2) +#define Z_MEM_ERROR (-4) + +/* + Additional tools for Minizip + Code: Xavier Roche '2004 + License: Same as ZLIB (www.gzip.org) +*/ + +/* Code */ + +#define READ_8(adr) ((unsigned char)*(adr)) +#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) ) +#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) ) + +#define WRITE_8(buff, n) do { \ + *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \ +} while(0) +#define WRITE_16(buff, n) do { \ + WRITE_8((unsigned char*)(buff), n); \ + WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \ +} while(0) +#define WRITE_32(buff, n) do { \ + WRITE_16((unsigned char*)(buff), (n) & 0xffff); \ + WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \ +} while(0) + +extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered) +const char* file; +const char* fileOut; +const char* fileOutTmp; +uLong* nRecovered; +uLong* bytesRecovered; +{ + int err = Z_OK; + FILE* fpZip = fopen(file, "rb"); + FILE* fpOut = fopen(fileOut, "wb"); + FILE* fpOutCD = fopen(fileOutTmp, "wb"); + if (fpZip != NULL && fpOut != NULL) { + int entries = 0; + uLong totalBytes = 0; + char header[30]; + char filename[1024]; + char extra[1024]; + int offset = 0; + int offsetCD = 0; + while ( fread(header, 1, 30, fpZip) == 30 ) { + int currentOffset = offset; + + /* File entry */ + if (READ_32(header) == 0x04034b50) { + unsigned int version = READ_16(header + 4); + unsigned int gpflag = READ_16(header + 6); + unsigned int method = READ_16(header + 8); + unsigned int filetime = READ_16(header + 10); + unsigned int filedate = READ_16(header + 12); + unsigned int crc = READ_32(header + 14); /* crc */ + unsigned int cpsize = READ_32(header + 18); /* compressed size */ + unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */ + unsigned int fnsize = READ_16(header + 26); /* file name length */ + unsigned int extsize = READ_16(header + 28); /* extra field length */ + filename[0] = extra[0] = '\0'; + + /* Header */ + if (fwrite(header, 1, 30, fpOut) == 30) { + offset += 30; + } else { + err = Z_ERRNO; + break; + } + + /* Filename */ + if (fnsize > 0) { + if (fnsize < sizeof(filename)) { + if (fread(filename, 1, fnsize, fpZip) == fnsize) { + if (fwrite(filename, 1, fnsize, fpOut) == fnsize) { + offset += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (extsize < sizeof(extra)) { + if (fread(extra, 1, extsize, fpZip) == extsize) { + if (fwrite(extra, 1, extsize, fpOut) == extsize) { + offset += extsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_ERRNO; + break; + } + } + + /* Data */ + { + int dataSize = cpsize; + if (dataSize == 0) { + dataSize = uncpsize; + } + if (dataSize > 0) { + char* data = malloc(dataSize); + if (data != NULL) { + if ((int)fread(data, 1, dataSize, fpZip) == dataSize) { + if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) { + offset += dataSize; + totalBytes += dataSize; + } else { + err = Z_ERRNO; + } + } else { + err = Z_ERRNO; + } + free(data); + if (err != Z_OK) { + break; + } + } else { + err = Z_MEM_ERROR; + break; + } + } + } + + /* Central directory entry */ + { + char header[46]; + char* comment = ""; + int comsize = (int) strlen(comment); + WRITE_32(header, 0x02014b50); + WRITE_16(header + 4, version); + WRITE_16(header + 6, version); + WRITE_16(header + 8, gpflag); + WRITE_16(header + 10, method); + WRITE_16(header + 12, filetime); + WRITE_16(header + 14, filedate); + WRITE_32(header + 16, crc); + WRITE_32(header + 20, cpsize); + WRITE_32(header + 24, uncpsize); + WRITE_16(header + 28, fnsize); + WRITE_16(header + 30, extsize); + WRITE_16(header + 32, comsize); + WRITE_16(header + 34, 0); /* disk # */ + WRITE_16(header + 36, 0); /* int attrb */ + WRITE_32(header + 38, 0); /* ext attrb */ + WRITE_32(header + 42, currentOffset); + /* Header */ + if (fwrite(header, 1, 46, fpOutCD) == 46) { + offsetCD += 46; + + /* Filename */ + if (fnsize > 0) { + if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) { + offsetCD += fnsize; + } else { + err = Z_ERRNO; + break; + } + } else { + err = Z_STREAM_ERROR; + break; + } + + /* Extra field */ + if (extsize > 0) { + if (fwrite(extra, 1, extsize, fpOutCD) == extsize) { + offsetCD += extsize; + } else { + err = Z_ERRNO; + break; + } + } + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) { + offsetCD += comsize; + } else { + err = Z_ERRNO; + break; + } + } + + + } else { + err = Z_ERRNO; + break; + } + } + + /* Success */ + entries++; + + } else { + break; + } + } + + /* Final central directory */ + { + int entriesZip = entries; + char header[22]; + char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools"; + int comsize = (int) strlen(comment); + if (entriesZip > 0xffff) { + entriesZip = 0xffff; + } + WRITE_32(header, 0x06054b50); + WRITE_16(header + 4, 0); /* disk # */ + WRITE_16(header + 6, 0); /* disk # */ + WRITE_16(header + 8, entriesZip); /* hack */ + WRITE_16(header + 10, entriesZip); /* hack */ + WRITE_32(header + 12, offsetCD); /* size of CD */ + WRITE_32(header + 16, offset); /* offset to CD */ + WRITE_16(header + 20, comsize); /* comment */ + + /* Header */ + if (fwrite(header, 1, 22, fpOutCD) == 22) { + + /* Comment field */ + if (comsize > 0) { + if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) { + err = Z_ERRNO; + } + } + + } else { + err = Z_ERRNO; + } + } + + /* Final merge (file + central directory) */ + fclose(fpOutCD); + if (err == Z_OK) { + fpOutCD = fopen(fileOutTmp, "rb"); + if (fpOutCD != NULL) { + int nRead; + char buffer[8192]; + while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) { + if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) { + err = Z_ERRNO; + break; + } + } + fclose(fpOutCD); + } + } + + /* Close */ + fclose(fpZip); + fclose(fpOut); + + /* Wipe temporary file */ + (void)remove(fileOutTmp); + + /* Number of recovered entries */ + if (err == Z_OK) { + if (nRecovered != NULL) { + *nRecovered = entries; + } + if (bytesRecovered != NULL) { + *bytesRecovered = totalBytes; + } + } + } else { + err = Z_STREAM_ERROR; + } + return err; /* { dg-warning "leak of FILE 'fpZip'" "leak of fpZip" } */ + /* { dg-warning "leak of FILE 'fpOut'" "leak of fpOut" { target *-*-* } .-1 } */ + /* { dg-warning "leak of FILE 'fpOutCD'" "leak of fpOutCD" { target *-*-* } .-2 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95000-1.c b/gcc/testsuite/gcc.dg/analyzer/pr95000-1.c new file mode 100644 index 0000000..bb23ab7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/pr95000-1.c @@ -0,0 +1,38 @@ +#include "analyzer-decls.h" + +void test_1 (char* x) +{ + char* y=0; + switch (*x) { + case 'a': /* { dg-message "to here" } */ + y="foo"; + case 'b': + if (*x=='a') *y='b'; /* { dg-bogus "dereference of NULL 'y'" "deref of null (PR analyzer/95000)" { xfail *-*-* } } */ + /* { dg-warning "write to string literal" "write to string literal" { target *-*-* } .-1 } */ + } +} + +void test_switch_char(char x) { + switch (x) { + case 'b': + __analyzer_eval (x == 'b'); /* { dg-warning "TRUE" "expected" { xfail *-*-* } } */ + /* { dg-bogus "UNKNOWN" "status quo (PR analyzer/95000)" { xfail *-*-* } .-1 } */ + } +} + +void test_switch_int(int x) { + switch (x) { + case 97: + __analyzer_eval (x == 97); /* { dg-warning "TRUE" } */ + } +} + +void test_if_char(char x) { + if (x == 'b') + __analyzer_eval (x == 'b'); /* { dg-warning "TRUE" } */ +} + +void test_if_int(int x) { + if (x == 97) + __analyzer_eval (x == 97); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96639.c b/gcc/testsuite/gcc.dg/analyzer/pr96639.c index 02ca3f0..aedf046 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr96639.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr96639.c @@ -3,7 +3,7 @@ void *calloc (__SIZE_TYPE__, __SIZE_TYPE__); int x7 (void) { - int **md = calloc (1, 1); + int **md = calloc (1, sizeof (void *)); return md[0][0]; /* { dg-warning "possibly-NULL" "unchecked deref" } */ /* { dg-warning "leak of 'md'" "leak" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96713.c b/gcc/testsuite/gcc.dg/analyzer/pr96713.c index fe9cafd..12170bd 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr96713.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr96713.c @@ -1,3 +1,4 @@ +/* { dg-options "-Wno-psabi" } */ typedef int __attribute__ ((vector_size (8))) V; void diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c b/gcc/testsuite/gcc.dg/analyzer/pr96841.c index c766582..14f3f7a 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr96841.c @@ -1,4 +1,4 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex -O1 -Wno-builtin-declaration-mismatch" } */ +/* { dg-additional-options "-O1 -Wno-builtin-declaration-mismatch" } */ int l8 (void); diff --git a/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c b/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c index 0422147..c3b7186 100644 --- a/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c @@ -13,3 +13,32 @@ int test_1 (void) called_by_test_1 (); return *global_ptr; /* { dg-warning "dereferencing pointer 'global_ptr' to within stale stack frame" } */ } + +static void __attribute__((noinline)) +called_by_test_2 (int **out) +{ + int i = 42; + *out = &i; +} + +int test_2 (void) +{ + int *ptr; + called_by_test_2 (&ptr); + return *ptr; /* { dg-warning "dereferencing pointer 'ptr' to within stale stack frame" } */ +} + +static int __attribute__((noinline)) +called_by_test_3 (int **out) +{ + int i = 42; + *out = &i; + return i; +} + +int test_3 (void) +{ + int *lhs_ptr; + *lhs_ptr = called_by_test_3 (&lhs_ptr); /* { dg-warning "use of uninitialized value 'lhs_ptr'" } */ + return *lhs_ptr; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-1.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-1.c new file mode 100644 index 0000000..f23d28c5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-1.c @@ -0,0 +1,433 @@ +#include "analyzer-decls.h" + +/* Unpacking a va_list. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_1 (int placeholder, ...) +{ + const char *s; + int i; + char c; + + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + s = __builtin_va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = __builtin_va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + c = (char)__builtin_va_arg (ap, int); + __analyzer_eval (c == '@'); /* { dg-warning "TRUE" } */ + + __builtin_va_end (ap); +} + +void test_1 (void) +{ + __analyzer_called_by_test_1 (42, "foo", 1066, '@'); +} + +/* Unpacking a va_list passed from an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_2_inner (__builtin_va_list ap) +{ + const char *s; + int i; + char c; + + s = __builtin_va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = __builtin_va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + c = (char)__builtin_va_arg (ap, int); + __analyzer_eval (c == '@'); /* { dg-warning "TRUE" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_2_middle (int placeholder, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + __analyzer_test_2_inner (ap); + __builtin_va_end (ap); +} + +void test_2 (void) +{ + __analyzer_test_2_middle (42, "foo", 1066, '@'); +} + +/* Not enough args. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_not_enough_args (int placeholder, ...) +{ + const char *s; + int i; + + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + s = __builtin_va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = __builtin_va_arg (ap, int); /* { dg-warning "'ap' has no more arguments \\(1 consumed\\) \\\[CWE-685\\\]" } */ + + __builtin_va_end (ap); +} + +void test_not_enough_args (void) +{ + __analyzer_called_by_test_not_enough_args (42, "foo"); +} + +/* Not enough args, with an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_not_enough_args_2_inner (__builtin_va_list ap) +{ + const char *s; + int i; + + s = __builtin_va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = __builtin_va_arg (ap, int); /* { dg-warning "'ap' has no more arguments \\(1 consumed\\)" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_not_enough_args_2_middle (int placeholder, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + __analyzer_test_not_enough_args_2_inner (ap); + __builtin_va_end (ap); +} + +void test_not_enough_args_2 (void) +{ + __analyzer_test_not_enough_args_2_middle (42, "foo"); +} + +/* Excess args (not a problem). */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_excess_args (int placeholder, ...) +{ + const char *s; + + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + s = __builtin_va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + __builtin_va_end (ap); +} + +void test_excess_args (void) +{ + __analyzer_called_by_test_excess_args (42, "foo", "bar"); +} + +/* Missing va_start. */ + +void test_missing_va_start (int placeholder, ...) +{ + __builtin_va_list ap; /* { dg-message "region created on stack here" } */ + int i = __builtin_va_arg (ap, int); /* { dg-warning "use of uninitialized value 'ap'" } */ +} + +/* Missing va_end. */ + +void test_missing_va_end (int placeholder, ...) +{ + int i; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); /* { dg-message "\\(1\\) 'va_start' called here" } */ + i = __builtin_va_arg (ap, int); +} /* { dg-warning "missing call to 'va_end'" "warning" } */ +/* { dg-message "\\(2\\) missing call to 'va_end' to match 'va_start' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + +/* Missing va_end due to error-handling. */ + +int test_missing_va_end_2 (int placeholder, ...) +{ + int i, j; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); /* { dg-message "\\(1\\) 'va_start' called here" } */ + i = __builtin_va_arg (ap, int); + if (i == 42) + { + __builtin_va_end (ap); + return -1; + } + j = __builtin_va_arg (ap, int); + if (j == 1066) /* { dg-message "branch" } */ + return -1; /* { dg-message "here" } */ + __builtin_va_end (ap); + return 0; +} /* { dg-warning "missing call to 'va_end'" "warning" } */ + +/* va_arg after va_end. */ + +void test_va_arg_after_va_end (int placeholder, ...) +{ + int i; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + __builtin_va_end (ap); /* { dg-message "'va_end' called here" } */ + i = __builtin_va_arg (ap, int); /* { dg-warning "'va_arg' after 'va_end'" } */ +} + +/* Type mismatch: expect int, but passed a char *. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_type_mismatch_1 (int placeholder, ...) +{ + int i; + + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + i = __builtin_va_arg (ap, int); /* { dg-warning "'va_arg' expected 'int' but received '\[^\n\r\]*' for variadic argument 1 of 'ap' \\\[CWE-686\\\]" } */ + + __builtin_va_end (ap); +} + +void test_type_mismatch_1 (void) +{ + __analyzer_called_by_test_type_mismatch_1 (42, "foo"); +} + +/* Type mismatch: expect char *, but passed an int. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_type_mismatch_2 (int placeholder, ...) +{ + const char *str; + + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + str = __builtin_va_arg (ap, const char *); /* { dg-warning "'va_arg' expected 'const char \\*' but received 'int' for variadic argument 1" } */ + + __builtin_va_end (ap); +} + +void test_type_mismatch_2 (void) +{ + __analyzer_called_by_test_type_mismatch_2 (42, 1066); +} + +/* As above, but with an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_type_mismatch_3_inner (__builtin_va_list ap) +{ + const char *str; + + str = __builtin_va_arg (ap, const char *); /* { dg-warning "'va_arg' expected 'const char \\*' but received 'int' for variadic argument 1 of 'ap'" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_type_mismatch_3_middle (int placeholder, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + + __analyzer_test_type_mismatch_3_inner (ap); + + __builtin_va_end (ap); +} + +void test_type_mismatch_3 (void) +{ + __analyzer_test_type_mismatch_3_middle (42, 1066); +} + +/* Multiple traversals of the args. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals (int placeholder, ...) +{ + __builtin_va_list ap; + + /* First traversal. */ + { + int i, j; + + __builtin_va_start (ap, placeholder); + + i = __builtin_va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + j = __builtin_va_arg (ap, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + + __builtin_va_end (ap); + } + + /* Second traversal. */ + { + int i, j; + + __builtin_va_start (ap, placeholder); + + i = __builtin_va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + j = __builtin_va_arg (ap, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + + __builtin_va_end (ap); + } +} + +void test_multiple_traversals (void) +{ + __analyzer_called_by_test_multiple_traversals (0, 1066, 42); +} + +/* Multiple traversals, using va_copy. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals_2 (int placeholder, ...) +{ + int i, j; + __builtin_va_list args1; + __builtin_va_list args2; + + __builtin_va_start (args1, placeholder); + __builtin_va_copy (args2, args1); + + /* First traversal. */ + i = __builtin_va_arg (args1, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + j = __builtin_va_arg (args1, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + __builtin_va_end (args1); + + /* Traversal of copy. */ + i = __builtin_va_arg (args2, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + j = __builtin_va_arg (args2, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + __builtin_va_end (args2); +} + +void test_multiple_traversals_2 (void) +{ + __analyzer_called_by_test_multiple_traversals_2 (0, 1066, 42); +} + +/* Multiple traversals, using va_copy after a va_arg. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals_3 (int placeholder, ...) +{ + int i, j; + __builtin_va_list args1; + __builtin_va_list args2; + + __builtin_va_start (args1, placeholder); + + /* First traversal. */ + i = __builtin_va_arg (args1, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + /* va_copy after the first va_arg. */ + __builtin_va_copy (args2, args1); + + j = __builtin_va_arg (args1, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + __builtin_va_end (args1); + + /* Traversal of copy. */ + j = __builtin_va_arg (args2, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + __builtin_va_end (args2); +} + +void test_multiple_traversals_3 (void) +{ + __analyzer_called_by_test_multiple_traversals_3 (0, 1066, 42); +} + +/* va_copy after va_end. */ + +void test_va_copy_after_va_end (int placeholder, ...) +{ + __builtin_va_list ap1, ap2; + __builtin_va_start (ap1, placeholder); + __builtin_va_end (ap1); /* { dg-message "'va_end' called here" } */ + __builtin_va_copy (ap2, ap1); /* { dg-warning "'va_copy' after 'va_end'" } */ + __builtin_va_end (ap2); +} + +/* leak of va_copy. */ + +void test_leak_of_va_copy (int placeholder, ...) +{ + __builtin_va_list ap1, ap2; + __builtin_va_start (ap1, placeholder); + __builtin_va_copy (ap2, ap1); /* { dg-message "'va_copy' called here" } */ + __builtin_va_end (ap1); +} /* { dg-warning "missing call to 'va_end'" "warning" } */ + /* { dg-message "missing call to 'va_end' to match 'va_copy' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + +/* double va_end. */ + +void test_double_va_end (int placeholder, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + __builtin_va_end (ap); /* { dg-message "'va_end' called here" } */ + __builtin_va_end (ap); /* { dg-warning "'va_end' after 'va_end'" } */ +} + +/* double va_start. */ + +void test_double_va_start (int placeholder, ...) +{ + int i; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); /* { dg-message "'va_start' called here" } */ + __builtin_va_start (ap, placeholder); /* { dg-warning "missing call to 'va_end'" "warning" } */ + /* { dg-message "missing call to 'va_end' to match 'va_start' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + __builtin_va_end (ap); +} + +/* va_copy before va_start. */ + +void test_va_copy_before_va_start (int placeholder, ...) +{ + __builtin_va_list ap1; /* { dg-message "region created on stack here" } */ + __builtin_va_list ap2; + __builtin_va_copy (ap2, ap1); /* { dg-warning "use of uninitialized value 'ap1'" } */ + __builtin_va_end (ap2); +} + +/* Verify that we complain about uses of a va_list after the function + in which va_start was called has returned. */ + +__builtin_va_list global_ap; + +static void __attribute__((noinline)) +__analyzer_called_by_test_va_arg_after_return (int placeholder, ...) +{ + __builtin_va_start (global_ap, placeholder); + __builtin_va_end (global_ap); +} + +void test_va_arg_after_return (void) +{ + int i; + __analyzer_called_by_test_va_arg_after_return (42, 1066); + i = __builtin_va_arg (global_ap, int); /* { dg-warning "dereferencing pointer 'global_ap' to within stale stack frame" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-2.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-2.c new file mode 100644 index 0000000..69a2acb --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-2.c @@ -0,0 +1,436 @@ +/* As per stdarg-1.c, but using <stdarg.h>, rather than hardcoded builtins. */ + +#include <stdarg.h> +#include "analyzer-decls.h" + +/* Unpacking a va_list. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_1 (int placeholder, ...) +{ + const char *s; + int i; + char c; + + va_list ap; + va_start (ap, placeholder); + + s = va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + c = (char)va_arg (ap, int); + __analyzer_eval (c == '@'); /* { dg-warning "TRUE" } */ + + va_end (ap); +} + +void test_1 (void) +{ + __analyzer_called_by_test_1 (42, "foo", 1066, '@'); +} + +/* Unpacking a va_list passed from an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_2_inner (va_list ap) +{ + const char *s; + int i; + char c; + + s = va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + c = (char)va_arg (ap, int); + __analyzer_eval (c == '@'); /* { dg-warning "TRUE" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_2_middle (int placeholder, ...) +{ + va_list ap; + va_start (ap, placeholder); + __analyzer_test_2_inner (ap); + va_end (ap); +} + +void test_2 (void) +{ + __analyzer_test_2_middle (42, "foo", 1066, '@'); +} + +/* Not enough args. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_not_enough_args (int placeholder, ...) +{ + const char *s; + int i; + + va_list ap; + va_start (ap, placeholder); + + s = va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = va_arg (ap, int); /* { dg-warning "'ap' has no more arguments \\(1 consumed\\)" } */ + + va_end (ap); +} + +void test_not_enough_args (void) +{ + __analyzer_called_by_test_not_enough_args (42, "foo"); +} + +/* Not enough args, with an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_not_enough_args_2_inner (va_list ap) +{ + const char *s; + int i; + + s = va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + i = va_arg (ap, int); /* { dg-warning "'ap' has no more arguments \\(1 consumed\\)" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_not_enough_args_2_middle (int placeholder, ...) +{ + va_list ap; + va_start (ap, placeholder); + __analyzer_test_not_enough_args_2_inner (ap); + va_end (ap); +} + +void test_not_enough_args_2 (void) +{ + __analyzer_test_not_enough_args_2_middle (42, "foo"); +} + +/* Excess args (not a problem). */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_excess_args (int placeholder, ...) +{ + const char *s; + + va_list ap; + va_start (ap, placeholder); + + s = va_arg (ap, char *); + __analyzer_eval (s[0] == 'f'); /* { dg-warning "TRUE" } */ + + va_end (ap); +} + +void test_excess_args (void) +{ + __analyzer_called_by_test_excess_args (42, "foo", "bar"); +} + +/* Missing va_start. */ + +void test_missing_va_start (int placeholder, ...) +{ + va_list ap; /* { dg-message "region created on stack here" } */ + int i = va_arg (ap, int); /* { dg-warning "use of uninitialized value 'ap'" } */ +} + +/* Missing va_end. */ + +void test_missing_va_end (int placeholder, ...) +{ + int i; + va_list ap; + va_start (ap, placeholder); /* { dg-message "\\(1\\) 'va_start' called here" } */ + i = va_arg (ap, int); +} /* { dg-warning "missing call to 'va_end'" "warning" } */ +/* { dg-message "\\(2\\) missing call to 'va_end' to match 'va_start' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + +/* Missing va_end due to error-handling. */ + +int test_missing_va_end_2 (int placeholder, ...) +{ + int i, j; + va_list ap; + va_start (ap, placeholder); /* { dg-message "\\(1\\) 'va_start' called here" } */ + i = va_arg (ap, int); + if (i == 42) + { + va_end (ap); + return -1; + } + j = va_arg (ap, int); + if (j == 1066) /* { dg-message "branch" } */ + return -1; /* { dg-message "here" } */ + va_end (ap); + return 0; +} /* { dg-warning "missing call to 'va_end'" "warning" } */ + +/* va_arg after va_end. */ + +void test_va_arg_after_va_end (int placeholder, ...) +{ + int i; + va_list ap; + va_start (ap, placeholder); + va_end (ap); /* { dg-message "'va_end' called here" } */ + i = va_arg (ap, int); /* { dg-warning "'va_arg' after 'va_end'" } */ +} + +/* Type mismatch: expect int, but passed a char *. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_type_mismatch_1 (int placeholder, ...) +{ + int i; + + va_list ap; + va_start (ap, placeholder); + + i = va_arg (ap, int); /* { dg-warning "'va_arg' expected 'int' but received '\[^\n\r\]*' for variadic argument 1 of 'ap'" } */ + + va_end (ap); +} + +void test_type_mismatch_1 (void) +{ + __analyzer_called_by_test_type_mismatch_1 (42, "foo"); +} + +/* Type mismatch: expect char *, but passed an int. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_type_mismatch_2 (int placeholder, ...) +{ + const char *str; + + va_list ap; + va_start (ap, placeholder); + + str = va_arg (ap, const char *); /* { dg-warning "'va_arg' expected 'const char \\*' but received 'int' for variadic argument 1 of 'ap'" } */ + + va_end (ap); +} + +void test_type_mismatch_2 (void) +{ + __analyzer_called_by_test_type_mismatch_2 (42, 1066); +} + +/* As above, but with an intermediate function. */ + +static void __attribute__((noinline)) +__analyzer_test_type_mismatch_3_inner (va_list ap) +{ + const char *str; + + str = va_arg (ap, const char *); /* { dg-warning "'va_arg' expected 'const char \\*' but received 'int' for variadic argument 1 of 'ap'" } */ +} + +static void __attribute__((noinline)) +__analyzer_test_type_mismatch_3_middle (int placeholder, ...) +{ + va_list ap; + va_start (ap, placeholder); + + __analyzer_test_type_mismatch_3_inner (ap); + + va_end (ap); +} + +void test_type_mismatch_3 (void) +{ + __analyzer_test_type_mismatch_3_middle (42, 1066); +} + +/* Multiple traversals of the args. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals (int placeholder, ...) +{ + va_list ap; + + /* First traversal. */ + { + int i, j; + + va_start (ap, placeholder); + + i = va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + j = va_arg (ap, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + + va_end (ap); + } + + /* Second traversal. */ + { + int i, j; + + va_start (ap, placeholder); + + i = va_arg (ap, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + j = va_arg (ap, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + + va_end (ap); + } +} + +void test_multiple_traversals (void) +{ + __analyzer_called_by_test_multiple_traversals (0, 1066, 42); +} + +/* Multiple traversals, using va_copy. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals_2 (int placeholder, ...) +{ + int i, j; + va_list args1; + va_list args2; + + va_start (args1, placeholder); + va_copy (args2, args1); + + /* First traversal. */ + i = va_arg (args1, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + j = va_arg (args1, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + va_end (args1); + + /* Traversal of copy. */ + i = va_arg (args2, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + j = va_arg (args2, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + va_end (args2); +} + +void test_multiple_traversals_2 (void) +{ + __analyzer_called_by_test_multiple_traversals_2 (0, 1066, 42); +} + +/* Multiple traversals, using va_copy after a va_arg. */ + +static void __attribute__((noinline)) +__analyzer_called_by_test_multiple_traversals_3 (int placeholder, ...) +{ + int i, j; + va_list args1; + va_list args2; + + va_start (args1, placeholder); + + /* First traversal. */ + i = va_arg (args1, int); + __analyzer_eval (i == 1066); /* { dg-warning "TRUE" } */ + + /* va_copy after the first va_arg. */ + va_copy (args2, args1); + + j = va_arg (args1, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + va_end (args1); + + /* Traversal of copy. */ + j = va_arg (args2, int); + __analyzer_eval (j == 42); /* { dg-warning "TRUE" } */ + va_end (args2); +} + +void test_multiple_traversals_3 (void) +{ + __analyzer_called_by_test_multiple_traversals_3 (0, 1066, 42); +} + +/* va_copy after va_end. */ + +void test_va_copy_after_va_end (int placeholder, ...) +{ + va_list ap1, ap2; + va_start (ap1, placeholder); + va_end (ap1); /* { dg-message "'va_end' called here" } */ + va_copy (ap2, ap1); /* { dg-warning "'va_copy' after 'va_end'" } */ + va_end (ap2); +} + +/* leak of va_copy. */ + +void test_leak_of_va_copy (int placeholder, ...) +{ + va_list ap1, ap2; + va_start (ap1, placeholder); + va_copy (ap2, ap1); /* { dg-message "'va_copy' called here" } */ + va_end (ap1); +} /* { dg-warning "missing call to 'va_end'" "warning" } */ + /* { dg-message "missing call to 'va_end' to match 'va_copy' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + +/* double va_end. */ + +void test_double_va_end (int placeholder, ...) +{ + va_list ap; + va_start (ap, placeholder); + va_end (ap); /* { dg-message "'va_end' called here" } */ + va_end (ap); /* { dg-warning "'va_end' after 'va_end'" } */ +} + +/* double va_start. */ + +void test_double_va_start (int placeholder, ...) +{ + int i; + va_list ap; + va_start (ap, placeholder); /* { dg-message "'va_start' called here" } */ + va_start (ap, placeholder); /* { dg-warning "missing call to 'va_end'" "warning" } */ + /* { dg-message "missing call to 'va_end' to match 'va_start' at \\(1\\)" "final event" { target *-*-* } .-1 } */ + va_end (ap); +} + +/* va_copy before va_start. */ + +void test_va_copy_before_va_start (int placeholder, ...) +{ + va_list ap1; /* { dg-message "region created on stack here" } */ + va_list ap2; + va_copy (ap2, ap1); /* { dg-warning "use of uninitialized value 'ap1'" } */ + va_end (ap2); +} + +/* Verify that we complain about uses of a va_list after the function + in which va_start was called has returned. */ + +va_list global_ap; + +static void __attribute__((noinline)) +__analyzer_called_by_test_va_arg_after_return (int placeholder, ...) +{ + va_start (global_ap, placeholder); + va_end (global_ap); +} + +void test_va_arg_after_return (void) +{ + int i; + __analyzer_called_by_test_va_arg_after_return (42, 1066); + i = va_arg (global_ap, int); /* { dg-warning "dereferencing pointer 'global_ap' to within stale stack frame" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-3.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-3.c new file mode 100644 index 0000000..6814614 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-3.c @@ -0,0 +1,57 @@ +typedef __builtin_va_list va_list; + +struct printf_spec { + unsigned int type; +}; + +int +format_decode(const char *fmt, struct printf_spec *spec); + +static int vbin_printf(const char *fmt, va_list args) { + struct printf_spec spec; + int width = 0; + + while (*fmt) { + int read = format_decode(fmt, &spec); + + fmt += read; + + switch (spec.type) { + case 0: + break; + case 1: + width = __builtin_va_arg(args, int); /* { dg-bogus "-Wanalyzer-va-list-exhausted" } */ + break; + } + } + + return width; +} + +int bprintf(const char *fmt, ...) { + va_list args; + int ret; + + __builtin_va_start(args, fmt); + ret = vbin_printf(fmt, args); + __builtin_va_end(args); + + return ret; +} + +static int called_by_test_2 (va_list args) +{ + return __builtin_va_arg(args, int); /* { dg-bogus "-Wanalyzer-va-list-exhausted" } */ +} + +int test_2 (const char *fmt, ...) +{ + va_list args; + int ret; + + __builtin_va_start (args, fmt); + ret = called_by_test_2 (args); + __builtin_va_end (args); + + return ret; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-fmtstring-1.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-fmtstring-1.c new file mode 100644 index 0000000..3892c3c --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-fmtstring-1.c @@ -0,0 +1,103 @@ +/* { dg-additional-options "-fno-analyzer-call-summaries -fno-analyzer-state-merge -Wno-analyzer-too-complex" } */ + +void test_format_string (const char *fmt, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, fmt); + while (*fmt) + switch (*fmt++) + { + case 's': + { + const char *s = __builtin_va_arg (ap, char *); /* { dg-warning "'va_arg' expected 'const char \\*' but received 'int' for variadic argument 1 of 'ap'" } */ + __builtin_printf ("string: %s\n", s); + } + break; + case 'd': + { + int i = __builtin_va_arg (ap, int); /* { dg-warning "'va_arg' expected 'int' but received '\[^\n\r\]*' for variadic argument 1 of 'ap'" "type mismatch from wrong_type_for_percent_d" } */ + /* { dg-warning "'ap' has no more arguments \\(1 consumed\\)" "not_enough_args" { target *-*-* } .-1 } */ + __builtin_printf ("int: %d\n", i); + } + break; + case 'c': + { + char c = (char)__builtin_va_arg (ap, int); + __builtin_printf ("char: %c\n", c); + } + break; + } + __builtin_va_end (ap); +} + +void test_missing_va_start (const char *fmt, ...) +{ + __builtin_va_list ap; + + while (*fmt) + switch (*fmt++) + { + case 's': + { + const char *s = __builtin_va_arg (ap, char *); /* { dg-warning "use of uninitialized value 'ap'" } */ + __builtin_printf ("string: %s\n", s); + } + break; + case 'd': + { + int i = __builtin_va_arg (ap, int); /* { dg-warning "use of uninitialized value 'ap'" } */ + __builtin_printf ("int: %d\n", i); + } + break; + case 'c': + { + char c = (char)__builtin_va_arg (ap, int); /* { dg-warning "use of uninitialized value 'ap'" } */ + __builtin_printf ("char: %c\n", c); + } + break; + } + __builtin_va_end (ap); +} + +void test_missing_va_end (const char *fmt, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, fmt); + while (*fmt) + switch (*fmt++) + { + case 's': + { + const char *s = __builtin_va_arg (ap, char *); + __builtin_printf ("string: %s\n", s); + } + break; + case 'd': + { + int i = __builtin_va_arg (ap, int); + __builtin_printf ("int: %d\n", i); + } + break; + case 'c': + { + char c = (char)__builtin_va_arg (ap, int); + __builtin_printf ("char: %c\n", c); + } + break; + } +} /* { dg-warning "missing call to 'va_end'" } */ + +void wrong_type_for_percent_s (void) +{ + test_format_string ("%s", 42); +} + +void wrong_type_for_percent_d (void) +{ + test_format_string ("%d", "foo"); +} + +void not_enough_args (void) +{ + test_format_string ("%s%d", "foo"); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-a.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-a.c new file mode 100644 index 0000000..f56ad88 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-a.c @@ -0,0 +1,24 @@ +/* { dg-do link } */ +/* { dg-require-effective-target lto } */ +/* { dg-additional-options "-flto" } */ +/* { dg-additional-sources stdarg-lto-1-b.c } */ + +#include <stdarg.h> +#include "stdarg-lto-1.h" + +/* Type mismatch: expect const char *, but passed an int. */ + +void +called_by_test_type_mismatch_1 (int placeholder, ...) +{ + const char *str; + + va_list ap; + va_start (ap, placeholder); + + str = va_arg (ap, const char *); /* { dg-warning "'va_arg' expected '\[^\n\r\]*' but received 'int' for variadic argument 1 of 'ap'" } */ + + va_end (ap); +} + +int main() { return 0; } diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-b.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-b.c new file mode 100644 index 0000000..edd51f0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1-b.c @@ -0,0 +1,6 @@ +#include "stdarg-lto-1.h" + +void test_type_mismatch_1 (void) +{ + called_by_test_type_mismatch_1 (42, 1066); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1.h b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1.h new file mode 100644 index 0000000..6983574 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-lto-1.h @@ -0,0 +1 @@ +extern void called_by_test_type_mismatch_1 (int placeholder, ...); diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-sentinel-1.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-sentinel-1.c new file mode 100644 index 0000000..f8c1f0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-sentinel-1.c @@ -0,0 +1,25 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#define NULL ((void *)0) + +void test_sentinel (int arg, ...) +{ + const char *s; + __builtin_va_list ap; + __builtin_va_start (ap, arg); + while (s = __builtin_va_arg (ap, char *)) /* { dg-warning "'ap' has no more arguments \\(2 consumed\\)" } */ + { + (void)s; + } + __builtin_va_end (ap); +} + +void test_caller (void) +{ + test_sentinel (42, "foo", "bar", NULL); +} + +void missing_sentinel (void) +{ + test_sentinel (42, "foo", "bar"); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-types-1.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-1.c new file mode 100644 index 0000000..dcea87e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-1.c @@ -0,0 +1,25 @@ +/* { dg-require-effective-target int32 } */ +/* { dg-require-effective-target lp64 } */ + +/* Type mismatch: expect long, but passed an int. */ + +static void __attribute__((noinline)) +__analyzer_consume_long (int placeholder, ...) +{ + long v; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + v = __builtin_va_arg (ap, long); /* { dg-warning "'va_arg' expected 'long int' but received 'int' for variadic argument 1 of 'ap'" } */ + __builtin_va_end (ap); +} + +void test_int_to_long (void) +{ + __analyzer_consume_long (42, 1066); +} + +void test_char_to_long (void) +{ + /* char promoted to int. */ + __analyzer_consume_long (42, 'a'); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-types-2.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-2.c new file mode 100644 index 0000000..39d5c6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-2.c @@ -0,0 +1,55 @@ +/* Should be OK to add a "const" qualifier to a ptr. */ + +static void __attribute__((noinline)) +__analyzer_consume_const_char_ptr (int placeholder, ...) +{ + const char *v; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + v = __builtin_va_arg (ap, const char *); + __builtin_va_end (ap); +} + +void test_char_ptr_to_const_char_ptr (char *p) +{ + __analyzer_consume_const_char_ptr (42, p); /* { dg-bogus "" } */ +} + +/* What about casting away const-ness? + Currently we don't complain. */ + +static void __attribute__((noinline)) +__analyzer_consume_char_ptr (int placeholder, ...) +{ + char *v; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + v = __builtin_va_arg (ap, char *); + __builtin_va_end (ap); +} + +void test_const_char_ptr_to_char_ptr (const char *p) +{ + __analyzer_consume_const_char_ptr (42, p); +} + +/* What about casting ptrs? + Currently we don't complain. */ + +struct foo; +struct bar; + +static void __attribute__((noinline)) +__analyzer_consume_bar_ptr (int placeholder, ...) +{ + struct bar *v; + __builtin_va_list ap; + __builtin_va_start (ap, placeholder); + v = __builtin_va_arg (ap, struct bar *); + __builtin_va_end (ap); +} + +void test_foo_ptr_to_bar_ptr (struct foo *p) +{ + __analyzer_consume_bar_ptr (42, p); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-types-3.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-3.c new file mode 100644 index 0000000..7351261 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-3.c @@ -0,0 +1,67 @@ +static void __attribute__((noinline)) +__analyzer_consume_n_ints (int num, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, num); + + int i, v; + for (i = 0; i < num; i++) + v = __builtin_va_arg (ap, int); + + __builtin_va_end (ap); +} + +void test_int (int x) +{ + __analyzer_consume_n_ints (1, x); +} + +void test_3_ints (int x, int y, int z) +{ + __analyzer_consume_n_ints (3, x, y, z); +} + +/* Verify that we don't complain about types that get promoted to int + at the variadic call. */ + +void test_short (short s) +{ + __analyzer_consume_n_ints (1, s); +} + +void test_ushort (unsigned short s) +{ + __analyzer_consume_n_ints (1, s); +} + +void test_schar (signed char ch) +{ + __analyzer_consume_n_ints (1, ch); +} + +void test_uchar (unsigned char ch) +{ + __analyzer_consume_n_ints (1, ch); +} + +struct ust +{ + int b0123 : 4; + int b4567 : 4; +}; + +void test_signed_bitfield (struct ust s) +{ + __analyzer_consume_n_ints (2, s.b0123, s.b4567); +} + +struct sst +{ + unsigned int b0123 : 4; + unsigned int b4567 : 4; +}; + +void test_unsigned_bitfield (struct sst s) +{ + __analyzer_consume_n_ints (2, s.b0123, s.b4567); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/stdarg-types-4.c b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-4.c new file mode 100644 index 0000000..920ecce --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/stdarg-types-4.c @@ -0,0 +1,22 @@ +static void __attribute__((noinline)) +__analyzer_consume_n_uints (int num, ...) +{ + __builtin_va_list ap; + __builtin_va_start (ap, num); + + int i, v; + for (i = 0; i < num; i++) + v = __builtin_va_arg (ap, unsigned int); + + __builtin_va_end (ap); +} + +void test_uint (unsigned int x) +{ + __analyzer_consume_n_uints (1, x); +} + +void test_3_uints (unsigned int x, unsigned int y, unsigned int z) +{ + __analyzer_consume_n_uints (3, x, y, z); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/strcpy-2.c b/gcc/testsuite/gcc.dg/analyzer/strcpy-2.c new file mode 100644 index 0000000..e4e6c97 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/strcpy-2.c @@ -0,0 +1,27 @@ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +#include "analyzer-decls.h" + +struct S +{ + char buf[10]; +}; + +/* strcpy to a static struct that never gets used. */ + +void +test_1 (const char *src) +{ + static struct S s; /* { dg-warning "track 's': no" } */ + __builtin_strcpy (s.buf, src); +} + +/* strcpy to a static struct that later gets used. */ + +const char * +test_2 (const char *src) +{ + static struct S s; /* { dg-warning "track 's': yes" } */ + __builtin_strcpy (s.buf, src); + return s.buf; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c index edf494a..8cf7a42 100644 --- a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c @@ -1,4 +1,5 @@ -/* { dg-skip-if "no strndup in libc" { *-*-darwin[789]* *-*-darwin10* *-*-mingw* } } */ +/* { dg-skip-if "no strndup in libc" { *-*-darwin[789]* *-*-darwin10* *-*-mingw* *-*-vxworks* } } */ + #include <string.h> #include <stdlib.h> diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c new file mode 100644 index 0000000..d7c50de --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c @@ -0,0 +1,106 @@ +#include "analyzer-decls.h" + +void external_fn(void); + +struct st_1 +{ + char *name; + unsigned size; +}; + +void test_1a (void *p, unsigned next_off) +{ + struct st_1 *r = p; + + external_fn(); + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1b (void *p, unsigned next_off) +{ + struct st_1 *r = p; + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1c (struct st_1 *r, unsigned next_off) +{ + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1d (struct st_1 *r, unsigned next_off) +{ + external_fn(); + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1e (void *p, unsigned next_off) +{ + struct st_1 *r = p; + + while (1) + { + external_fn(); + + if (next_off >= r->size) + return; + + __analyzer_dump_path (); /* { dg-message "path" } */ + } +} + +struct st_2 +{ + char *name; + unsigned arr[10]; +}; + +void test_2a (void *p, unsigned next_off) +{ + struct st_2 *r = p; + + external_fn(); + + if (next_off >= r->arr[5]) + return; + + if (next_off >= r->arr[5]) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_2b (void *p, unsigned next_off, int idx) +{ + struct st_2 *r = p; + + external_fn(); + + if (next_off >= r->arr[idx]) + return; + + if (next_off >= r->arr[idx]) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-9.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-9.c new file mode 100644 index 0000000..54ed30f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-9.c @@ -0,0 +1,197 @@ +#include "analyzer-decls.h" + +struct st +{ + void *ptr[10]; + int arr[10]; +}; + +/* Various combinations of a pair of writes, involving + symbolic vs concrete clusters, with symbolic vs concrete keys + within them. */ + +struct st g; + +/* "ptr" write: fully concrete. */ + +struct st +test_conc_conc_ptr_conc_conc_arr (void) +{ + struct st s; + s.ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + s.arr[5] = 42; + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + __analyzer_describe (0, s.arr[5]); /* { dg-warning "42" } */ + return s; +} + +struct st +test_conc_conc_ptr_conc_sym_arr (int j) +{ + struct st s; + s.ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + s.arr[j] = 42; + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, s.arr[j]); /* { dg-warning "42" } */ + return s; +} + +struct st +test_conc_conc_ptr_sym_conc_arr (struct st *p) +{ + struct st s; + s.ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + p->arr[5] = 42; + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + __analyzer_describe (0, p->arr[5]); /* { dg-warning "42" } */ + return s; +} + +struct st +test_conc_conc_ptr_sym_sym_arr (struct st *p, int j) +{ + struct st s; + s.ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + p->arr[j] = 42; + __analyzer_describe (0, s.ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + __analyzer_describe (0, p->arr[j]); /* { dg-warning "42" } */ + return s; +} + +/* "ptr" write: symbolic region, but at concrete offset. */ + +void +test_sym_conc_ptr_conc_conc_arr (struct st *p) +{ + p->ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + g.arr[5] = 42; + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, g.arr[5]); /* { dg-warning "42" } */ +} + +void +test_sym_conc_ptr_conc_sym_arr (struct st *p, int j) +{ + p->ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + g.arr[j] = 42; + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, g.arr[j]); /* { dg-warning "42" } */ +} + +void +test_sym_conc_ptr_sym_conc_arr (struct st *p, struct st *q) +{ + p->ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + q->arr[5] = 42; + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, q->arr[5]); /* { dg-warning "42" } */ +} + +void +test_sym_conc_ptr_sym_sym_arr (struct st *p, struct st *q, int j) +{ + p->ptr[1] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + q->arr[j] = 42; + __analyzer_describe (0, p->ptr[1]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, q->arr[j]); /* { dg-warning "42" } */ +} + +/* "ptr" write: concrete region, but at symbolic offset. */ + +struct st +test_conc_sym_ptr_conc_conc_arr (int i) +{ + struct st s; + s.ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + s.arr[5] = 42; + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, s.arr[5]); /* { dg-warning "42" } */ + return s; +} + +struct st +test_conc_sym_ptr_conc_sym_arr (int i, int j) +{ + struct st s; + s.ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + s.arr[j] = 42; + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, s.arr[j]); /* { dg-warning "42" } */ + return s; +} + +struct st +test_conc_sym_ptr_sym_conc_arr (int i, struct st *p) +{ + struct st s; + s.ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + p->arr[5] = 42; + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + __analyzer_describe (0, p->arr[5]); /* { dg-warning "42" } */ + return s; +} /* { dg-bogus "leak" "PR analyzer/105190" { xfail *-*-* } } */ + +struct st +test_conc_sym_ptr_sym_sym_arr (int i, struct st *p, int j) +{ + struct st s; + s.ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + p->arr[j] = 42; + __analyzer_describe (0, s.ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + __analyzer_describe (0, p->arr[j]); /* { dg-warning "42" } */ + return s; +} /* { dg-bogus "leak" "PR analyzer/105190" { xfail *-*-* } } */ + +/* "ptr" write: symbolic region, with symbolic offset. */ + +void +test_sym_sym_ptr_conc_conc_arr (struct st *p, int i) +{ + p->ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + g.arr[5] = 42; + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, g.arr[5]); /* { dg-warning "42" } */ +} + +void +test_sym_sym_ptr_conc_sym_arr (struct st *p, int i, int j) +{ + p->ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + g.arr[j] = 42; + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, g.arr[j]); /* { dg-warning "42" } */ +} + +void +test_sym_sym_ptr_sym_conc_arr (struct st *p, int i, struct st *q) +{ + p->ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + q->arr[5] = 42; + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, q->arr[5]); /* { dg-warning "42" } */ +} + +void +test_sym_sym_ptr_sym_sym_arr (struct st *p, int i, struct st *q, int j) +{ + p->ptr[i] = __builtin_malloc (1024); + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "HEAP_ALLOCATED_REGION" } */ + q->arr[j] = 42; + __analyzer_describe (0, p->ptr[i]); /* { dg-warning "UNKNOWN" } */ + __analyzer_describe (0, q->arr[j]); /* { dg-warning "42" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-alloc-1.c b/gcc/testsuite/gcc.dg/analyzer/taint-alloc-1.c index bc4f63b..cb2db6c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/taint-alloc-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/taint-alloc-1.c @@ -25,6 +25,7 @@ void *test_1 (FILE *f) return malloc (tmp.sz); /* { dg-warning "use of attacker-controlled value 'tmp\\.sz' as allocation size without upper-bounds checking" "warning" } */ /* { dg-message "23: \\(\[0-9\]+\\) 'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event: tmp.i has an unchecked value" { xfail *-*-* } .-1 } */ /* { dg-message "\\(\[0-9\]+\\) use of attacker-controlled value 'tmp\\.sz' as allocation size without upper-bounds checking" "final event" { target *-*-* } .-2 } */ + /* { dg-message "heap-based allocation" "memory space" { target *-*-* } .-3 } */ // TOOD: better messages for state changes } @@ -46,6 +47,7 @@ void *test_2 (FILE *f) char buf[tmp.sz]; /* { dg-warning "use of attacker-controlled value 'tmp\\.sz' as allocation size without upper-bounds checking" "warning" } */ /* { dg-message "\\(\[0-9\]+\\) 'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event: tmp.i has an unchecked value" { xfail *-*-* } .-1 } */ /* { dg-message "\\(\[0-9\]+\\) use of attacker-controlled value 'tmp\\.sz' as allocation size without upper-bounds checking" "final event" { target *-*-* } .-2 } */ + /* { dg-message "stack-based allocation" "memory space" { target *-*-* } .-3 } */ fread (buf, tmp.sz, 1, f); } diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-alloc-5.c b/gcc/testsuite/gcc.dg/analyzer/taint-alloc-5.c new file mode 100644 index 0000000..9a15980 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/taint-alloc-5.c @@ -0,0 +1,21 @@ +// TODO: remove need for this option +/* { dg-additional-options "-fanalyzer-checker=taint" } */ + +#include "analyzer-decls.h" + +struct foo +{ + int num; +}; + +/* malloc with tainted size from a field. */ + +void * __attribute__ ((tainted_args)) +test_1 (struct foo f) +{ + __analyzer_dump_state ("taint", f.num); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", f.num * 16); /* { dg-warning "state: 'tainted'" } */ + + return __builtin_malloc (f.num * 16); /* { dg-warning "use of attacker-controlled value 'f\\.num \\* 16' as allocation size without upper-bounds checking" "warning" } */ + /* { dg-message "\\(\[0-9\]+\\) use of attacker-controlled value 'f\\.num \\* 16' as allocation size without upper-bounds checking" "final event with expr" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-divisor-1.c b/gcc/testsuite/gcc.dg/analyzer/taint-divisor-1.c index 5a5a0b9..b7c1fae 100644 --- a/gcc/testsuite/gcc.dg/analyzer/taint-divisor-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/taint-divisor-1.c @@ -24,3 +24,69 @@ int test_2 (FILE *f) fread (&s, sizeof (s), 1, f); return s.a % s.b; /* { dg-warning "use of attacker-controlled value 's\\.b' as divisor without checking for zero" } */ } + +/* We shouldn't complain if the divisor has been checked for zero. */ + +int test_checked_ne_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + if (s.b) + return s.a / s.b; /* { dg-bogus "divisor" } */ + else + return 0; +} + +int test_checked_gt_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + if (s.b > 0) + return s.a / s.b; /* { dg-bogus "divisor" } */ + else + return 0; +} + +int test_checked_lt_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + if (s.b < 0) + return s.a / s.b; /* { dg-bogus "divisor" } */ + else + return 0; +} + +/* We should complain if the check on the divisor still allows it to be + zero. */ + +int test_checked_ge_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + if (s.b >= 0) + return s.a / s.b; /* { dg-warning "use of attacker-controlled value 's\\.b' as divisor without checking for zero" } */ + else + return 0; +} + +int test_checked_le_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + if (s.b <= 0) + return s.a / s.b; /* { dg-warning "use of attacker-controlled value 's\\.b' as divisor without checking for zero" } */ + else + return 0; +} + +int test_checked_eq_zero (FILE *f) +{ + struct st1 s; + fread (&s, sizeof (s), 1, f); + /* Wrong sense of test. */ + if (s.b != 0) + return 0; + else + return s.a / s.b; /* { dg-warning "use of attacker-controlled value 's\\.b' as divisor without checking for zero" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-size-access-attr-1.c b/gcc/testsuite/gcc.dg/analyzer/taint-size-access-attr-1.c index 724679a..7d243a9 100644 --- a/gcc/testsuite/gcc.dg/analyzer/taint-size-access-attr-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/taint-size-access-attr-1.c @@ -1,8 +1,8 @@ /* Passing tainted sizes to external functions with attribute ((access)) with a size-index. */ -// TODO: remove need for this option: -/* { dg-additional-options "-fanalyzer-checker=taint" } */ +// TODO: remove need for the explicit taint option: +/* { dg-additional-options "-fanalyzer-checker=taint -fanalyzer-show-duplicate-count" } */ #include "analyzer-decls.h" #include <stdio.h> @@ -27,7 +27,8 @@ void test_fn_read_only (FILE *f, void *p) __analyzer_dump_state ("taint", tmp.sz); /* { dg-warning "state: 'tainted'" } */ /* { dg-message "\\(\[0-9\]+\\) \\.\\.\\.to here" "event: to here" { target *-*-* } .-1 } */ - extern_fn_read_only (p, tmp.sz); /* { dg-warning "use of attacker-controlled value 'tmp.sz' as size without upper-bounds checking" } */ + extern_fn_read_only (p, tmp.sz); /* { dg-warning "use of attacker-controlled value 'tmp.sz' as size without upper-bounds checking" "warning" } */ + /* { dg-bogus "duplicate" "duplicate" { target *-*-* } .-1 } */ } } diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/boxed-int-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/boxed-int-1.c new file mode 100644 index 0000000..94111e6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/boxed-int-1.c @@ -0,0 +1,170 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include "../analyzer-decls.h" + +typedef struct boxed_int { int value; } boxed_int; + +extern boxed_int boxed_int_add (boxed_int a, boxed_int b); +extern boxed_int boxed_int_mul (boxed_int a, boxed_int b); + +boxed_int __attribute__((noinline)) +noinline_boxed_int_add (boxed_int a, boxed_int b) +{ + boxed_int result; + result.value = a.value + b.value; + return result; +} + +static inline boxed_int +inline_boxed_int_add (boxed_int a, boxed_int b) +{ + boxed_int result; + result.value = a.value + b.value; + return result; +} + +boxed_int +test_1 (boxed_int a, boxed_int b) +{ + boxed_int result = boxed_int_add (boxed_int_mul (a, a), + boxed_int_mul (b, b)); + return result; +} + +void +test_2a (void) +{ + boxed_int arr[4]; + arr[0].value = 1; + arr[1].value = 2; + arr[2].value = 3; + arr[3].value = 4; + boxed_int sum; + sum.value = arr[0].value + arr[1].value + arr[2].value + arr[3].value; + __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */ +} + +void +test_2b (void) +{ + boxed_int a, b, c, d; + a.value = 1; + b.value = 2; + c.value = 3; + d.value = 4; + boxed_int sum; + sum.value = a.value + b.value + c.value + d.value; + __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */ +} + +void +test_2c (void) +{ + boxed_int a, b, c, d; + a.value = 1; + b.value = 2; + c.value = 3; + d.value = 4; + boxed_int sum = inline_boxed_int_add (inline_boxed_int_add (a, b), + inline_boxed_int_add (c, d)); + __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */ +} + +void +test_2d (void) +{ + boxed_int a, b, c, d; + a.value = 1; + b.value = 2; + c.value = 3; + d.value = 4; + boxed_int sum = noinline_boxed_int_add (noinline_boxed_int_add (a, b), + noinline_boxed_int_add (c, d)); + __analyzer_eval (sum.value == 10); /* { dg-warning "TRUE" } */ +} + +/* Pointer to a local. */ + +void test_4 (void) +{ + boxed_int i; + int *p = &i.value; + i.value = 1; + *p = 2; + __analyzer_eval (i.value == 2); /* { dg-warning "TRUE" } */ +} + +/* Local array. */ + +void test_5 (void) +{ + boxed_int a[10]; + a[3].value = 5; /* ARRAY_REF. */ + __analyzer_eval (a[3].value == 5); /* { dg-warning "TRUE" } */ +} + +/* Local array, but using an unknown index. */ + +void test_5a (int idx) +{ + boxed_int a[10]; + a[idx].value = 5; /* ARRAY_REF. */ + __analyzer_eval (a[idx].value == 5); /* { dg-warning "TRUE" } */ +} + +/* Array passed in as a param. */ + +void test_6 (boxed_int a[10]) +{ + /* POINTER_PLUS_EXPR then a MEM_REF. */ + __analyzer_eval (a[3].value == 42); /* { dg-warning "UNKNOWN" } */ + a[3].value = 42; + __analyzer_eval (a[3].value == 42); /* { dg-warning "TRUE" } */ +} + +/* Array passed in as a param ptr. */ + +void test_7 (boxed_int *a) +{ + __analyzer_eval (a[3].value == 42); /* { dg-warning "UNKNOWN" } */ + a[3].value = 42; + __analyzer_eval (a[3].value == 42); /* { dg-warning "TRUE" } */ +} + +/* Globals. */ + +boxed_int glob_a; + +void test_10 (void) +{ + __analyzer_eval (glob_a.value == 42); /* { dg-warning "UNKNOWN" } */ + glob_a.value = 42; + __analyzer_eval (glob_a.value == 42); /* { dg-warning "TRUE" } */ +} + +/* Use of uninit value. */ +int test_12a (void) +{ + boxed_int i; /* { dg-message "region created on stack here" } */ + return i.value; /* { dg-warning "use of uninitialized value 'i.value'" } */ +} + +/* Use of uninit value. */ +boxed_int test_12b (void) +{ + boxed_int i; /* { dg-message "region created on stack here" } */ + return i; /* { dg-warning "use of uninitialized value '\[^\n\r\]*'" } */ +} + +void test_loop (void) +{ + boxed_int i; + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + + for (i.value=0; i.value<256; i.value++) { + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ + } + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/boxed-ptr-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/boxed-ptr-1.c new file mode 100644 index 0000000..5bc7151 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/boxed-ptr-1.c @@ -0,0 +1,78 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include <stdlib.h> +#include "../analyzer-decls.h" + +typedef struct boxed_ptr { void *value; } boxed_ptr; + +boxed_ptr __attribute__((noinline)) +boxed_malloc (size_t sz) +{ + boxed_ptr result; + result.value = malloc (sz); + return result; +} + +boxed_ptr __attribute__((noinline)) +boxed_free (boxed_ptr ptr) +{ + free (ptr.value); +} + +const boxed_ptr boxed_null = {NULL}; + +boxed_ptr test_1 (int flag) +{ + boxed_ptr ptr = boxed_malloc (sizeof (int)); + + if (flag) /* { dg-message "following 'false' branch" } */ + if (!ptr.value) + return boxed_null; + + *((int *)ptr.value) = 42; /* { dg-warning "dereference of possibly-NULL '\[^\n\r\]*'" } */ + + return ptr; +} + +void test_2 (int flag) +{ + boxed_ptr ptr; + + if (flag) + ptr = boxed_malloc (4096); + else + ptr = boxed_malloc (1024); + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ + + boxed_free (ptr); + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} + +void test_3 (int kind) +{ + boxed_ptr ptr; + + switch (kind) + { + default: + ptr = boxed_malloc (4096); + break; + case 0: + ptr = boxed_malloc (128); + break; + case 1: + ptr = boxed_malloc (1024); + break; + case 2: + ptr = boxed_malloc (65536); + break; + } + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "4 processed enodes" } */ + + boxed_free (ptr); + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-1.c new file mode 100644 index 0000000..3174716 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-1.c @@ -0,0 +1,19 @@ +#include <stdlib.h> + +struct s { + char *p; + int arr[2]; +}; + +int main(void) { + struct s *s = malloc(sizeof *s); + if (s) { + s->p = malloc(1); + for (int i = 0; i < 2; i++) + s->arr[i] = -1; /* { dg-bogus "leak" } */ + } + if (s) { + free(s->p); + free(s); + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-2.c new file mode 100644 index 0000000..d65f176 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/leak-pr102308-2.c @@ -0,0 +1,12 @@ +#include <stdlib.h> +struct s { + char *p; + int arr[1]; +}; +int main(void) { + struct s s; + s.p = malloc(1); + for (int i = 0; i < 1; i++) + s.arr[i] = -1; /* { dg-bogus "leak" } */ + free(s.p); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr104863.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr104863.c new file mode 100644 index 0000000..30ed4fe --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr104863.c @@ -0,0 +1,14 @@ +/* { dg-additional-options "-fanalyzer-transitivity" } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +extern void g(); +struct a { +} b(int c, int d) { + struct a *e = 0; + int f; + if (c & 1 || !(c & 2)) + return *e; + f = 0; + for (; f < d - 1; f++) + g(e[1]); /* { dg-warning "dereference of NULL" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/pr51628-30.c b/gcc/testsuite/gcc.dg/analyzer/torture/pr51628-30.c index 4513e0f..abc1341 100644 --- a/gcc/testsuite/gcc.dg/analyzer/torture/pr51628-30.c +++ b/gcc/testsuite/gcc.dg/analyzer/torture/pr51628-30.c @@ -1,3 +1,4 @@ /* { dg-additional-options "-Wno-address-of-packed-member" } */ +/* { dg-excess-errors "warnings about ignored 'packed' attribute" { target default_packed } } */ #include "../../../c-c++-common/pr51628-30.c" diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/stdarg-4.c b/gcc/testsuite/gcc.dg/analyzer/torture/stdarg-4.c new file mode 100644 index 0000000..8275b0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/stdarg-4.c @@ -0,0 +1,329 @@ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#include "../analyzer-decls.h" + +/* va_arg in loop, with no caller to function containing va_start. */ + +int test_1a (const char *fmt, ...) +{ + __builtin_va_list args; + int sum = 0; + char ch; + + __builtin_va_start(args, fmt); + + while (ch = *fmt++) + if (ch == '%') + sum += __builtin_va_arg(args, int); + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with no caller to function containing va_start. */ + +static int test_1b_callee (const char *fmt, __builtin_va_list args) +{ + int sum = 0; + char ch; + + while (ch = *fmt++) + if (ch == '%') + sum += __builtin_va_arg(args, int); + + return sum; +} + +int test_1b_caller (const char *fmt, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, fmt); + + sum = test_1b_callee (fmt, args); + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with a caller to the function containing va_start, + with specific args. */ + +static int +test_1c_inner (const char *fmt, __builtin_va_list args) +{ + int sum = 0; + char ch; + + while (ch = *fmt++) + if (ch == '%') + sum += __builtin_va_arg(args, int); + + return sum; +} + +static int +test_1c_middle (const char *fmt, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, fmt); + + sum = test_1c_inner (fmt, args); + + __builtin_va_end(args); + + return sum; +} + +void test_1c_outer (void) +{ + int sum = test_1c_middle ("%%", 42, 17); + + __analyzer_describe (0, sum); /* { dg-message "'\\(int\\)59'" } */ +} + +/* va_arg in loop, with no caller to function containing va_start. */ + +int test_2a (int count, ...) +{ + __builtin_va_list args; + int sum = 0; + char ch; + + __builtin_va_start(args, count); + + while (count-- > 0) + sum += __builtin_va_arg(args, int); + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with no caller to function containing va_start. */ + +static int test_2b_callee (int count, __builtin_va_list args) +{ + int sum = 0; + + while (count-- > 0) + sum += __builtin_va_arg(args, int); + + return sum; +} + +int test_2b_caller (int count, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, count); + + sum = test_2b_callee (count, args); + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with a caller to the function containing va_start, + with specific args. */ + +static int test_2c_inner (int count, __builtin_va_list args) +{ + int sum = 0; + + while (count-- > 0) + sum += __builtin_va_arg(args, int); + + return sum; +} + +int test_2c_middle (int count, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, count); + + sum = test_2c_inner (count, args); + + __builtin_va_end(args); + + return sum; +} + +void test_2c_outer (void) +{ + int sum = test_2c_middle (2, 50, 42); + + __analyzer_describe (0, sum); /* { dg-message "'\\(int\\)92'" } */ +} + +/* va_arg in loop, with no caller to function containing va_start. */ + +int test_3a (int placeholder, ...) +{ + __builtin_va_list args; + int sum = 0; + int val; + + __builtin_va_start(args, placeholder); + + while (val = __builtin_va_arg(args, int)) + sum += val; + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with no caller to function containing va_start. */ + +static int test_3b_callee (__builtin_va_list args) +{ + int sum = 0; + int val; + while (val = __builtin_va_arg(args, int)) + sum += val; + return sum; +} + +int test_3b_caller (int placeholder, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, placeholder); + + sum = test_3b_callee (args); + + __builtin_va_end(args); + + return sum; +} + +/* va_arg in loop, with a caller to the function containing va_start, + with specific args. */ + +static int test_3c_inner (__builtin_va_list args) +{ + int sum = 0; + int val; + while (val = __builtin_va_arg(args, int)) + sum += val; + return sum; +} + +int test_3c_middle (int placeholder, ...) +{ + __builtin_va_list args; + int sum = 0; + + __builtin_va_start(args, placeholder); + + sum = test_3c_inner (args); + + __builtin_va_end(args); + + return sum; +} + +void test_3c_outer (void) +{ + int sum = test_3c_middle (0, 5, 12, 0); + __analyzer_describe (0, sum); /* { dg-message "'\\(int\\)17'" } */ +} + +/* va_arg in loop, with no caller to function containing va_start, + with a va_copy. */ + +static int test_3d_callee (__builtin_va_list args) +{ + int sum = 0; + int val; + while (val = __builtin_va_arg(args, int)) + sum += val; + return sum; +} + +int test_3d_caller (int placeholder, ...) +{ + __builtin_va_list args1, args2; + int sum = 0; + + __builtin_va_start(args1, placeholder); + __builtin_va_copy (args2, args1); + + sum = test_3d_callee (args1); + __builtin_va_end(args1); + + sum += test_3d_callee (args2); + __builtin_va_end(args2); + + return sum; +} + +/* va_arg in loop, with a caller to the function containing va_start, + with specific args, with a va_copy. */ + +static int test_3e_inner (__builtin_va_list args) +{ + int sum = 0; + int val; + while (val = __builtin_va_arg(args, int)) + sum += val; + return sum; +} + +int test_3e_middle (int placeholder, ...) +{ + __builtin_va_list args1, args2; + int sum = 0; + + __builtin_va_start(args1, placeholder); + __builtin_va_copy (args2, args1); + + sum = test_3e_inner (args1); + __builtin_va_end(args1); + + sum += test_3e_inner (args2); + __builtin_va_end(args2); + + return sum; +} + +void test_3e_outer (void) +{ + int sum = test_3e_middle (0, 5, 6, 0); + __analyzer_describe (0, sum); /* { dg-message "'\\(int\\)22'" } */ +} + +/* va_arg in loop, with specific symbolic args. */ + +static int test_3f_callee (int placeholder, ...) +{ + __builtin_va_list args; + int sum = 0; + int val; + + __builtin_va_start(args, placeholder); + + while (val = __builtin_va_arg(args, int)) + sum += val; + + __builtin_va_end(args); + + return sum; +} + +void test_3f_caller (int x, int y, int z) +{ + int sum = test_3f_callee (0, x, y, z, 0); + __analyzer_describe (0, sum); /* { dg-message "'UNKNOWN\\(int\\)'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/symbolic-10.c b/gcc/testsuite/gcc.dg/analyzer/torture/symbolic-10.c new file mode 100644 index 0000000..b2f3a8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/symbolic-10.c @@ -0,0 +1,40 @@ +/* Verify that -fanalyzer considers that mmfs escapes when passing either: + *(mmfs + i) + and + (&mmfs[i]) + to an external function (for symbolic i). */ + +typedef struct s_mmfile { + char *ptr; + long size; +} mmfile_t; + +void init_mmfile(mmfile_t *ptr); + +long test__init_via_ptr_arith__read_via_array_idx(int i) +{ + mmfile_t mmfs[3]; + init_mmfile(mmfs + i); + return mmfs[i].size; /* { dg-bogus "uninit" } */ +} + +long test__init_via_array_idx__read_via_ptr_arith(int i) +{ + mmfile_t mmfs[3]; + init_mmfile(&mmfs[i]); + return (mmfs + i)->size; /* { dg-bogus "uninit" } */ +} + +long test__ptr_arith_for_both(int i) +{ + mmfile_t mmfs[3]; + init_mmfile(mmfs + i); + return (mmfs + i)->size; /* { dg-bogus "uninit" } */ +} + +long test__array_idx_for_both(int i) +{ + mmfile_t mmfs[3]; + init_mmfile(&mmfs[i]); + return mmfs[i].size; /* { dg-bogus "uninit" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-2.c new file mode 100644 index 0000000..b3dc177 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-2.c @@ -0,0 +1,141 @@ +// TODO: remove need for the taint option: +/* { dg-additional-options "-fanalyzer-checker=taint" } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +#define LOWER_LIMIT 5 +#define UPPER_LIMIT 20 + +static int arr[UPPER_LIMIT]; + +static int +called_by_test_1 (int iarg) +{ + return arr[iarg]; /* { dg-warning "without bounds checking" } */ +} + +int __attribute__((tainted_args)) +test_1 (unsigned long ularg) +{ + return called_by_test_1 (ularg); +} + +static int +called_by_test_2 (int iarg) +{ + if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT) + return 0; + return arr[iarg]; /* { dg-bogus "bounds checking" } */ +} + +int __attribute__((tainted_args)) +test_2 (unsigned long ularg) +{ + return called_by_test_2 (ularg); +} + +int __attribute__((tainted_args)) +test_3 (int iarg) +{ + if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT) + return 0; + return arr[iarg]; /* { dg-bogus "bounds checking" } */ +} + +static int +called_by_test_4 (int iarg) +{ + if (iarg < LOWER_LIMIT || iarg > UPPER_LIMIT) + return 0; + return arr[iarg]; /* { dg-bogus "bounds checking" } */ +} + +int __attribute__((tainted_args)) +test_4 (unsigned uarg) +{ + return called_by_test_4 (uarg); +} + +int __attribute__((tainted_args)) +test_5 (int idx) +{ + switch (idx) + { + default: + return 0; + case 5 ... 20: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + /* 20 is still an out-of-bounds error (off-by-one) + but we don't check for that, just that bounds have been imposed. */ + + /* Extra cases to avoid optimizing the switch away. */ + case 22: + return 22; + case 23: + return -17; + } +} + +int __attribute__((tainted_args)) +test_6 (int idx) +{ + switch (idx) + { + default: + return arr[idx]; /* { dg-warning "without bounds checking" } */ + + case 2: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 6 ... 19: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 22: + return 22; + case 23: + return -17; + } +} + +int __attribute__((tainted_args)) +test_7 (int idx) +{ + switch (idx) + { + default: + return arr[idx]; /* { dg-warning "without bounds checking" } */ + + case 2 ... 4: + case 7 ... 9: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 12 ... 19: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 22: + return 22; + case 23: + return -17; + } +} + +int __attribute__((tainted_args)) +test_8 (unsigned idx) +{ + switch (idx) + { + default: + return arr[idx]; /* { dg-warning "without upper-bounds checking" } */ + + case 2 ... 4: + case 7 ... 9: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 12 ... 19: + return arr[idx]; /* { dg-bogus "bounds checking" } */ + + case 22: + return 22; + case 23: + return -17; + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-3.c b/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-3.c new file mode 100644 index 0000000..8eb6061 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/taint-read-index-3.c @@ -0,0 +1,52 @@ +// TODO: remove need for the taint option: +/* { dg-additional-options "-fanalyzer-checker=taint" } */ +/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */ + +struct raw_ep { + /* ...snip... */ + int state; + /* ...snip... */ +}; + +struct raw_dev { + /* ...snip... */ + struct raw_ep eps[30]; + int eps_num; + /* ...snip... */ +}; + +int __attribute__((tainted_args)) +simplified_raw_ioctl_ep_disable(struct raw_dev *dev, unsigned long value) +{ + int ret = 0, i = value; + + if (i < 0 || i >= dev->eps_num) { + ret = -16; + goto out_unlock; + } + if (dev->eps[i].state == 0) { /* { dg-bogus "attacker-controlled" } */ + ret = -22; + goto out_unlock; + } + +out_unlock: + return ret; +} + +int __attribute__((tainted_args)) +test_2(struct raw_dev *dev, int i) +{ + int ret = 0; + + if (i < 0 || i >= dev->eps_num) { + ret = -16; + goto out_unlock; + } + if (dev->eps[i].state == 0) { /* { dg-bogus "attacker-controlled" } */ + ret = -22; + goto out_unlock; + } + +out_unlock: + return ret; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c new file mode 100644 index 0000000..25edcf5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/torture/uninit-pr106204.c @@ -0,0 +1,13 @@ +/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */ + +int foo(unsigned *len); +int test_1() +{ + unsigned len; /* { dg-bogus "uninit" } */ + int rc; + + rc = foo(&len); + if (!rc) + rc = len; + return rc; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c index 9a6576e..3d10216 100644 --- a/gcc/testsuite/gcc.dg/analyzer/uninit-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-1.c @@ -127,3 +127,22 @@ size_t test_builtin_strlen (void) const char *ptr; /* { dg-message "region created on stack here" } */ return __builtin_strlen (ptr); /* { dg-warning "use of uninitialized value 'ptr'" } */ } + +void test_calling_uninit_fn_ptr_1 (void) +{ + void (*fn_ptr) (void); /* { dg-message "region created on stack here" } */ + fn_ptr (); /* { dg-warning "use of uninitialized value 'fn_ptr'" } */ +} + +int test_calling_uninit_fn_ptr_2 (void) +{ + int (*fn_ptr) (void); /* { dg-message "region created on stack here" } */ + return fn_ptr (); /* { dg-warning "use of uninitialized value 'fn_ptr'" } */ +} + +extern void called_by_uninit_arg (int); +void test_passing_uninit_arg (void) +{ + int i; /* { dg-message "region created on stack here" } */ + called_by_uninit_arg (i); /* { dg-warning "use of uninitialized value 'i'" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c b/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c new file mode 100644 index 0000000..7d7cf7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/uninit-pr106204.c @@ -0,0 +1,17 @@ +/* { dg-additional-options "-ftrivial-auto-var-init=zero" } */ + +int foo(unsigned *len); + +/* Modified version of reproducer that does use "len" before init. */ + +int test_2() +{ + unsigned len; + int rc; + + rc = len; /* { dg-warning "use of uninitialized value 'len'" } */ + rc = foo(&len); + if (!rc) + rc = len; + return rc; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/untracked-1.c b/gcc/testsuite/gcc.dg/analyzer/untracked-1.c new file mode 100644 index 0000000..9f3a639 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/untracked-1.c @@ -0,0 +1,131 @@ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +#include "analyzer-decls.h" + +struct st +{ + const char *m_filename; + int m_line; +}; + +typedef struct boxed_int { int value; } boxed_int; + +extern void extern_fn (struct st *); +static void __attribute__((noinline)) internal_fn (struct st *) {} +extern int extern_get_int (void); +extern void extern_fn_char_ptr (const char *); + +void test_0 (void) +{ + /* Not ever referenced; will get optimized away before + analyzer ever sees it, so no message. */ + static struct st s1 = { __FILE__, __LINE__ }; +} + +void test_1 (void) +{ + static struct st s1 = { __FILE__, __LINE__ }; /* { dg-warning "track 's1': no" } */ + extern_fn (&s1); +} + +static struct st s2 = { __FILE__, __LINE__ }; /* { dg-warning "track 's2': yes" } */ + +void test_2 (void) +{ + extern_fn (&s2); +} + +void test_3 (void) +{ + struct st s3 = { __FILE__, __LINE__ }; /* { dg-warning "track 's3': yes" } */ + extern_fn (&s3); +} + +void test_3a (void) +{ + struct st s3a = { "foo.c", 42 }; /* { dg-warning "track 's3a': yes" } */ + __analyzer_eval (s3a.m_filename[0] == 'f'); /* { dg-warning "TRUE" } */ + __analyzer_eval (s3a.m_line == 42); /* { dg-warning "TRUE" } */ + extern_fn (&s3a); + __analyzer_eval (s3a.m_filename[0] == 'f'); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (s3a.m_line == 42); /* { dg-warning "UNKNOWN" } */ +} + +extern void called_by_test_4 (int *); + +int test_4 (void) +{ + int i; /* { dg-warning "track 'i': yes" } */ + called_by_test_4 (&i); + return i; +} + +void test_5 (int i) +{ + boxed_int bi5 = { i }; /* { dg-warning "track 'bi5': yes" } */ +} + +int test_6 (int i) +{ + static boxed_int bi6; /* { dg-warning "track 'bi6': yes" } */ + bi6.value = i; + return bi6.value; +} + +int test_7 (void) +{ + boxed_int bi7; /* { dg-warning "track 'bi7': yes" } */ + return bi7.value; /* { dg-warning "use of uninitialized value 'bi7.value'" "uninit" } */ +} + +void test_8 (void) +{ + static struct st s8 = { __FILE__, __LINE__ }; /* { dg-warning "track 's8': no" } */ + extern_fn (&s8); + extern_fn (&s8); +} + +void test_9 (void) +{ + static struct st s9 = { __FILE__, __LINE__ }; /* { dg-warning "track 's9': yes" } */ + internal_fn (&s9); +} + +int test_10 (void) +{ + static struct st s10 = { __FILE__, __LINE__ }; /* { dg-warning "track 's10': yes" } */ + extern_fn (&s10); + return s10.m_line; +} + +int test_11 (void) +{ + static struct st s10 = { __FILE__, __LINE__ }; /* { dg-warning "track 's10': yes" } */ + s10.m_line = extern_get_int (); + return 42; +} + +int test_12 (void (*fnptr) (struct st *)) +{ + static struct st s12 = { __FILE__, __LINE__ }; /* { dg-warning "track 's12': yes" } */ + fnptr (&s12); +} + +void test_13 (void) +{ + extern_fn_char_ptr (__func__); /* { dg-warning "track '__func__': no" } */ +} + +char t14_global_unused[100]; /* { dg-warning "track 't14_global_unused': yes" } */ +static char t14_static_unused[100]; /* { dg-warning "track 't14_static_unused': yes" } */ +char t14_global_used[100]; /* { dg-warning "track 't14_global_used': yes" } */ +static char t14_static_used[100]; /* { dg-warning "track 't14_static_used': yes" } */ +void test_14 (void) +{ + extern_fn_char_ptr (t14_global_unused); + extern_fn_char_ptr (t14_static_unused); + extern_fn_char_ptr (t14_global_used); + __analyzer_eval (t14_global_used[0] == '\0'); /* { dg-warning "UNKNOWN" } */ + extern_fn_char_ptr (t14_static_used); + __analyzer_eval (t14_static_used[0] == '\0'); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/gcc.dg/analyzer/untracked-2.c b/gcc/testsuite/gcc.dg/analyzer/untracked-2.c new file mode 100644 index 0000000..565a9cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/untracked-2.c @@ -0,0 +1,7 @@ +typedef unsigned char u8; +extern int foo(const u8 *key, unsigned int keylen); +int test (void) +{ + static const u8 default_salt[64]; + return foo(default_salt, 64); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/unused-local-1.c b/gcc/testsuite/gcc.dg/analyzer/unused-local-1.c new file mode 100644 index 0000000..361cdce --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/unused-local-1.c @@ -0,0 +1,22 @@ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +struct st +{ + const char *m_filename; + int m_line; + const char *m_function; +}; + +extern void debug (struct st *); + +void test (void) +{ + { + static struct st s1 = { __FILE__, __LINE__, __func__ }; /* { dg-warning "track 's1': no" } */ + debug (&s1); + } + { + static struct st s2 = { __FILE__, __LINE__, __func__ }; /* { dg-warning "track 's2': no" } */ + debug (&s2); + } +} diff --git a/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c b/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c new file mode 100644 index 0000000..061cd00 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c @@ -0,0 +1,57 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#define NULL ((void *)0) + +extern int printf (const char *__restrict __format, ...); +extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, + __builtin_va_list __arg) + __attribute__ ((__nothrow__, __format__ (__printf__, 2, 0))) ; +extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); + +static char * __attribute__ ((__format__ (__printf__, 1, 2))) +zasprintf (const char *format, ...) +{ + char *resultp; + __builtin_va_list args; + __builtin_va_start (args, format); + int r = vasprintf (&resultp, format, args); + __builtin_va_end (args); + return r < 0 ? NULL : resultp; +} + +int run_test() { + char *buf = NULL; + char *bar = NULL; + char *baz = NULL; + int i = 1232; + + printf("static function check\n"); + + buf = zasprintf("i = %d", i); + if (buf) { + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + bar = zasprintf("i = %d - %d", i, i - 13); + if (bar) { + printf("bar = %s\nbar = %p\n", bar, bar); + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + baz = zasprintf("No i's here"); + if (baz) { + printf("baz = %s\nbaz = %p\n", baz, baz); + printf("bar = %s\nbar = %p\n", bar, bar); + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + free(buf); + free(bar); + free(baz); + + return 1; +} + +int main(int argc, char **argv) { + return run_test(); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-const-2.c b/gcc/testsuite/gcc.dg/analyzer/write-to-const-2.c new file mode 100644 index 0000000..bd9f3c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-const-2.c @@ -0,0 +1,60 @@ +typedef __SIZE_TYPE__ size_t; + +void read_only (void *) + __attribute__ ((access (read_only, 1))); +void write_only (void *) /* { dg-message "parameter 1 of 'write_only' marked with attribute 'access \\(write_only, 1\\)'" } */ + __attribute__ ((access (write_only, 1))); +void read_write (void *) /* { dg-message "parameter 1 of 'read_write' marked with attribute 'access \\(read_write, 1\\)'" } */ + __attribute__ ((access (read_write, 1))); +void none (void *) + __attribute__ ((access (none, 1))); +void read_only_with_size (void *, size_t) + __attribute__ ((access (read_only, 1, 2))); +void write_only_with_size (void *, size_t) /* { dg-message "parameter 1 of 'write_only_with_size' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + __attribute__ ((access (write_only, 1, 2))); +void read_write_with_size (void *, size_t) /* { dg-message "parameter 1 of 'read_write_with_size' marked with attribute 'access \\(read_write, 1, 2\\)'" } */ + __attribute__ ((access (read_write, 1, 2))); +void none_with_size (void *, size_t) + __attribute__ ((access (none, 1, 2))); + +const char buf[5] = { 0 }; /* { dg-message "declared here" } */ + +void test_read_only (void) +{ + read_only ((char *)buf); +} + +void test_write_only (void) +{ + write_only ((char *)buf); /* { dg-warning "write to 'const' object 'buf'" } */ +} + +void test_read_write (void) +{ + read_write ((char *)buf); /* { dg-warning "write to 'const' object 'buf'" } */ +} + +void test_none (void) +{ + none ((char *)buf); +} + +void test_read_only_with_size (void) +{ + read_only_with_size ((char *)buf, sizeof (buf)); +} + +void test_write_only_with_size (void) +{ + write_only_with_size ((char *)buf, sizeof (buf)); /* { dg-warning "write to 'const' object 'buf'" } */ +} + +void test_read_write_with_size (void) +{ + read_write_with_size ((char *)buf, sizeof (buf)); /* { dg-warning "write to 'const' object 'buf'" } */ +} + +void test_none_with_size (void) +{ + none_with_size ((char *)buf, sizeof (buf)); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c b/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c new file mode 100644 index 0000000..c1bece6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c @@ -0,0 +1,15 @@ +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void test (void) +{ + char buf[16]; + + if (getrandom(test, 16, GRND_RANDOM)) /* { dg-warning "write to function 'test'" } */ + __builtin_printf("%s\n", buf); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-2.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-2.c new file mode 100644 index 0000000..657ada6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-2.c @@ -0,0 +1,19 @@ +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +const char *test = "test"; + +int main(void) +{ + const char buf[5] = { 0 }; + + if (getrandom((char *)test, sizeof(buf), GRND_RANDOM)) /* { dg-warning "write to string literal" } */ + __builtin_printf("%s\n", buf); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-3.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-3.c new file mode 100644 index 0000000..9d5d07d --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-3.c @@ -0,0 +1,66 @@ +typedef __SIZE_TYPE__ size_t; + +void read_only (void *) + __attribute__ ((access (read_only, 1))); +void write_only (void *) /* { dg-message "parameter 1 of 'write_only' marked with attribute 'access \\(write_only, 1\\)'" } */ + __attribute__ ((access (write_only, 1))); +void read_write (void *) /* { dg-message "parameter 1 of 'read_write' marked with attribute 'access \\(read_write, 1\\)'" } */ + __attribute__ ((access (read_write, 1))); +void none (void *) + __attribute__ ((access (none, 1))); +void read_only_with_size (void *, size_t) + __attribute__ ((access (read_only, 1, 2))); +void write_only_with_size (void *, size_t) /* { dg-message "parameter 1 of 'write_only_with_size' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + __attribute__ ((access (write_only, 1, 2))); +void read_write_with_size (void *, size_t) /* { dg-message "parameter 1 of 'read_write_with_size' marked with attribute 'access \\(read_write, 1, 2\\)'" } */ + __attribute__ ((access (read_write, 1, 2))); +void none_with_size (void *, size_t) + __attribute__ ((access (none, 1, 2))); + +void test_read_only (void) +{ + const char *str = "hello world"; + read_only ((char *)str); +} + +void test_write_only (void) +{ + const char *str = "hello world"; + write_only ((char *)str); /* { dg-warning "write to string literal" } */ +} + +void test_read_write (void) +{ + const char *str = "hello world"; + read_write ((char *)str); /* { dg-warning "write to string literal" } */ +} + +void test_none (void) +{ + const char *str = "hello world"; + none ((char *)str); +} + +void test_read_only_with_size (void) +{ + const char *str = "hello world"; + read_only_with_size ((char *)str, sizeof (str)); +} + +void test_write_only_with_size (void) +{ + const char *str = "hello world"; + write_only_with_size ((char *)str, sizeof (str)); /* { dg-warning "write to string literal" } */ +} + +void test_read_write_with_size (void) +{ + const char *str = "hello world"; + read_write_with_size ((char *)str, sizeof (str)); /* { dg-warning "write to string literal" } */ +} + +void test_none_with_size (void) +{ + const char *str = "hello world"; + none_with_size ((char *)str, sizeof (str)); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c new file mode 100644 index 0000000..fa21af1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c @@ -0,0 +1,28 @@ +/* Verify that we can disable warnings that have notes added to them via + region_model_context_decorator::add_note. */ + +/* { dg-additional-options "-Wno-analyzer-write-to-string-literal" } */ + +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-bogus "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void test (int flag) +{ + char *buf; + + if (flag) + buf = __builtin_malloc (1024); + else + buf = (char *)""; /* { dg-bogus "here" } */ + + if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-bogus "write to string literal" } */ + __builtin_printf("%s\n", buf); + + if (flag) + __builtin_free (buf); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c new file mode 100644 index 0000000..a8f600f --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c @@ -0,0 +1,23 @@ +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void test (int flag) +{ + char *buf; + + if (flag) + buf = __builtin_malloc (1024); + else + buf = (char *)""; /* { dg-message "here" } */ + + if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-warning "write to string literal" } */ + __builtin_printf("%s\n", buf); + + if (flag) + __builtin_free (buf); +} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c new file mode 100644 index 0000000..b7ac465 --- /dev/null +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c @@ -0,0 +1,31 @@ +/* Verify that deduplication of -Wanalyzer-write-to-string-literal (and their + notes) works. */ + +/* { dg-additional-options "-fanalyzer-show-duplicate-count" } */ + +#include "analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void *test (int flag) +{ + char *ptr; + if (flag) + ptr = __builtin_malloc (1024); + else + ptr = __builtin_alloca (1024); + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ + + if (getrandom((char *)"foo", 3, GRND_RANDOM)) /* { dg-warning "write to string literal" "warning" } */ + /* { dg-message "1 duplicate" "dup" { target *-*-* } .-1 } */ + __builtin_printf("ok\n"); + + return ptr; +} diff --git a/gcc/testsuite/gcc.dg/asan/pr105214.c b/gcc/testsuite/gcc.dg/asan/pr105214.c new file mode 100644 index 0000000..a755336 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr105214.c @@ -0,0 +1,16 @@ +/* PR target/105214 */ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-Ofast -fnon-call-exceptions -fexceptions -fstack-check=generic -fsanitize=address -fno-finite-math-only -fsignaling-nans -fno-associative-math" } */ + +float f; +void bar (int *); + +void +foo (void) +{ + int a[1600], b[1]; + f += __builtin_log1pf (f); + bar (a); + bar (b); +} diff --git a/gcc/testsuite/gcc.dg/asan/pr105396.c b/gcc/testsuite/gcc.dg/asan/pr105396.c new file mode 100644 index 0000000..d4bd7f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr105396.c @@ -0,0 +1,19 @@ +/* PR sanitizer/105396 */ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */ +/* { dg-shouldfail "asan" } */ + +int +main () +{ + int a; + int *b[1]; + int c[10]; + int d[1][1]; + for (a = 0; a < 1; a++) + d[1][a] = 0; + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer: stack-buffer-overflow on address.*(\n|\r\n|\r)" } */ +/* { dg-output "WRITE of size.*" } */ diff --git a/gcc/testsuite/gcc.dg/asan/pr105714.c b/gcc/testsuite/gcc.dg/asan/pr105714.c new file mode 100644 index 0000000..d378b8a --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/pr105714.c @@ -0,0 +1,33 @@ +/* PR sanitizer/105714 */ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-Os" } } */ +/* { dg-shouldfail "asan" } */ + +struct A { int x; }; +struct A b[2]; +struct A *c = b, *d = b; +int e; + +int +foo () +{ + for (e = 0; e < 1; e++) + { + int i[1]; + i; + } + for (int h = 0; h < 3; h++) + *c = *d; + *c = *(b + 3); + return c->x; +} + +int +main () +{ + foo (); + return 0; +} + +/* { dg-output "ERROR: AddressSanitizer: global-buffer-overflow on address.*(\n|\r\n|\r)" } */ +/* { dg-output "READ of size.*" } */ diff --git a/gcc/testsuite/gcc.dg/asan/pr99673.c b/gcc/testsuite/gcc.dg/asan/pr99673.c index 05857fd..a1e9631 100644 --- a/gcc/testsuite/gcc.dg/asan/pr99673.c +++ b/gcc/testsuite/gcc.dg/asan/pr99673.c @@ -1,4 +1,6 @@ /* { dg-do compile } */ +/* Skip XPASS cases. */ +/* { dg-skip-if "" { *-*-* } { "-O0" "-O1" "-O2 -flto" } { "" } } */ /* { dg-additional-options "-Wstringop-overread" } */ struct B { @@ -22,6 +24,6 @@ void g (struct C *pc, struct D *pd, int i) pd->i = pb->i; const short *psa = pb->a[i].sa; - if (f (psa)) + if (f (psa)) /* { dg-bogus "from a region of size" "pr99673" { xfail *-*-* } } */ return; } diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c index d6bb629..669e7c0 100644 --- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c +++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-4.c @@ -32,7 +32,10 @@ test_thread_##NAME (void *arg) \ { \ thread_ready = true; \ for (int i = 0; i < ITER_COUNT; i++) \ - PRE var_##NAME POST; \ + { \ + sched_yield (); \ + PRE var_##NAME POST; \ + } \ return NULL; \ } \ \ @@ -49,9 +52,12 @@ test_main_##NAME (void) \ return 1; \ } \ while (!thread_ready) \ - ; \ + sched_yield (); \ for (int i = 0; i < ITER_COUNT; i++) \ - PRE var_##NAME POST; \ + { \ + PRE var_##NAME POST; \ + sched_yield (); \ + } \ pthread_join (thread_id, NULL); \ if (var_##NAME != (FINAL)) \ { \ diff --git a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c index 692c64a..f8bfa63 100644 --- a/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c +++ b/gcc/testsuite/gcc.dg/atomic/c11-atomic-exec-5.c @@ -53,8 +53,11 @@ test_thread_##NAME (void *arg) \ thread_ready = true; \ while (!thread_stop) \ { \ + sched_yield (); \ var_##NAME = (INIT1); \ + sched_yield (); \ var_##NAME = (INIT2); \ + sched_yield (); \ } \ return NULL; \ } \ @@ -75,13 +78,14 @@ test_main_##NAME (void) \ } \ int num_1_pass = 0, num_1_fail = 0, num_2_pass = 0, num_2_fail = 0; \ while (!thread_ready) \ - ; \ + sched_yield (); \ for (int i = 0; i < ITER_COUNT; i++) \ { \ feclearexcept (FE_ALL_EXCEPT); \ feraiseexcept (BEXC); \ LHSTYPE r = (PRE var_##NAME POST); \ int rexc = fetestexcept (TEST_ALL_EXCEPT); \ + sched_yield (); \ if (VALTEST1 (r)) \ { \ if (rexc == ((BEXC) | (EXC1))) \ diff --git a/gcc/testsuite/gcc.dg/atomic/pr80640-2.c b/gcc/testsuite/gcc.dg/atomic/pr80640-2.c index a735054..e33dcc3 100644 --- a/gcc/testsuite/gcc.dg/atomic/pr80640-2.c +++ b/gcc/testsuite/gcc.dg/atomic/pr80640-2.c @@ -12,7 +12,8 @@ static void *f(void *va) void **p = va; if (*p) return *p; sem1 = 1; - while (!__atomic_load_n(&sem2, __ATOMIC_ACQUIRE)); + while (!__atomic_load_n(&sem2, __ATOMIC_ACQUIRE)) + sched_yield (); // GCC used to RTL-CSE this and the first load, causing 0 to be returned return *p; } @@ -23,7 +24,8 @@ int main() pthread_t thr; if (pthread_create(&thr, 0, f, &p)) return 2; - while (!sem1); + while (!sem1) + sched_yield (); __atomic_thread_fence(__ATOMIC_ACQUIRE); p = &p; __atomic_store_n(&sem2, 1, __ATOMIC_RELEASE); diff --git a/gcc/testsuite/gcc.dg/atomic/pr80640.c b/gcc/testsuite/gcc.dg/atomic/pr80640.c index fd17978..2577e0d 100644 --- a/gcc/testsuite/gcc.dg/atomic/pr80640.c +++ b/gcc/testsuite/gcc.dg/atomic/pr80640.c @@ -12,7 +12,8 @@ static void *f(void *va) void **p = va; if (*p) return *p; sem1 = 1; - while (!sem2); + while (!sem2) + sched_yield (); __atomic_thread_fence(__ATOMIC_ACQUIRE); // GCC used to RTL-CSE this and the first load, causing 0 to be returned return *p; @@ -24,7 +25,8 @@ int main() pthread_t thr; if (pthread_create(&thr, 0, f, &p)) return 2; - while (!sem1); + while (!sem1) + sched_yield (); __atomic_thread_fence(__ATOMIC_ACQUIRE); p = &p; __atomic_thread_fence(__ATOMIC_RELEASE); diff --git a/gcc/testsuite/gcc.dg/atomic/pr81316.c b/gcc/testsuite/gcc.dg/atomic/pr81316.c index ef10095..dc6569a 100644 --- a/gcc/testsuite/gcc.dg/atomic/pr81316.c +++ b/gcc/testsuite/gcc.dg/atomic/pr81316.c @@ -10,7 +10,8 @@ static _Atomic int sem1; static void *f(void *va) { void **p = va; - while (!__atomic_load_n(&sem1, __ATOMIC_ACQUIRE)); + while (!__atomic_load_n(&sem1, __ATOMIC_ACQUIRE)) + sched_yield (); exit(!*p); } @@ -24,6 +25,10 @@ int main(int argc) p = &p; __atomic_store_n(&sem1, 1, __ATOMIC_RELEASE); int r = -1; - while (r < 0) asm("":"+r"(r)); + while (r < 0) + { + sched_yield (); + asm("":"+r"(r)); + } return r; } diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-1.c b/gcc/testsuite/gcc.dg/auto-init-pr102276-1.c new file mode 100644 index 0000000..d574926 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -ftrivial-auto-var-init=zero" } */ + +int g(int *); +int f() +{ + switch (0) { + int x; /* { dg-bogus "statement will never be executed" } */ + default: + return g(&x); + } +} + +int g1(int); +int f1() +{ + switch (0) { + int x; /* { dg-bogus "statement will never be executed" } */ + default: + return g1(x); /* { dg-warning "is used uninitialized" } */ + } +} + +struct S +{ + char a; + int b; +}; +int g2(int); +int f2(int input) +{ + switch (0) { + struct S x; /* { dg-bogus "statement will never be executed" } */ + default: + return g2(input) + x.b; /* { dg-warning "is used uninitialized" } */ + } +} + diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-2.c b/gcc/testsuite/gcc.dg/auto-init-pr102276-2.c new file mode 100644 index 0000000..779d3ec --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-2.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall -ftrivial-auto-var-init=pattern" } */ + +int g(int *); +int f() +{ + switch (0) { + int x; /* { dg-bogus "statement will never be executed" } */ + default: + return g(&x); + } +} + +int g1(int); +int f1() +{ + switch (0) { + int x; /* { dg-bogus "statement will never be executed" } */ + default: + return g1(x); /* { dg-warning "is used uninitialized" } */ + } +} + +struct S +{ + char a; + int b; +}; +int g2(int); +int f2(int input) +{ + switch (0) { + struct S x; /* { dg-bogus "statement will never be executed" } */ + default: + return g2(input) + x.b; /* { dg-warning "is used uninitialized" } */ + } +} + diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c b/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c new file mode 100644 index 0000000..f113f46 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-3.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wtrivial-auto-var-init -ftrivial-auto-var-init=zero" } */ + +int g(int *, int *); +int f() +{ + switch (0) { + int x; /* { dg-warning "cannot be initialized with" } */ + int y; /* { dg-warning "cannot be initialized with" } */ + default: + return g(&x, &y); + } +} + +int g1(int, int); +int f1() +{ + switch (0) { + int x; /* { dg-warning "cannot be initialized with" } */ + int y; /* { dg-warning "cannot be initialized with" } */ + default: + return g1(x, y); + } +} + +struct S +{ + char a; + int b; +}; +int g2(int); +int f2(int input) +{ + switch (0) { + struct S x; /* { dg-warning "cannot be initialized with" } */ + struct S y; /* { dg-warning "cannot be initialized with" } */ + default: + return g2(input) + x.b + y.b; + } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c b/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c new file mode 100644 index 0000000..662e0d1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr102276-4.c @@ -0,0 +1,40 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wtrivial-auto-var-init -ftrivial-auto-var-init=pattern" } */ + +int g(int *, int *); +int f() +{ + switch (0) { + int x; /* { dg-warning "cannot be initialized with" } */ + int y; /* { dg-warning "cannot be initialized with" } */ + default: + return g(&x, &y); + } +} + +int g1(int, int); +int f1() +{ + switch (0) { + int x; /* { dg-warning "cannot be initialized with" } */ + int y; /* { dg-warning "cannot be initialized with" } */ + default: + return g1(x, y); + } +} + +struct S +{ + char a; + int b; +}; +int g2(int); +int f2(int input) +{ + switch (0) { + struct S x; /* { dg-warning "cannot be initialized with" } */ + struct S y; /* { dg-warning "cannot be initialized with" } */ + default: + return g2(input) + x.b + y.b; + } +} diff --git a/gcc/testsuite/gcc.dg/auto-init-pr104550-1.c b/gcc/testsuite/gcc.dg/auto-init-pr104550-1.c new file mode 100644 index 0000000..a08110c --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr104550-1.c @@ -0,0 +1,10 @@ +/* PR 104550*/ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=pattern" } */ +struct vx_audio_level { + int has_monitor_level : 1; +}; + +void vx_set_monitor_level() { + struct vx_audio_level info; /* { dg-bogus "info" "is used uninitialized" } */ +} diff --git a/gcc/testsuite/gcc.dg/auto-init-pr104550-2.c b/gcc/testsuite/gcc.dg/auto-init-pr104550-2.c new file mode 100644 index 0000000..2c395b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr104550-2.c @@ -0,0 +1,11 @@ +/* PR 104550 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=zero" } */ +struct vx_audio_level { + int has_monitor_level : 1; +}; + +void vx_set_monitor_level() { + struct vx_audio_level info; + __builtin_clear_padding (&info); /* { dg-bogus "info" "is used uninitialized" } */ +} diff --git a/gcc/testsuite/gcc.dg/auto-init-pr104550-3.c b/gcc/testsuite/gcc.dg/auto-init-pr104550-3.c new file mode 100644 index 0000000..9893e37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/auto-init-pr104550-3.c @@ -0,0 +1,11 @@ +/* PR 104550 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized -ftrivial-auto-var-init=pattern" } */ +struct vx_audio_level { + int has_monitor_level : 1; +}; + +void vx_set_monitor_level() { + struct vx_audio_level info; /* { dg-bogus "info" "is used uninitialized" } */ + __builtin_clear_padding (&info); /* { dg-bogus "info" "is used uninitialized" } */ +} diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c index 9049af5..0f350f4 100644 --- a/gcc/testsuite/gcc.dg/builtin-apply2.c +++ b/gcc/testsuite/gcc.dg/builtin-apply2.c @@ -1,7 +1,7 @@ /* { dg-do run } */ /* { dg-require-effective-target untyped_assembly } */ /* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "avr-*-* nds32*-*-* amdgcn-*-*" } } */ -/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "csky*-*-* riscv*-*-* or1k*-*-* msp430-*-* pru-*-*" } } */ +/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "csky*-*-* riscv*-*-* or1k*-*-* msp430-*-* pru-*-* loongarch*-*-*" } } */ /* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } } */ /* PR target/12503 */ diff --git a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c index dd8dc99..01a280b 100644 --- a/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c +++ b/gcc/testsuite/gcc.dg/builtin-dynamic-object-size-0.c @@ -8,6 +8,15 @@ void * __attribute__ ((alloc_size (1))) __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((noinline)) +alloc_func_long (long sz) +{ + return __builtin_malloc (sz); +} + +void * +__attribute__ ((alloc_size (1))) +__attribute__ ((__nothrow__ , __leaf__)) +__attribute__ ((noinline)) alloc_func (size_t sz) { return __builtin_malloc (sz); @@ -145,6 +154,16 @@ test_builtin_malloc_condphi5 (size_t sz, int cond, char *c) return ret; } +long +__attribute__ ((noinline)) +test_builtin_malloc_long (long sz, long off) +{ + char *a = alloc_func_long (sz); + char *dest = a + off; + long ret = __builtin_dynamic_object_size (dest, 0); + return ret; +} + /* Calloc-like allocator. */ size_t @@ -304,6 +323,34 @@ test_substring (size_t sz, size_t off) return __builtin_dynamic_object_size (&str[off], 0); } +struct S2 +{ + char arr[7]; +}; + +struct S1 +{ + int pad; + struct S2 s2; +}; + +static long +g (struct S1 *s1) +{ + struct S2 *s2 = &s1->s2; + return __builtin_dynamic_object_size (s2->arr, 0); +} + +long +__attribute__ ((noinline)) +test_alloc_nested_structs (int x) +{ + struct S1 *s1 = __builtin_malloc (x); + return g (s1); +} + +/* POINTER_PLUS expressions. */ + size_t __attribute__ ((noinline)) test_substring_ptrplus (size_t sz, size_t off) @@ -323,6 +370,8 @@ test_substring_ptrplus2 (size_t sz, size_t off, size_t off2) return __builtin_dynamic_object_size (ptr + off2, 0); } +/* Function parameters. */ + size_t __attribute__ ((access (__read_write__, 1, 2))) __attribute__ ((noinline)) @@ -332,6 +381,22 @@ test_parmsz_simple (void *obj, size_t sz) } size_t +__attribute__ ((access (__read_write__, 2, 1))) +__attribute__ ((noinline)) +test_parmsz_simple2 (size_t sz, char obj[]) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +/* Implicitly constructed access attributes not supported yet. */ +size_t +__attribute__ ((noinline)) +test_parmsz_simple3 (size_t sz, char obj[sz]) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +size_t __attribute__ ((noinline)) __attribute__ ((access (__read_write__, 1, 2))) test_parmsz (void *obj, size_t sz, size_t off) @@ -363,6 +428,40 @@ test_parmsz_unknown (void *obj, void *unknown, size_t sz, int cond) return __builtin_dynamic_object_size (cond ? obj : unknown, 0); } +struct S; +size_t +__attribute__ ((access (__read_write__, 1, 2))) +__attribute__ ((noinline)) +test_parmsz_extern (struct S *obj, size_t sz) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +/* Implicitly constructed access attributes not supported yet. */ +size_t +__attribute__ ((noinline)) +test_parmsz_internal (size_t sz, double obj[][sz]) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +size_t +__attribute__ ((access (__read_write__, 2, 1))) +__attribute__ ((noinline)) +test_parmsz_internal2 (size_t sz, double obj[][sz]) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +size_t +__attribute__ ((noinline)) +test_parmsz_internal3 (size_t sz1, size_t sz2, double obj[sz1][sz2]) +{ + return __builtin_dynamic_object_size (obj, 0); +} + +/* Loops. */ + size_t __attribute__ ((noinline)) __attribute__ ((access (__read_write__, 1, 2))) @@ -380,6 +479,20 @@ test_loop (int *obj, size_t sz, size_t start, size_t end, int incr) return __builtin_dynamic_object_size (ptr, 0); } +/* Other tests. */ + +struct TV4 +{ + __attribute__((vector_size (sizeof (int) * 4))) int v; +}; + +struct TV4 val3; +int * +test_pr105736 (struct TV4 *a) +{ + return &a->v[0]; +} + unsigned nfails = 0; #define FAIL() ({ \ @@ -419,6 +532,9 @@ main (int argc, char **argv) FAIL (); if (test_builtin_malloc_condphi5 (128, 0, argv[0]) != -1) FAIL (); + long x = 42; + if (test_builtin_malloc_long (x, 0) != x) + FAIL (); if (test_calloc (2048, 4) != 2048 * 4) FAIL (); if (test_builtin_calloc (2048, 8) != 2048 * 8) @@ -469,6 +585,8 @@ main (int argc, char **argv) FAIL (); if (test_dynarray_cond (1) != 8) FAIL (); + if (test_alloc_nested_structs (42) != 42 - sizeof (int)) + FAIL (); if (test_deploop (128, 4) != 128) FAIL (); if (test_deploop (128, 129) != 32) @@ -476,9 +594,22 @@ main (int argc, char **argv) if (test_parmsz_simple (argv[0], __builtin_strlen (argv[0]) + 1) != __builtin_strlen (argv[0]) + 1) FAIL (); + if (test_parmsz_simple2 (__builtin_strlen (argv[0]) + 1, argv[0]) + != __builtin_strlen (argv[0]) + 1) + FAIL (); + /* Only explicitly added access attributes are supported for now. */ + if (test_parmsz_simple3 (__builtin_strlen (argv[0]) + 1, argv[0]) != -1) + FAIL (); int arr[42]; if (test_parmsz_scaled (arr, 42) != sizeof (arr)) FAIL (); + if (test_parmsz_scaled (arr, 40) != 40 * sizeof (int)) + FAIL (); + /* __bdos cannot see the actual size of ARR, so it will return what it was + passed. Fortunately though the overflow warnings see this caller side and + warns of the problematic size. */ + if (test_parmsz_scaled (arr, 44) != 44 * sizeof (int)) /* { dg-warning "-Wstringop-overflow=" } */ + FAIL (); if (test_parmsz_unknown (argv[0], argv[0], __builtin_strlen (argv[0]) + 1, 0) != -1) if (test_parmsz (argv[0], __builtin_strlen (argv[0]) + 1, -1) != 0) @@ -494,6 +625,16 @@ main (int argc, char **argv) FAIL (); if (test_parmsz_scaled_off (arr, 42, 2) != 40 * sizeof (int)) FAIL (); + struct S *s; + if (test_parmsz_extern (s, 42) != -1) + FAIL (); + double obj[4][4]; + if (test_parmsz_internal (4, obj) != -1) + FAIL (); + if (test_parmsz_internal2 (4, obj) != -1) + FAIL (); + if (test_parmsz_internal3 (4, 4, obj) != -1) + FAIL (); if (test_loop (arr, 42, 0, 32, 1) != 10 * sizeof (int)) FAIL (); if (test_loop (arr, 42, 32, -1, -1) != 0) @@ -506,6 +647,10 @@ main (int argc, char **argv) FAIL (); if (test_loop (arr, 42, 20, 52, 1) != 0) FAIL (); + /* pr105736. */ + int *t = test_pr105736 (&val3); + if (__builtin_dynamic_object_size (t, 0) != -1) + FAIL (); if (nfails > 0) __builtin_abort (); diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-20.c b/gcc/testsuite/gcc.dg/builtin-object-size-20.c index bed973c..f40e3dc 100644 --- a/gcc/testsuite/gcc.dg/builtin-object-size-20.c +++ b/gcc/testsuite/gcc.dg/builtin-object-size-20.c @@ -1,7 +1,8 @@ /* PR middle-end/92815 - spurious -Wstringop-overflow writing into a flexible array of an extern struct { dg-do compile } - { dg-options "-O -Wall -fdump-tree-optimized" } */ + { dg-options "-O -Wall -fdump-tree-optimized" } + { dg-skip-if "test assumes that structs have padding" { default_packed } } */ #define ASSERT(expr) ((expr) ? (void)0 : fail (__LINE__)) #define bos0(expr) __builtin_object_size (expr, 1) @@ -18,44 +19,6 @@ typedef __SIZE_TYPE__ size_t; extern void fail (int); -/* Verify sizes of a struct with a flexible array member and no padding. */ - -struct ACX { char n, a[]; }; - -struct ACX ac0 = { }; -struct ACX ac1 = { 1, { 1 } }; -struct ACX ac2 = { 2, { 1, 2 } }; -struct ACX ac3 = { 3, { 1, 2, 3 } }; - -extern struct ACX eacx; - -void facx (void) -{ - ASSERT (bos0 (&ac0) == sizeof ac0); - ASSERT (bos0 (&ac1) == 2); - ASSERT (bos0 (&ac2) == 3); - ASSERT (bos0 (&ac3) == 4); - ASSERT (bos0 (&eacx) == (size_t)-1); - - ASSERT (bos1 (&ac0) == sizeof ac0); - ASSERT (bos1 (&ac1) == 2); - ASSERT (bos1 (&ac2) == 3); - ASSERT (bos1 (&ac3) == 4); - ASSERT (bos1 (&eacx) == (size_t)-1); - - ASSERT (bos2 (&ac0) == sizeof ac0); - ASSERT (bos2 (&ac1) == 2); - ASSERT (bos2 (&ac2) == 3); - ASSERT (bos2 (&ac3) == 4); - ASSERT (bos2 (&eacx) == sizeof eacx); - - ASSERT (bos3 (&ac0) == sizeof ac0); - ASSERT (bos3 (&ac1) == 2); - ASSERT (bos3 (&ac2) == 3); - ASSERT (bos3 (&ac3) == 4); - ASSERT (bos3 (&eacx) == sizeof eacx); -} - /* Verify sizes of a struct with a flexible array member and 1 byte @@ -289,27 +252,4 @@ void fai64cx (void) ASSERT (bos3 (&eai64cx) == sizeof eai64cx); } - -/* Also verify sizes of a struct with a zero length array member. */ - -struct A0C0 { char n, a[0]; }; - -struct A0C0 a0c0 = { }; -extern struct A0C0 ea0c0; - -void fa0c0 (void) -{ - ASSERT (bos0 (&a0c0) == sizeof a0c0); - ASSERT (bos0 (&ea0c0) == sizeof ea0c0); - - ASSERT (bos1 (&a0c0) == sizeof a0c0); - ASSERT (bos1 (&a0c0) == sizeof ea0c0); - - ASSERT (bos2 (&a0c0) == sizeof a0c0); - ASSERT (bos2 (&a0c0) == sizeof ea0c0); - - ASSERT (bos3 (&a0c0) == sizeof a0c0); - ASSERT (bos3 (&a0c0) == sizeof ea0c0); -} - /* { dg-final { scan-tree-dump-not "fail" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-22.c b/gcc/testsuite/gcc.dg/builtin-object-size-22.c new file mode 100644 index 0000000..1e55229 --- /dev/null +++ b/gcc/testsuite/gcc.dg/builtin-object-size-22.c @@ -0,0 +1,79 @@ +/* PR middle-end/92815 - a variant of gcc.dg/builtin-object-size-20.c + prepared for all targets, irregardless if they pack or not + the structs by default. + { dg-do compile } + { dg-options "-O -Wall -fdump-tree-optimized" } */ + +#define ASSERT(expr) ((expr) ? (void)0 : fail (__LINE__)) +#define bos0(expr) __builtin_object_size (expr, 1) +#define bos1(expr) __builtin_object_size (expr, 1) +#define bos2(expr) __builtin_object_size (expr, 2) +#define bos3(expr) __builtin_object_size (expr, 3) + +typedef __SIZE_TYPE__ size_t; + + +extern void fail (int); + + +/* Verify sizes of a struct with a flexible array member and no padding. */ + +struct ACX { char n, a[]; }; + +struct ACX ac0 = { }; +struct ACX ac1 = { 1, { 1 } }; +struct ACX ac2 = { 2, { 1, 2 } }; +struct ACX ac3 = { 3, { 1, 2, 3 } }; + +extern struct ACX eacx; + +void facx (void) +{ + ASSERT (bos0 (&ac0) == sizeof ac0); + ASSERT (bos0 (&ac1) == 2); + ASSERT (bos0 (&ac2) == 3); + ASSERT (bos0 (&ac3) == 4); + ASSERT (bos0 (&eacx) == (size_t)-1); + + ASSERT (bos1 (&ac0) == sizeof ac0); + ASSERT (bos1 (&ac1) == 2); + ASSERT (bos1 (&ac2) == 3); + ASSERT (bos1 (&ac3) == 4); + ASSERT (bos1 (&eacx) == (size_t)-1); + + ASSERT (bos2 (&ac0) == sizeof ac0); + ASSERT (bos2 (&ac1) == 2); + ASSERT (bos2 (&ac2) == 3); + ASSERT (bos2 (&ac3) == 4); + ASSERT (bos2 (&eacx) == sizeof eacx); + + ASSERT (bos3 (&ac0) == sizeof ac0); + ASSERT (bos3 (&ac1) == 2); + ASSERT (bos3 (&ac2) == 3); + ASSERT (bos3 (&ac3) == 4); + ASSERT (bos3 (&eacx) == sizeof eacx); +} + +/* Also verify sizes of a struct with a zero length array member. */ + +struct A0C0 { char n, a[0]; }; + +struct A0C0 a0c0 = { }; +extern struct A0C0 ea0c0; + +void fa0c0 (void) +{ + ASSERT (bos0 (&a0c0) == sizeof a0c0); + ASSERT (bos0 (&ea0c0) == sizeof ea0c0); + + ASSERT (bos1 (&a0c0) == sizeof a0c0); + ASSERT (bos1 (&a0c0) == sizeof ea0c0); + + ASSERT (bos2 (&a0c0) == sizeof a0c0); + ASSERT (bos2 (&a0c0) == sizeof ea0c0); + + ASSERT (bos3 (&a0c0) == sizeof a0c0); + ASSERT (bos3 (&a0c0) == sizeof ea0c0); +} + +/* { dg-final { scan-tree-dump-not "fail" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/c11-align-4.c b/gcc/testsuite/gcc.dg/c11-align-4.c index 57f93ff..eb9071b 100644 --- a/gcc/testsuite/gcc.dg/c11-align-4.c +++ b/gcc/testsuite/gcc.dg/c11-align-4.c @@ -2,7 +2,7 @@ are at least some alignment constraints). */ /* { dg-do compile } */ /* { dg-options "-std=c11 -pedantic-errors" } */ -/* { dg-skip-if "no alignment constraints" { "avr-*-*" } } */ +/* { dg-skip-if "no alignment constraints" { no_alignment_constraints } } */ #include <stddef.h> diff --git a/gcc/testsuite/gcc.dg/c11-unproto-1.c b/gcc/testsuite/gcc.dg/c11-unproto-1.c index ea9e807..0949c7b 100644 --- a/gcc/testsuite/gcc.dg/c11-unproto-1.c +++ b/gcc/testsuite/gcc.dg/c11-unproto-1.c @@ -1,6 +1,7 @@ -/* Test compatibility of unprototyped and prototyped function types (C2x makes - the case of types affected by default argument promotions compatible). Test - valid-in-C2x usages are not accepted for C11. */ +/* Test compatibility of unprototyped and prototyped function types (C2x made + the case of types affected by default argument promotions compatible, before + removing unprototyped functions completely). Test affected usages are not + accepted for C11. */ /* { dg-do compile } */ /* { dg-options "-std=c11 -pedantic-errors" } */ diff --git a/gcc/testsuite/gcc.dg/c11-unproto-2.c b/gcc/testsuite/gcc.dg/c11-unproto-2.c index 0557ae3..06da935 100644 --- a/gcc/testsuite/gcc.dg/c11-unproto-2.c +++ b/gcc/testsuite/gcc.dg/c11-unproto-2.c @@ -1,6 +1,7 @@ -/* Test compatibility of unprototyped and prototyped function types (C2x makes - the case of types affected by default argument promotions compatible). Test - invalid-in-C2x usages, in C11 mode. */ +/* Test compatibility of unprototyped and prototyped function types (C2x made + the case of types affected by default argument promotions compatible, before + removing unprototyped functions completely). Test always-invalid-in-C2x + usages, in C11 mode. */ /* { dg-do compile } */ /* { dg-options "-std=c11 -pedantic-errors" } */ diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-1.c b/gcc/testsuite/gcc.dg/c2x-unproto-1.c index 45d68f2..aa87d78 100644 --- a/gcc/testsuite/gcc.dg/c2x-unproto-1.c +++ b/gcc/testsuite/gcc.dg/c2x-unproto-1.c @@ -1,20 +1,25 @@ -/* Test compatibility of unprototyped and prototyped function types (C2x makes - the case of types affected by default argument promotions compatible). Test - valid-in-C2x usages. */ +/* Test compatibility of unprototyped and prototyped function types (C2x made + the case of types affected by default argument promotions compatible, before + removing unprototyped functions completely). Test affected usages are not + accepted for C2x. */ /* { dg-do compile } */ /* { dg-options "-std=c2x -pedantic-errors" } */ -void f1 (); -void f1 (float); +void f1 (); /* { dg-message "previous declaration" } */ +void f1 (float); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ -void f2 (float); -void f2 (); +void f2 (float); /* { dg-message "previous declaration" } */ +void f2 (); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ -void f3 (); -void f3 (char); +void f3 (); /* { dg-message "previous declaration" } */ +void f3 (char); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ -void f4 (char); -void f4 (); +void f4 (char); /* { dg-message "previous declaration" } */ +void f4 (); /* { dg-error "conflicting types" } */ +/* { dg-message "default promotion" "" { target *-*-* } .-1 } */ /* Built-in function case. */ -float sqrtf (); +float sqrtf (); /* { dg-warning "conflicting types for built-in function" } */ diff --git a/gcc/testsuite/gcc.dg/c2x-unproto-2.c b/gcc/testsuite/gcc.dg/c2x-unproto-2.c index f826b7c..3d5ae9d 100644 --- a/gcc/testsuite/gcc.dg/c2x-unproto-2.c +++ b/gcc/testsuite/gcc.dg/c2x-unproto-2.c @@ -1,6 +1,7 @@ -/* Test compatibility of unprototyped and prototyped function types (C2x makes - the case of types affected by default argument promotions compatible). Test - invalid-in-C2x usages. */ +/* Test compatibility of unprototyped and prototyped function types (C2x made + the case of types affected by default argument promotions compatible, before + removing unprototyped functions completely). Test always-invalid-in-C2x + usages, in C2X mode. */ /* { dg-do compile } */ /* { dg-options "-std=c2x -pedantic-errors" } */ diff --git a/gcc/testsuite/gcc.dg/compat/pr102024_main.c b/gcc/testsuite/gcc.dg/compat/pr102024_main.c new file mode 100644 index 0000000..8aa78da --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/pr102024_main.c @@ -0,0 +1,22 @@ +/* { dg-require-effective-target int32plus } */ +/* { dg-options "-Wno-abi" } */ +/* { dg-options "-mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } */ +/* { dg-options "-mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* x86_64-*-darwin* } } */ +/* { dg-options "-mno-base-addresses" { target mmix-*-* } } */ +/* { dg-options "-mlongcalls -mtext-section-literals" { target xtensa*-*-* } } */ +/* { dg-prune-output ".*-Wno-abi.*" } */ +/* { dg-prune-output ".*Offset of packed bit-field.*" } */ +#include "struct-layout-1.h" + +#define TX(n, type, attrs, fields, ops) extern void test##n (void); +#include "pr102024_test.h" +#undef TX + +int main (void) +{ +#define TX(n, type, attrs, fields, ops) test##n (); +#include "pr102024_test.h" +#undef TX + exit (fails != 0); +} diff --git a/gcc/testsuite/gcc.dg/compat/pr102024_test.h b/gcc/testsuite/gcc.dg/compat/pr102024_test.h new file mode 100644 index 0000000..d610dbd --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/pr102024_test.h @@ -0,0 +1,12 @@ +T(0,float a;int:0;float b;,F(0,a,42.0f,43.125f)F(0,b,-17.5f,35.75f)) +T(1,float a;int:0;,F(1,a,1.0f,17.125f)) +T(2,int:0;float a;,F(2,a,2.25f,16.5f)) +T(3,double a;long long:0;double b;,F(3,a,42.0,43.125)F(3,b,-17.5,35.75)) +T(4,double a;long long:0;,F(4,a,1.0,17.125)) +T(5,long long:0;double a;,F(5,a,2.25,16.5)) +T(6,float a;struct{}b;float c;,F(6,a,42.0f,43.125f)F(6,c,-17.5f,35.75f)) +T(7,float a;struct{}b[0];;,F(7,a,1.0f,17.125f)) +T(8,int a[0];float b;,F(8,b,2.25f,16.5f)) +T(9,double a;long long b[0];double c;,F(9,a,42.0,43.125)F(9,c,-17.5,35.75)) +T(10,double a;struct{}b;,F(10,a,1.0,17.125)) +T(11,struct{}a[0];double b;,F(11,b,2.25,16.5)) diff --git a/gcc/testsuite/gcc.dg/compat/pr102024_x.c b/gcc/testsuite/gcc.dg/compat/pr102024_x.c new file mode 100644 index 0000000..de20752 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/pr102024_x.c @@ -0,0 +1,10 @@ +/* { dg-options "-w -Wno-abi" } */ +/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } */ +/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* x86_64-*-darwin* } } */ +/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */ +/* { dg-options "-w -mlongcalls -mtext-section-literals" { target xtensa*-*-* } } */ +#include "struct-layout-1_x1.h" +#include "pr102024_test.h" +#include "struct-layout-1_x2.h" +#include "pr102024_test.h" diff --git a/gcc/testsuite/gcc.dg/compat/pr102024_y.c b/gcc/testsuite/gcc.dg/compat/pr102024_y.c new file mode 100644 index 0000000..a3f8396 --- /dev/null +++ b/gcc/testsuite/gcc.dg/compat/pr102024_y.c @@ -0,0 +1,10 @@ +/* { dg-options "-w -Wno-abi" } */ +/* { dg-options "-w -mno-mmx -Wno-abi" { target i?86-*-* x86_64-*-* } } */ +/* { dg-options "-w -fno-common" { target hppa*-*-hpux* powerpc*-*-darwin* } } */ +/* { dg-options "-w -mno-mmx -fno-common -Wno-abi" { target i?86-*-darwin* x86_64-*-darwin* } } */ +/* { dg-options "-w -mno-base-addresses" { target mmix-*-* } } */ +/* { dg-options "-w -mlongcalls -mtext-section-literals" { target xtensa*-*-* } } */ +#include "struct-layout-1_y1.h" +#include "pr102024_test.h" +#include "struct-layout-1_y2.h" +#include "pr102024_test.h" diff --git a/gcc/testsuite/gcc.dg/complex-6.c b/gcc/testsuite/gcc.dg/complex-6.c index a7eae1e..cfbfc07 100644 --- a/gcc/testsuite/gcc.dg/complex-6.c +++ b/gcc/testsuite/gcc.dg/complex-6.c @@ -10,4 +10,4 @@ foo (__complex float a, __complex float b) } /* { dg-final { scan-tree-dump-times "unord" 1 "cplxlower1" { target { ! rx*-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "__mulsc3" 1 "cplxlower1" { target { ! rx*-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "__(?:gnu_)?mulsc3" 1 "cplxlower1" { target { ! rx*-*-* } } } } */ diff --git a/gcc/testsuite/gcc.dg/complex-7.c b/gcc/testsuite/gcc.dg/complex-7.c index a1f136c..659ae40 100644 --- a/gcc/testsuite/gcc.dg/complex-7.c +++ b/gcc/testsuite/gcc.dg/complex-7.c @@ -11,4 +11,4 @@ foo (__complex double a, __complex double b) } /* { dg-final { scan-tree-dump-times "unord" 1 "cplxlower1" } } */ -/* { dg-final { scan-tree-dump-times "__muldc3" 1 "cplxlower1" } } */ +/* { dg-final { scan-tree-dump-times "__(?:gnu_)?muldc3" 1 "cplxlower1" } } */ diff --git a/gcc/testsuite/gcc.dg/darwin-comm-1.c b/gcc/testsuite/gcc.dg/darwin-comm-1.c index 4651998..2ea11d6 100644 --- a/gcc/testsuite/gcc.dg/darwin-comm-1.c +++ b/gcc/testsuite/gcc.dg/darwin-comm-1.c @@ -1,5 +1,6 @@ -/* { dg-do compile { target *-*-darwin[912]* } } */ +/* { dg-do compile { target *-*-darwin* } } */ /* { dg-options "-fcommon" } */ /* In all cases, common has a max alignment of 2^15. */ -int badcommon __attribute__ ((aligned (65536))); /* { dg-error "common variables must have an alignment" } */ +int badcommon __attribute__ ((aligned (65536))); /* { dg-error "common variables must have an alignment" "" { target { *-*-darwin1[1-9]* *-*-darwin2* } } } */ +/* { dg-error "requested alignment .65536. exceeds object file maximum 32768" "" { target { *-*-darwin[4-9]* *-*-darwin10* } } .-1 } */
\ No newline at end of file diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c index c6bf521..793b4c8 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-1.c @@ -5,16 +5,19 @@ (bit_size << 24) | bit_offset - (0xa << 24) | 0x20 - (0x7 << 24) | 0x2a - - (0x13 << 24) | 0x40 - note that this is aligned to 0x40. */ + - (0x13 << 24) | 0x40 - note that this is aligned to 0x40. + - (0x13 << 24) | 0x31 - in case structures are packed. */ /* { dg-do compile ) */ /* { dg-options "-O0 -gbtf -dA" } */ +/* { dg-require-effective-target int32plus } */ /* { dg-final { scan-assembler-times "\[\t \]0x84000004\[\t \]+\[^\n\]*btt_info" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0xa000020\[\t \]+\[^\n\]*btm_offset" 1 } } */ /* { dg-final { scan-assembler-times "\[\t \]0x700002a\[\t \]+\[^\n\]*btm_offset" 1 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x13000040\[\t \]+\[^\n\]*btm_offset" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x13000040\[\t \]+\[^\n\]*btm_offset" 1 { target { ! default_packed } } } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x13000031\[\t \]+\[^\n\]*btm_offset" 1 { target { default_packed } } } } */ struct bitt { int a; diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c index dbb236b..77df886 100644 --- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c +++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c @@ -12,6 +12,7 @@ /* { dg-do compile ) */ /* { dg-options "-O0 -gbtf -dA" } */ /* { dg-options "-O0 -gbtf -dA -msdata=none" { target { { powerpc*-*-* } && ilp32 } } } */ +/* { dg-options "-O0 -gbtf -dA -msmall-data-limit=0" { target { riscv*-*-* } } } */ /* { dg-options "-O0 -gbtf -dA -G0" { target { nios2-*-* } } } */ /* Check for two DATASEC entries with vlen 3, and one with vlen 1. */ diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c index 2a19da0..4721c4f 100644 --- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-2.c @@ -5,34 +5,26 @@ TBD_CTF_FORMAT_OPEN_ISSUES (1) - This testcase makes a note of the case of a probable misrepresentation. - See Note 1 and Note 2 below. + See Note 1 below. In the CTF section, these types are encoded as : Variables: - _CTF_NEWSTR -> 7: const char [0] (size 0x0) - _CTF_SECTION -> 6: const char [5] (size 0x5) - b1 -> 2: int [0] (size 0x0) - b2 -> 3: int [0] (size 0x0) + b1 -> 3: int [0] (size 0x0) + b2 -> 5: int [0] (size 0x0) Note 1 : There is misrepresentation in that b1 and b2 are specified differently by the user. - Note 2 : It is arguable though whether the representation for - _CTF_NEWSTR is incorrect. */ + + In this testcase, two CTF array records each of type int [0] is expected. */ /* { dg-do compile ) */ /* { dg-options "-O0 -gctf -dA" } */ -/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 5 } } */ +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 3 } } */ -/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 2 } } */ static int b1[] = {}; int b2[0]; - -const char _CTF_SECTION[] = ".ctf"; - -extern const char _CTF_NEWSTR[]; -const char _CTF_NEWSTR[] = "ctfinfo"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c new file mode 100644 index 0000000..ec50441 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-array-5.c @@ -0,0 +1,17 @@ +/* CTF generation for unsized (but initialized) arrays + + In this testcase, one CTF array type record of size 5 is expected. + + Variables: + _CTF_SECTION -> 5: const const char [5] (size 0x5) -> 4: const char [5] (size 0x5) + +*/ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 1 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0x5\[\t \]+\[^\n\]*cta_nelems" 1 } } */ + +const char _CTF_SECTION[] = ".ctf"; diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c new file mode 100644 index 0000000..8aea1e8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-variables-3.c @@ -0,0 +1,22 @@ +/* CTF generation for extern variable with defining and non-defining decl + in the same CU. + + This testcase checks the case when a non-defining decl is followed by + a defining decl for the same variable. See PR debug/105089. + + In this testcase, although two CTF array types are generated, only a + single CTF variable and a single entry in the CTF object info section + are expected. */ + +/* { dg-do compile ) */ +/* { dg-options "-O0 -gctf -dA" } */ + +/* { dg-final { scan-assembler-times "0x12000000\[\t \]+\[^\n\]*ctt_info" 2 } } */ + +/* { dg-final { scan-assembler-times "\[\t \]0\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "\[\t \]0x8\[\t \]+\[^\n\]*cta_nelems" 1 } } */ +/* { dg-final { scan-assembler-times "ctv_name" 1 } } */ +/* { dg-final { scan-assembler-times "objtinfo_var_type" 1 } } */ + +extern const char _CTF_NEWSTR[]; +const char _CTF_NEWSTR[] = "ctfinfo"; diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c index eee5471..f8da702 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-1.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal128. Bug 91226. */ -/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O2" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c index 6267121..dade48f 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-2.c @@ -1,6 +1,7 @@ /* Test non-canonical BID significands: _Decimal128, case where combination field starts 11. Bug 91226. */ -/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O2" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c index 9190dae..77c0941 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-3.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal128. Bug 91226. */ -/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O0" } */ #include "bid-non-canonical-d128-1.c" diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c index b148ce4..93ff0fc 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d128-4.c @@ -1,6 +1,7 @@ /* Test non-canonical BID significands: _Decimal128, case where combination field starts 11. Bug 91226. */ -/* { dg-do run { target { { i?86-*-* x86_64-*-* } && lp64 } } } */ +/* { dg-do run { target lp64 } } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O0" } */ #include "bid-non-canonical-d128-2.c" diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c index b46b71c..69d014f 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-1.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal32. Bug 91226. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O2" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c index 11d64dc..874b2fb 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d32-2.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal32. Bug 91226. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O0" } */ #include "bid-non-canonical-d32-1.c" diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c index 87b1069..4602d34 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-1.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal64. Bug 91226. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O2" } */ extern void abort (void); diff --git a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c index 3c10145..c2993b6 100644 --- a/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c +++ b/gcc/testsuite/gcc.dg/dfp/bid-non-canonical-d64-2.c @@ -1,5 +1,6 @@ /* Test non-canonical BID significands: _Decimal64. Bug 91226. */ -/* { dg-do run { target i?86-*-* x86_64-*-* } } */ +/* { dg-do run } */ +/* { dg-require-effective-target dfp_bid } */ /* { dg-options "-std=gnu2x -O0" } */ #include "bid-non-canonical-d64-1.c" diff --git a/gcc/testsuite/gcc.dg/dfp/pr104557.c b/gcc/testsuite/gcc.dg/dfp/pr104557.c new file mode 100644 index 0000000..a4a1cc6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/dfp/pr104557.c @@ -0,0 +1,22 @@ +/* PR debug/104557 */ +/* { dg-do compile } */ +/* { dg-options "-O -g -Wno-psabi" } */ + +typedef int __attribute__((__vector_size__ (32))) U; +typedef double __attribute__((__vector_size__ (32))) F; +typedef _Decimal64 __attribute__((__vector_size__ (32))) D; + +F +bar (void) +{ + F f = __builtin_convertvector ((D) (-10.d < (D) ((D) (U) { 0, 0, 0, 0, 0, 0, 0, -0xe0 } + >= (D) { 80000000 })), F); + return f; +} + +F +foo () +{ + F x = bar (); + return x; +} diff --git a/gcc/testsuite/gcc.dg/di-sync-multithread.c b/gcc/testsuite/gcc.dg/di-sync-multithread.c index 493f1e2..1a97df7 100644 --- a/gcc/testsuite/gcc.dg/di-sync-multithread.c +++ b/gcc/testsuite/gcc.dg/di-sync-multithread.c @@ -70,6 +70,8 @@ worker (void* data) case this to carry across the 32bit boundary. */ for (tmp2 = 0; tmp2 < 64; tmp2++) { + sched_yield (); + /* Add 2 using the two different adds. */ tmp1 = __sync_add_and_fetch (&workspace, add1bit); tmp3 = __sync_fetch_and_add (&workspace, add1bit); @@ -103,6 +105,8 @@ worker (void* data) for (tmp2 = 0; tmp2 < 64; tmp2++) { + sched_yield (); + /* Subtract 2 using the two different subs. */ tmp1=__sync_sub_and_fetch (&workspace, add1bit); tmp3=__sync_fetch_and_sub (&workspace, add1bit); @@ -178,6 +182,8 @@ main () t, err); }; + sched_yield (); + #ifdef _WIN32 Sleep (5000); #else @@ -187,6 +193,8 @@ main () /* Stop please. */ __sync_lock_test_and_set (&doquit, 1ll); + sched_yield (); + for (t = 0; t < 3; t++) { err=pthread_join (threads[t], NULL); diff --git a/gcc/testsuite/gcc.dg/fixed-point/composite-type.c b/gcc/testsuite/gcc.dg/fixed-point/composite-type.c index 026bdaf..59351ff 100644 --- a/gcc/testsuite/gcc.dg/fixed-point/composite-type.c +++ b/gcc/testsuite/gcc.dg/fixed-point/composite-type.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-std=gnu99 -O -Wall -Wno-unused -ftrack-macro-expansion=0" } */ +/* { dg-options "-std=gnu99 -O -Wall -Wno-unused -ftrack-macro-expansion=0 -Wno-array-parameter" } */ /* C99 6.2.7: Compatible type and composite type. */ diff --git a/gcc/testsuite/gcc.dg/fold-convlshift-4.c b/gcc/testsuite/gcc.dg/fold-convlshift-4.c new file mode 100644 index 0000000..001627f --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-convlshift-4.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +short foo(short x) +{ + return x << 5; +} + +/* { dg-final { scan-tree-dump-not "\\(int\\)" "optimized" } } */ +/* { dg-final { scan-tree-dump-not "\\(short int\\)" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/fold-reduc-1.c b/gcc/testsuite/gcc.dg/fold-reduc-1.c new file mode 100644 index 0000000..c8360b0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fold-reduc-1.c @@ -0,0 +1,19 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffast-math -fdump-tree-optimized" } */ +float foo (float x) +{ + int i; + float j; + float a = 0; + for (i = 0; i < 4; ++i) + { + for (j = 0; j < 4; ++j) + { + a += 1; + x += a; + } + } + return x; +} + +/* { dg-final { scan-tree-dump-not "REDUC_PLUS" "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c index 4583360..ca9b3e8 100644 --- a/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c +++ b/gcc/testsuite/gcc.dg/gcov-info-to-gcda.c @@ -17,16 +17,20 @@ __gcov_info_to_gcda (const struct gcov_info *__info, void *(*__allocate_fn) (unsigned, void *), void *__arg); +extern void +__gcov_filename_to_gcfn (const char *__filename, + void (*__dump_fn) (const void *, unsigned, void *), + void *__arg); + extern const struct gcov_info *my_info; static unsigned counter; -static void -filename (const char *f, void *arg) -{ - assert (arg == &counter); - assert (__builtin_strstr (f, "gcov-info-to-gcda.c") == 0); -} +static unsigned counter_after_filename; + +static int check_zero; + +static int check_after_filename; static void dump (const void *d, unsigned n, void *arg) @@ -37,12 +41,28 @@ dump (const void *d, unsigned n, void *arg) if (*m == 0) { const unsigned *u = d; + assert (*u == 0x6763666e); + check_zero = 1; + } + else if (*m == counter_after_filename) + { + const unsigned *u = d; assert (*u == 0x67636461); + check_after_filename = 1; } *m += n; } +static void +filename (const char *f, void *arg) +{ + assert (arg == &counter); + assert (__builtin_strstr (f, "gcov-info-to-gcda.c") == 0); + __gcov_filename_to_gcfn (f, dump, arg); + counter_after_filename = counter; +} + static void * allocate (unsigned length, void *arg) { @@ -54,6 +74,8 @@ int main() { __asm__ volatile (".set my_info, .LPBX2"); __gcov_info_to_gcda (my_info, filename, dump, allocate, &counter); - assert (counter > 4); + assert (counter > 8); + assert (check_zero); + assert (check_after_filename); return 0; } diff --git a/gcc/testsuite/gcc.dg/gimplefe-27.c b/gcc/testsuite/gcc.dg/gimplefe-27.c index 604a2cc..0053222 100644 --- a/gcc/testsuite/gcc.dg/gimplefe-27.c +++ b/gcc/testsuite/gcc.dg/gimplefe-27.c @@ -4,6 +4,8 @@ int __GIMPLE () p (int n) { int _2; - _2 = n_1(D) != 0 ? 2 : 0; + _Bool _3; + _3 = n_1(D) != 0; + _2 = _3 ? 2 : 0; return _2; } diff --git a/gcc/testsuite/gcc.dg/gimplefe-37.c b/gcc/testsuite/gcc.dg/gimplefe-37.c index d3ea186..12f6f64 100644 --- a/gcc/testsuite/gcc.dg/gimplefe-37.c +++ b/gcc/testsuite/gcc.dg/gimplefe-37.c @@ -22,6 +22,6 @@ main (int argc) /* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[count: 3" 2 "optimized" } } */ -/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[count: 2" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "<bb \[0-9\]> \\\[count: \[12\]" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[33\\\.33%\\\]" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times "goto <bb \[0-9\]>; \\\[66\\\.67%\\\]" 1 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/gimplefe-45.c b/gcc/testsuite/gcc.dg/gimplefe-45.c index b1d3cbb..8e1447f 100644 --- a/gcc/testsuite/gcc.dg/gimplefe-45.c +++ b/gcc/testsuite/gcc.dg/gimplefe-45.c @@ -10,10 +10,12 @@ p (int n) int *_2; int *_t; int *_t1; + _Bool _3; _t = (int*)8; _t1 = 0; n = n & 2; - _2 = n != 0 ? _t : _t1; + _3 = n != 0; + _2 = _3 ? _t : _t1; return _2; } diff --git a/gcc/testsuite/gcc.dg/gimplefe-49.c b/gcc/testsuite/gcc.dg/gimplefe-49.c new file mode 100644 index 0000000..d28dc70 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-49.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +__GIMPLE (ssa) int * +bar (int i, int a, int b) +{ + int * _3; + int *p; + +__BB(2): + if (i_24(D) <= 0) + goto __BB3; + else + goto __BB4; + +__BB(3): + _3 = &a; + goto __BB5; + +__BB(4): + p_4 = &b; + goto __BB5; + +__BB(5): + p_5 = __PHI (__BB3: _3, __BB4: p_4); + return p_5; +} diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-13.c b/gcc/testsuite/gcc.dg/gimplefe-error-13.c new file mode 100644 index 0000000..637ed32 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-13.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +__GIMPLE (ssa) void +bar (void) +{ + int _3; + +__BB(2): + return; +} /* { dg-error "version 3 has no definition" } */ diff --git a/gcc/testsuite/gcc.dg/gimplefe-error-14.c b/gcc/testsuite/gcc.dg/gimplefe-error-14.c new file mode 100644 index 0000000..3e1a132 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gimplefe-error-14.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-fgimple" } */ + +int __GIMPLE () foo () +{ + int _1; + return a_1(D); /* { dg-error "cannot have default definition" } */ +} diff --git a/gcc/testsuite/gcc.dg/goacc/nested-function-1.c b/gcc/testsuite/gcc.dg/goacc/nested-function-1.c index e17c0e2..2e48410 100644 --- a/gcc/testsuite/gcc.dg/goacc/nested-function-1.c +++ b/gcc/testsuite/gcc.dg/goacc/nested-function-1.c @@ -2,6 +2,22 @@ /* See gcc/testsuite/gfortran.dg/goacc/nested-function-1.f90 for the Fortran version. */ +/* { dg-additional-options "--param=openacc-kernels=decompose" } */ + +/* { dg-additional-options "-fopt-info-all-omp" } */ + +/* { dg-additional-options "--param=openacc-privatization=noisy" } + Prune a few: uninteresting, and potentially varying depending on GCC configuration (data types): + { dg-prune-output {note: variable 'D\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} } */ + +/* It's only with Tcl 8.5 (released in 2007) that "the variable 'varName' + passed to 'incr' may be unset, and in that case, it will be set to [...]", + so to maintain compatibility with earlier Tcl releases, we manually + initialize counter variables: + { dg-line l_dummy[variable c_compute_loop 0 c_loop 0] } + { dg-message dummy {} { target iN-VAl-Id } l_dummy } to avoid + "WARNING: dg-line var l_dummy defined, but not used". */ + int main () { #define N 100 @@ -25,32 +41,50 @@ int main () local_a[i] = 5; local_arg = 5; -#pragma acc kernels loop \ +#pragma acc kernels loop /* { dg-line l_compute_loop[incr c_compute_loop] } */ \ gang(num:local_arg) worker(local_arg) vector(local_arg) \ wait async(local_arg) + /* { dg-note {OpenACC 'kernels' decomposition: variable 'local_arg' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } + { dg-note {variable 'local_arg' made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_arg\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_i\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-optimized {assigned OpenACC seq loop parallelism} {} { target *-*-* } l_compute_loop$c_compute_loop } */ for (local_i = 0; local_i < N; ++local_i) { #pragma acc cache (local_a[local_i:5]) local_a[local_i] = 100; -#pragma acc loop seq tile(*) +#pragma acc loop seq tile(*) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'local_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (local_j = 0; local_j < N; ++local_j) ; -#pragma acc loop auto independent tile(1) +#pragma acc loop auto independent tile(1) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'local_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (local_j = 0; local_j < N; ++local_j) ; } -#pragma acc kernels loop \ +#pragma acc kernels loop /* { dg-line l_compute_loop[incr c_compute_loop] } */ \ gang(static:local_arg) worker(local_arg) vector(local_arg) \ wait(local_arg, local_arg + 1, local_arg + 2) async + /* { dg-note {OpenACC 'kernels' decomposition: variable 'local_arg' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } + { dg-note {variable 'local_arg' already made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_arg\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_i\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'local_i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-optimized {assigned OpenACC seq loop parallelism} {} { target *-*-* } l_compute_loop$c_compute_loop } */ for (local_i = 0; local_i < N; ++local_i) { #pragma acc cache (local_a[local_i:4]) local_a[local_i] = 100; -#pragma acc loop seq tile(1) +#pragma acc loop seq tile(1) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'local_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (local_j = 0; local_j < N; ++local_j) ; -#pragma acc loop auto independent tile(*) +#pragma acc loop auto independent tile(*) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'local_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (local_j = 0; local_j < N; ++local_j) ; } @@ -62,32 +96,50 @@ int main () nonlocal_a[i] = 5; nonlocal_arg = 5; -#pragma acc kernels loop \ +#pragma acc kernels loop /* { dg-line l_compute_loop[incr c_compute_loop] } */ \ gang(num:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) \ wait async(nonlocal_arg) + /* { dg-note {OpenACC 'kernels' decomposition: variable 'nonlocal_arg' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } + { dg-note {variable 'nonlocal_arg' made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_arg\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_i\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-optimized {assigned OpenACC seq loop parallelism} {} { target *-*-* } l_compute_loop$c_compute_loop } */ for (nonlocal_i = 0; nonlocal_i < N; ++nonlocal_i) { #pragma acc cache (nonlocal_a[nonlocal_i:3]) nonlocal_a[nonlocal_i] = 100; -#pragma acc loop seq tile(2) +#pragma acc loop seq tile(2) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'nonlocal_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) ; -#pragma acc loop auto independent tile(3) +#pragma acc loop auto independent tile(3) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'nonlocal_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) ; } -#pragma acc kernels loop \ +#pragma acc kernels loop /* { dg-line l_compute_loop[incr c_compute_loop] } */ \ gang(static:nonlocal_arg) worker(nonlocal_arg) vector(nonlocal_arg) \ wait(nonlocal_arg, nonlocal_arg + 1, nonlocal_arg + 2) async + /* { dg-note {OpenACC 'kernels' decomposition: variable 'nonlocal_arg' in 'copy' clause requested to be made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } + { dg-note {variable 'nonlocal_arg' already made addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {forwarded loop nest in OpenACC 'kernels' region to 'parloops' for analysis} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_arg\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_i\.[0-9]+' declared in block isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-note {variable 'nonlocal_i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_compute_loop$c_compute_loop } */ + /* { dg-optimized {assigned OpenACC seq loop parallelism} {} { target *-*-* } l_compute_loop$c_compute_loop } */ for (nonlocal_i = 0; nonlocal_i < N; ++nonlocal_i) { #pragma acc cache (nonlocal_a[nonlocal_i:2]) nonlocal_a[nonlocal_i] = 100; -#pragma acc loop seq tile(*) +#pragma acc loop seq tile(*) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'nonlocal_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) ; -#pragma acc loop auto independent tile(*) +#pragma acc loop auto independent tile(*) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'nonlocal_j' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ for (nonlocal_j = 0; nonlocal_j < N; ++nonlocal_j) ; } diff --git a/gcc/testsuite/gcc.dg/goacc/nested-function-2.c b/gcc/testsuite/gcc.dg/goacc/nested-function-2.c index 70c9ec8..4070069 100644 --- a/gcc/testsuite/gcc.dg/goacc/nested-function-2.c +++ b/gcc/testsuite/gcc.dg/goacc/nested-function-2.c @@ -1,5 +1,17 @@ /* Exercise nested function decomposition, gcc/tree-nested.c. */ +/* { dg-additional-options "-fopt-info-all-omp" } */ + +/* { dg-additional-options "--param=openacc-privatization=noisy" } */ + +/* It's only with Tcl 8.5 (released in 2007) that "the variable 'varName' + passed to 'incr' may be unset, and in that case, it will be set to [...]", + so to maintain compatibility with earlier Tcl releases, we manually + initialize counter variables: + { dg-line l_dummy[variable c_loop 0] } + { dg-message dummy {} { target iN-VAl-Id } l_dummy } to avoid + "WARNING: dg-line var l_dummy defined, but not used". */ + int main (void) { @@ -9,7 +21,9 @@ main (void) int i; #pragma acc parallel { -#pragma acc loop +#pragma acc loop /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'i' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop$c_loop } */ for (i = 0; i < m; i+= k) j = (m + i - j) * l; } @@ -19,7 +33,11 @@ main (void) int x, y, z; #pragma acc parallel { -#pragma acc loop collapse (3) +#pragma acc loop collapse (3) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'z' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-note {variable 'y' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-note {variable 'x' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop$c_loop } */ for (x = 0; x < k; x++) for (y = -5; y < l; y++) for (z = 0; z < m; z++) @@ -31,7 +49,11 @@ main (void) int x, y, z; #pragma acc parallel reduction (+:j) { -#pragma acc loop reduction (+:j) collapse (3) +#pragma acc loop reduction (+:j) collapse (3) /* { dg-line l_loop[incr c_loop] } */ + /* { dg-note {variable 'z' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-note {variable 'y' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-note {variable 'x' in 'private' clause isn't candidate for adjusting OpenACC privatization level: not addressable} {} { target *-*-* } l_loop$c_loop } */ + /* { dg-optimized {assigned OpenACC gang vector loop parallelism} {} { target *-*-* } l_loop$c_loop } */ for (x = 0; x < k; x++) for (y = -5; y < l; y++) for (z = 0; z < m; z++) diff --git a/gcc/testsuite/gcc.dg/gomp/pr104517.c b/gcc/testsuite/gcc.dg/gomp/pr104517.c index efb3175..7e3bd1a 100644 --- a/gcc/testsuite/gcc.dg/gomp/pr104517.c +++ b/gcc/testsuite/gcc.dg/gomp/pr104517.c @@ -2,11 +2,13 @@ /* { dg-do compile } */ /* { dg-options "-O1 -fcompare-debug -fopenmp -fno-tree-ter -save-temps" } */ -enum { - omp_default_mem_alloc, - omp_large_cap_mem_alloc, - omp_const_mem_alloc, - omp_high_bw_mem_alloc +typedef enum omp_allocator_handle_t +{ + omp_null_allocator = 0, + omp_default_mem_alloc = 1, + omp_large_cap_mem_alloc = 2, + omp_const_mem_alloc = 3, + omp_high_bw_mem_alloc = 4, } omp_allocator_handle_t; int t, bar_nte, bar_tl, bar_i3, bar_dd; @@ -23,7 +25,7 @@ bar (int *idp, int s, int nth, int g, int nta, int fi, int pp, int *q, int p = 0, i2 = 0, i1 = 0, m = 0, d = 0; #pragma omp target parallel for \ - device(p) firstprivate (f) allocate (f) in_reduction(+:r2) + device(p) firstprivate (f) allocate (omp_default_mem_alloc:f) in_reduction(+:r2) for (int i = 0; i < 4; i++) ll++; @@ -31,8 +33,8 @@ bar (int *idp, int s, int nth, int g, int nta, int fi, int pp, int *q, device(d) map (m) \ if (target: p) firstprivate (f) defaultmap(tofrom: scalar) is_device_ptr (idp) \ if (parallel: i2) reduction(+:r) num_threads (nth) linear (ll) \ - schedule(static) collapse(1) nowait depend(inout: d) allocate (f) \ - in_reduction(+:r2) + schedule(static) collapse(1) nowait depend(inout: d) \ + allocate (omp_default_mem_alloc:f) in_reduction(+:r2) for (int i = 0; i < 4; i++) ll++; diff --git a/gcc/testsuite/gcc.dg/gomp/pr104532.c b/gcc/testsuite/gcc.dg/gomp/pr104532.c new file mode 100644 index 0000000..1bf8e03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr104532.c @@ -0,0 +1,15 @@ +/* PR c/104532 */ +/* { dg-do compile } */ + +void +foo (int x) +{ + #pragma omp target enter data map (to: x->vectors) /* { dg-error "invalid type argument of '->'" } */ +} /* { dg-error "must contain at least one" "" { target *-*-* } .-1 } */ + +void +bar (int x) +{ + #pragma omp target enter data map (to: x->vectors[]) /* { dg-error "invalid type argument of '->'" } */ +} /* { dg-error "must contain at least one" "" { target *-*-* } .-1 } */ + /* { dg-error "expected expression before" "" { target *-*-* } .-2 } */ diff --git a/gcc/testsuite/gcc.dg/gomp/pr104757.c b/gcc/testsuite/gcc.dg/gomp/pr104757.c new file mode 100644 index 0000000..7383965 --- /dev/null +++ b/gcc/testsuite/gcc.dg/gomp/pr104757.c @@ -0,0 +1,14 @@ +/* PR middle-end/104757 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fopenmp" } */ + +#pragma omp declare target +void +foo (int x, int y, int *z) +{ + int j = 0; + #pragma omp simd linear(j:x + y) + for (int i = 0; i < 64; i++) + j += x + y; +} +#pragma omp end declare target diff --git a/gcc/testsuite/gcc.dg/graphite/pr106055.c b/gcc/testsuite/gcc.dg/graphite/pr106055.c new file mode 100644 index 0000000..22be62b --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/pr106055.c @@ -0,0 +1,41 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -floop-parallelize-all -fno-tree-dce" } */ + +__attribute__ ((returns_twice)) int +bar (void); + +void +quux (void); + +void +empty (void) +{ +} + +unsigned int +choose (unsigned int x, unsigned int y) +{ + return y ? x : 0; +} + +int +foo (int *p, unsigned int x, int y) +{ + unsigned int acc = 0; + + empty (); + + while (x) + { + bar (); + ++x; + } + + while (y) + acc += y; + + *p = choose (acc, 1); + quux (); + + return x; +} diff --git a/gcc/testsuite/gcc.dg/graphite/scop-22a.c b/gcc/testsuite/gcc.dg/graphite/scop-22a.c new file mode 100644 index 0000000..00d4b53 --- /dev/null +++ b/gcc/testsuite/gcc.dg/graphite/scop-22a.c @@ -0,0 +1,56 @@ +/* { dg-require-effective-target size32plus } */ +double u[1782225]; + +void foo(int N, int *res) +{ + int i, j; + double a, b; + double sum = 0.0; + + for (j = 3; j < N; j = j * j) + { + sum += a + b; + } + + /* Next two loops form first SCoP */ + for (i = 0; i < N; i++) + sum += u[i]; + + for (i = 0; i < N; i++) + { + a = u[i]; + u[i] = i * i; + b = u[i]; + sum += a + b; + } + + for (j = 3; j < N; j = j * j) + { + sum += a + b; + } + + for (j = 3; j < N; j = j * j) + { + sum += a + b; + } + + /* Next two loop-nests form second SCoP */ + for (i = 0; i < N; i++) + sum += u[i]; + + for (i = 0; i < N; i++) + for (j = 0; j < N; j++) + { + a = u[i]; + u[i] = i * i; + b = u[j]; + sum += a + b; + } + + *res = sum + N; +} + +/* { dg-final { scan-tree-dump-times "number of SCoPs: 2" 1 "graphite"} } */ +/* { dg-final { scan-tree-dump-times "Loops in SCoP" 2 "graphite"} } */ +/* { dg-final { scan-tree-dump "Loops in SCoP: 2, 3" "graphite"} } */ +/* { dg-final { scan-tree-dump "Loops in SCoP: 6, 7, 8" "graphite"} } */ diff --git a/gcc/testsuite/gcc.dg/ifcvt-4.c b/gcc/testsuite/gcc.dg/ifcvt-4.c index 37aa76a..46245f0 100644 --- a/gcc/testsuite/gcc.dg/ifcvt-4.c +++ b/gcc/testsuite/gcc.dg/ifcvt-4.c @@ -2,7 +2,7 @@ /* { dg-additional-options "-misel" { target { powerpc*-*-* } } } */ /* { dg-additional-options "-march=z196" { target { s390x-*-* } } } */ /* { dg-additional-options "-mtune-ctrl=^one_if_conv_insn" { target { i?86-*-* x86_64-*-* } } } */ -/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* avr-*-* hppa*64*-*-* visium-*-*" riscv*-*-* msp430-*-* nios2-*-*} } */ +/* { dg-skip-if "Multiple set if-conversion not guaranteed on all subtargets" { "arm*-*-* avr-*-* hppa*64*-*-* visium-*-*" riscv*-*-* msp430-*-* nios2-*-* pru-*-* } } */ /* { dg-skip-if "" { "s390x-*-*" } { "-m31" } } */ typedef int word __attribute__((mode(word))); diff --git a/gcc/testsuite/gcc.dg/instrument-4.c b/gcc/testsuite/gcc.dg/instrument-4.c new file mode 100644 index 0000000..c19e8bf --- /dev/null +++ b/gcc/testsuite/gcc.dg/instrument-4.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-finstrument-functions-once" } */ + +void fn () { } + +/* { dg-final { scan-assembler "__cyg_profile_func_enter" } } */ +/* { dg-final { scan-assembler "__cyg_profile_func_exit" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/pr102513.c b/gcc/testsuite/gcc.dg/ipa/pr102513.c new file mode 100644 index 0000000..9ee5431 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr102513.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -Warray-bounds" } */ + +extern int block2[7][256]; + +static int encode_block(int block2[7][256], unsigned level) +{ + int best_score = 0; + + for (unsigned x = 0; x < level; x++) { + int v = block2[1][x]; + block2[level][x] = 0; + best_score += v * v; + } + + if (level > 0 && best_score > 64) { + int score = 0; + + score += encode_block(block2, level - 1); + score += encode_block(block2, level - 1); + + if (score < best_score) { + best_score = score; + } + } + + return best_score; +} + +int foo(void) +{ + return encode_block(block2, 5); +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr103083-1.c b/gcc/testsuite/gcc.dg/ipa/pr103083-1.c new file mode 100644 index 0000000..e2fbb45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr103083-1.c @@ -0,0 +1,28 @@ +/* { dg-do run } */ +/* { dg-options "-O2 -Wno-pointer-to-int-cast" } */ + +struct b {int b;}; +struct a {int a; struct b b;}; + +long i; + +__attribute__ ((noinline)) +static void test2 (struct b *b) +{ + if (((int)b)&4) + __builtin_abort (); +} + +__attribute__ ((noinline)) +static void +test (struct a *a) +{ + test2(a? &a->b : 0); +} + +int +main() +{ + test(0); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr103083-2.c b/gcc/testsuite/gcc.dg/ipa/pr103083-2.c new file mode 100644 index 0000000..ae1b905 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr103083-2.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-ipa-bit-cp -fdump-tree-optimized" } */ + +struct b {int b;}; +struct a {int a; struct b b;}; + +void remove_any_mention (void); + +__attribute__ ((noinline)) +static void test2 (struct b *b) +{ + if (b) + remove_any_mention (); +} + +__attribute__ ((noinline)) +static void +test (struct a *a) +{ + test2(a? &a->b : 0); +} + +int +foo() +{ + test(0); + return 0; +} + +/* { dg-final { scan-tree-dump-not "remove_any_mention" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/pr104813.c b/gcc/testsuite/gcc.dg/ipa/pr104813.c new file mode 100644 index 0000000..34f413e --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr104813.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int a, b, c, d, *e; +void f(int h) { + if (b) { + int g; + while (g++) + d = *e; + e++; + } +} +static void i(); +static void j(int *h, int k, int *l) { + if (c) { + int *o = h, m; + f(*l); + i(m); + j(o, 1, o); + for (;;) + ; + } +} +void i() { + int *n = &a; + while (1) + j(n, 1, n); +} +int main() { + j(&a, 0, &a); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr105160.c b/gcc/testsuite/gcc.dg/ipa/pr105160.c new file mode 100644 index 0000000..ea80545 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr105160.c @@ -0,0 +1,77 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-ipa-modref" } */ +#define sysreg_read(regname) \ +({ \ + unsigned long __sr_val; \ + asm volatile(""); \ + \ + __sr_val; \ +}) + +#define sysreg_write(regname, __sw_val) \ +do { \ + asm volatile(""); \ +} while (0) + +#define isb() \ +do { \ + asm volatile( \ + "isb" \ + : \ + : \ + : "memory"); \ +} while (0) + +static unsigned long sctlr_read(void) +{ + return sysreg_read(sctlr_el1); +} + +static void sctlr_write(unsigned long val) +{ + sysreg_write(sctlr_el1, val); +} + +static void sctlr_rmw(void) +{ + unsigned long val; + + val = sctlr_read(); + val |= 1UL << 7; + sctlr_write(val); +} + +void sctlr_read_multiple(void) +{ + sctlr_read(); + sctlr_read(); + sctlr_read(); + sctlr_read(); +} + +void sctlr_write_multiple(void) +{ + sctlr_write(0); + sctlr_write(0); + sctlr_write(0); + sctlr_write(0); + sctlr_write(0); +} + +void sctlr_rmw_multiple(void) +{ + sctlr_rmw(); + sctlr_rmw(); + sctlr_rmw(); + sctlr_rmw(); +} + +void function(void) +{ + sctlr_read_multiple(); + sctlr_write_multiple(); + sctlr_rmw_multiple(); + + isb(); +} +/* { dg-final { scan-ipa-dump-not "Function found to be const" "modref" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/pr105639.c b/gcc/testsuite/gcc.dg/ipa/pr105639.c new file mode 100644 index 0000000..5534fe9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr105639.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -w" } */ + +void typedef (*cb) (void); + +static void +bar (cb *fp) +{ + (*fp) (); +} + +void +foo (void) +{ + bar (foo); +} diff --git a/gcc/testsuite/gcc.dg/ipa/pr105739.c b/gcc/testsuite/gcc.dg/ipa/pr105739.c new file mode 100644 index 0000000..8dbe8fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/pr105739.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + + +__attribute__((noinline)) +static int +test2(int a) +{ + if (__builtin_constant_p (a)) + __builtin_abort (); + return a; +} +static int +test(int *a) +{ + int val = *(volatile int *)a; + if (__builtin_constant_p (val)) + __builtin_abort (); + if (val) + return test2(val); + return 0; +} +int a; +int +main() +{ + a = 0; + return test (&a); +} +/* { dg-final { scan-tree-dump "test2" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/pr91088.c b/gcc/testsuite/gcc.dg/ipa/pr91088.c index cc146a8..f8b3c49 100644 --- a/gcc/testsuite/gcc.dg/ipa/pr91088.c +++ b/gcc/testsuite/gcc.dg/ipa/pr91088.c @@ -115,6 +115,7 @@ int caller () /* { dg-final { scan-ipa-dump-times "Creating a specialized node of callee1" 1 "cp" } } */ /* { dg-final { scan-ipa-dump-times "Creating a specialized node of callee2" 1 "cp" } } */ /* { dg-final { scan-ipa-dump-times "Creating a specialized node of callee3" 1 "cp" } } */ -/* { dg-final { scan-ipa-dump "op0\\\[offset: 32],\\(\\(short int\\) #\\),\\(\\(int\\) #\\),\\(1300 / #\\) == 19" "cp" } } */ +/* { dg-final { scan-ipa-dump "op0\\\[offset: 16],\\(\\(short int\\) #\\),\\(\\(int\\) #\\),\\(1300 / #\\) == 19" "cp" { target default_packed } } } */ +/* { dg-final { scan-ipa-dump "op0\\\[offset: 32],\\(\\(short int\\) #\\),\\(\\(int\\) #\\),\\(1300 / #\\) == 19" "cp" { target { ! default_packed } } } } */ /* { dg-final { scan-ipa-dump "op0\\\[ref offset: 0],\\(# \\^ 1\\) <" "cp" } } */ /* { dg-final { scan-ipa-dump "op0,\\(# & 255\\),\\(1 - #\\),\\(# \\* 3\\),\\(27 % #\\) <" "cp" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/remref-6.c b/gcc/testsuite/gcc.dg/ipa/remref-6.c index 7deae31..f31f4c1 100644 --- a/gcc/testsuite/gcc.dg/ipa/remref-6.c +++ b/gcc/testsuite/gcc.dg/ipa/remref-6.c @@ -20,5 +20,5 @@ void entry() } /* { dg-final { scan-ipa-dump "Removed a reference" "inline" } } */ -/* { dg-final { scan-ipa-dump "replaced it with LOAD" "inline" } } */ +/* { dg-final { scan-ipa-dump "adding LOAD reference" "inline" } } */ /* { dg-final { scan-tree-dump-not "builtin_exp" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ipa/remref-7.c b/gcc/testsuite/gcc.dg/ipa/remref-7.c new file mode 100644 index 0000000..152b9d0 --- /dev/null +++ b/gcc/testsuite/gcc.dg/ipa/remref-7.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-early-inlining -fno-ipa-sra -fdump-ipa-inline --param max-inline-insns-auto=100" } */ + +int rglobal = 0; +int g; + +int c; +double *array; + +/* unused parameter */ +static void bar(int *p) +{ + int i; + for (i = 0; i < c; i++) + { + /* something big so that it is inlined second. */ + array[i] = __builtin_exp(array[i]+1)*2; + } +} + +void foo(int *p) { + g = *p; + bar(p); +} + +void entry() +{ + foo(&rglobal); +} + +/* { dg-final { scan-ipa-dump "Removed a reference" "inline" } } */ +/* { dg-final { scan-ipa-dump "adding LOAD reference" "inline" } } */ + diff --git a/gcc/testsuite/gcc.dg/loop-8.c b/gcc/testsuite/gcc.dg/loop-8.c index a685fc2..8e5f208 100644 --- a/gcc/testsuite/gcc.dg/loop-8.c +++ b/gcc/testsuite/gcc.dg/loop-8.c @@ -1,6 +1,6 @@ /* { dg-do compile } */ /* { dg-options "-O1 -fdump-rtl-loop2_invariant" } */ -/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-* vax-*-*" } } */ +/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-* vax-*-* loongarch*-*-*" } } */ /* Load immediate on condition is available from z13 on and prevents moving the load out of the loop, so always run this test with -march=zEC12 that does not have load immediate on condition. */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-1.c b/gcc/testsuite/gcc.dg/loop-unswitch-1.c index f9d628d..196cb64 100644 --- a/gcc/testsuite/gcc.dg/loop-unswitch-1.c +++ b/gcc/testsuite/gcc.dg/loop-unswitch-1.c @@ -33,4 +33,4 @@ parse_tag: ; } /* Test that we actually unswitched something. */ -/* { dg-final { scan-tree-dump "Unswitching loop" "unswitch" } } */ +/* { dg-final { scan-tree-dump "unswitching loop" "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-10.c b/gcc/testsuite/gcc.dg/loop-unswitch-10.c new file mode 100644 index 0000000..395167e --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-10.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int +__attribute__((noipa)) +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp, tmp2; + + switch(order) + { + case 0: + tmp = -8 * a[i]; + tmp2 = 2 * b[i]; + break; + case 1: + tmp = 3 * a[i] - 2 * b[i]; + tmp2 = 5 * b[i] - 2 * c[i]; + break; + case 2: + tmp = 9 * a[i] + 2 * b[i] + c[i]; + tmp2 = 4 * b[i] + 2 * c[i] + 8 * d[i]; + break; + case 3: + tmp = 3 * a[i] + 2 * b[i] - c[i]; + tmp2 = b[i] - 2 * c[i] + 8 * d[i]; + break; + default: + __builtin_unreachable (); + } + + double x = 3 * tmp + d[i] + tmp; + double y = 3.4f * tmp + d[i] + tmp2; + r[i] = x + y; + } + + return 0; +} + +#define N 16 * 1024 +double aa[N], bb[N], cc[N], dd[N], rr[N]; + +int main() +{ + for (int i = 0; i < 100 * 1000; i++) + foo (aa, bb, cc, dd, rr, N, i % 4); +} + + +/* Test that we actually unswitched something. */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 0" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 1" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 2" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 3" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-11.c b/gcc/testsuite/gcc.dg/loop-unswitch-11.c new file mode 100644 index 0000000..422a942 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-11.c @@ -0,0 +1,45 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp, tmp2; + + switch(order) + { + case 5 ... 6: + case 9: + tmp = -8 * a[i]; + tmp2 = 2 * b[i]; + break; + case 11: + tmp = 3 * a[i] - 2 * b[i]; + tmp2 = 5 * b[i] - 2 * c[i]; + break; + case 22: + tmp = 9 * a[i] + 2 * b[i] + c[i]; + tmp2 = 4 * b[i] + 2 * c[i] + 8 * d[i]; + break; + case 33: + tmp = 3 * a[i] + 2 * b[i] - c[i]; + tmp2 = b[i] - 2 * c[i] + 8 * d[i]; + break; + default: + __builtin_unreachable (); + } + + double x = 3 * tmp + d[i] + tmp; + double y = 3.4f * tmp + d[i] + tmp2; + r[i] = x + y; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* \\+ 4294967291.*order.* == 9" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 1" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 2" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 3" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-12.c b/gcc/testsuite/gcc.dg/loop-unswitch-12.c new file mode 100644 index 0000000..052c456 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-12.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp; + + if (order == 1) + tmp = -8 * a[i]; + else + tmp = -4 * b[i]; + + double x = 3 * tmp + d[i] + tmp; + + if (order == 1) + x += 2; + + double y = 3.4f * tmp + d[i]; + r[i] = x + y; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .if. with condition: order.* == 1" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-13.c b/gcc/testsuite/gcc.dg/loop-unswitch-13.c new file mode 100644 index 0000000..d09c4aa --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-13.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fno-thread-jumps -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, unsigned order) +{ + for (int i = 0; i < size; i++) + { + double tmp; + + switch (order) + { + case 0 ... 4: + tmp = -8 * a[i]; + break; + default: + tmp = -4 * b[i]; + break; + } + + double x = 3 * tmp + d[i] + tmp; + + /* This and the case 0 ... 4 condition should only be unswitched once + since they are mutually excluded. */ + if (order >= 5) + x += 2; + + double y = 3.4f * tmp + d[i]; + r[i] = x + y; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .\[^\n\r\]*. with condition" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-14.c b/gcc/testsuite/gcc.dg/loop-unswitch-14.c new file mode 100644 index 0000000..d9d3168 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-14.c @@ -0,0 +1,60 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized --param=max-unswitch-insns=1000" } */ + +int +__attribute__((noipa)) +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp, tmp2; + + if (order <= 0) + tmp = 123; + + switch(order) + { + case 0: + tmp += -8 * a[i]; + tmp2 = 2 * b[i]; + break; + case 1: + tmp = 3 * a[i] - 2 * b[i]; + tmp2 = 5 * b[i] - 2 * c[i]; + break; + case 2: + tmp = 9 * a[i] + 2 * b[i] + c[i]; + tmp2 = 4 * b[i] + 2 * c[i] + 8 * d[i]; + break; + case 3: + tmp = 3 * a[i] + 2 * b[i] - c[i]; + tmp2 = b[i] - 2 * c[i] + 8 * d[i]; + break; + default: + __builtin_unreachable (); + } + + double x = 3 * tmp + d[i] + tmp; + double y = 3.4f * tmp + d[i] + tmp2; + r[i] = x + y; + } + + return 0; +} + +#define N 16 * 1024 +double aa[N], bb[N], cc[N], dd[N], rr[N]; + +int main() +{ + for (int i = 0; i < 100 * 1000; i++) + foo (aa, bb, cc, dd, rr, N, i % 4); +} + + +/* Test that we actually unswitched something. */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* <= 0" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 0" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 1" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 2" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .switch. with condition: order.* == 3" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-15.c b/gcc/testsuite/gcc.dg/loop-unswitch-15.c new file mode 100644 index 0000000..87139bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-15.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +void bar(); +void baz(); +void foo (int a, int b, int n) +{ + for (int i = 0; i < n; ++i) + if (a < b) + bar (); + else + baz (); +} + +/* { dg-final { scan-tree-dump "unswitching loop . on .if. with condition:" "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-16.c b/gcc/testsuite/gcc.dg/loop-unswitch-16.c new file mode 100644 index 0000000..4b0b400 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-16.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized --param max-unswitch-insns=100" } */ + +void bar (int); +void foo (int a, int b, int c, int n) +{ + for (int i = 0; i < n; ++i) + { + if (a > 5) + bar (1); + if (b < 10) + bar (2); + if (c != 5) + bar (3); + } +} + +/* Verify we can unswitch all permutations of the predicates. */ +/* { dg-final { scan-tree-dump-times "unswitching loop . on .if. with condition" 7 "unswitch" } } */ +/* { dg-final { scan-tree-dump "unswitching loop . on .if. with condition: a" "unswitch" } } */ +/* { dg-final { scan-tree-dump "unswitching loop . on .if. with condition: b" "unswitch" } } */ +/* { dg-final { scan-tree-dump "unswitching loop . on .if. with condition: c" "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-17.c b/gcc/testsuite/gcc.dg/loop-unswitch-17.c new file mode 100644 index 0000000..8655e09 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-17.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int foo (int a) +{ + do + { + if (a == 1) + return 0; + switch (a) + { + case 1: + return 5; + case 2: + return 7; + case 3: + return 11; + default:; + } + } + while (1); +} + +/* { dg-final { scan-tree-dump-times "unswitching loop" 3 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-7.c b/gcc/testsuite/gcc.dg/loop-unswitch-7.c new file mode 100644 index 0000000..db2f930 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-7.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fno-thread-jumps -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, float order) +{ + for (int i = 0; i < size; i++) + { + double tmp; + + if (order == 1.f) + tmp = -8 * a[i]; + else + tmp = -4 * b[i]; + + double x = 3 * tmp + d[i] + tmp; + + if (order == 1.f) + x += 2; + + double y = 3.4f * tmp + d[i]; + r[i] = x + y; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .if. with condition: order.* == 1.0e" 1 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-8.c b/gcc/testsuite/gcc.dg/loop-unswitch-8.c new file mode 100644 index 0000000..32796e9 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-8.c @@ -0,0 +1,31 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp; + + if (order < 3) + tmp = -8 * a[i]; + else + tmp = -4 * b[i]; + + double x = 3 * tmp + d[i] + tmp; + + if (5 > order) + x += 2; + + if (order == 12345) + x *= 5; + + double y = 3.4f * tmp + d[i]; + r[i] = x + y; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .if. with condition: order" 3 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/loop-unswitch-9.c b/gcc/testsuite/gcc.dg/loop-unswitch-9.c new file mode 100644 index 0000000..5e50b07 --- /dev/null +++ b/gcc/testsuite/gcc.dg/loop-unswitch-9.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -funswitch-loops -fdump-tree-unswitch-optimized" } */ + +int +foo(double *a, double *b, double *c, double *d, double *r, int size, int order) +{ + for (int i = 0; i < size; i++) + { + double tmp; + + if (order == 1) + tmp = -8 * a[i]; + else + { + if (order == 2) + tmp = -4 * b[i]; + else + tmp = a[i]; + } + + r[i] = 3.4f * tmp + d[i]; + } + + return 0; +} + +/* { dg-final { scan-tree-dump-times "unswitching loop . on .if. with condition: order" 2 "unswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c index 63a4710..c62db2c 100644 --- a/gcc/testsuite/gcc.dg/lower-subreg-1.c +++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c @@ -1,7 +1,5 @@ -/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* tilegx-*-* } } } } } */ +/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* i?86-*-* ia64-*-* pru-*-* sparc*-*-* x86_64-*-* } } } } } */ /* { dg-options "-O -fdump-rtl-subreg1" } */ -/* { dg-additional-options "-mno-stv" { target ia32 } } */ -/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } } */ /* { dg-require-effective-target ilp32 } */ long long test (long long a, long long b) { return a | b; } diff --git a/gcc/testsuite/gcc.dg/lto/20090717_0.c b/gcc/testsuite/gcc.dg/lto/20090717_0.c index fe13bdf..41558df 100644 --- a/gcc/testsuite/gcc.dg/lto/20090717_0.c +++ b/gcc/testsuite/gcc.dg/lto/20090717_0.c @@ -1,4 +1,4 @@ struct variable { const char *string; }; -struct variable table[] = { }; +struct variable table[] = { { 0 } }; diff --git a/gcc/testsuite/gcc.dg/lto/pr101868_0.c b/gcc/testsuite/gcc.dg/lto/pr101868_0.c index c84d19b..0312430 100644 --- a/gcc/testsuite/gcc.dg/lto/pr101868_0.c +++ b/gcc/testsuite/gcc.dg/lto/pr101868_0.c @@ -22,12 +22,13 @@ repro(VALUE dummy, VALUE hash) static VALUE (*that)(VALUE dummy, VALUE hash) = repro; +volatile int zero = 0; + int main(int argc, char **argv) { - argc--; - that(0, argc); + that(0, zero); - rb_check_type(argc, argc); + rb_check_type(zero, zero); } diff --git a/gcc/testsuite/gcc.dg/lto/pr103171_0.c b/gcc/testsuite/gcc.dg/lto/pr103171_0.c new file mode 100644 index 0000000..5dc17d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr103171_0.c @@ -0,0 +1,11 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -O2 -flto -flto-partition=1to1 -fno-early-inlining -fno-ipa-sra -w } } } */ + +extern void __attribute__((noinline)) entry(void); + +int +main (int argc, char **argv) +{ + entry(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/lto/pr103171_1.c b/gcc/testsuite/gcc.dg/lto/pr103171_1.c new file mode 100644 index 0000000..39aed25 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr103171_1.c @@ -0,0 +1,35 @@ +int rglobal = 0; + +volatile int g; +volatile int c; +volatile double *array; + +/* unused parameter */ +static void +bar(int *p) +{ + int i; + for (i = 0; i < c; i++) + { + /* something big so that it is inlined second. */ + array[i] = (array[i+1]+array[i]+1)*2; + } +} + +void foo(int *p) { + g = *p; + bar(p); +} + +void __attribute__((noinline)) +entry(void) +{ + foo(&rglobal); +} + +void __attribute__((used)) +blah(int *p) +{ + bar(p); +} + diff --git a/gcc/testsuite/gcc.dg/lto/pr105459_0.c b/gcc/testsuite/gcc.dg/lto/pr105459_0.c new file mode 100644 index 0000000..c799e6e --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr105459_0.c @@ -0,0 +1,35 @@ +/* { dg-lto-do link } */ +/* { dg-lto-options { { -flto -O1 } } } */ + +double m; +int n; + +__attribute__ ((optimize ("-funsafe-math-optimizations"))) +void +bar (int x) +{ + n = x; + m = n; +} + +__attribute__ ((flatten)) +void +foo (int x) +{ + bar (x); +} + +void +quux (void) +{ + ++n; +} + +int +main (void) +{ + foo (0); + quux (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/mallign.c b/gcc/testsuite/gcc.dg/mallign.c index 349cdaa..9a18a00 100644 --- a/gcc/testsuite/gcc.dg/mallign.c +++ b/gcc/testsuite/gcc.dg/mallign.c @@ -9,7 +9,7 @@ typedef int word __attribute__((mode(word))); int main() { - if ((__UINTPTR_TYPE__)malloc (1) & (sizeof(word)-1)) + if ((sizeof(word)>1) && ((__UINTPTR_TYPE__)malloc (1) & (sizeof(word)-1))) abort (); return 0; } diff --git a/gcc/testsuite/gcc.dg/memchr.c b/gcc/testsuite/gcc.dg/memchr.c index fb21d58..27524b8 100644 --- a/gcc/testsuite/gcc.dg/memchr.c +++ b/gcc/testsuite/gcc.dg/memchr.c @@ -1,6 +1,7 @@ /* PR middle-end/78257 - missing memcmp optimization with constant arrays { dg-do compile } - { dg-options "-O -Wall -fdump-tree-optimized" } */ + { dg-options "-O -Wall -fdump-tree-optimized" } + { dg-skip-if "test assumes structs are not packed" { default_packed } } */ typedef __INT8_TYPE__ int8_t; typedef __INT16_TYPE__ int16_t; diff --git a/gcc/testsuite/gcc.dg/memcmp-3.c b/gcc/testsuite/gcc.dg/memcmp-3.c index b5b8ac1..8ddde99 100644 --- a/gcc/testsuite/gcc.dg/memcmp-3.c +++ b/gcc/testsuite/gcc.dg/memcmp-3.c @@ -1,7 +1,8 @@ /* PR middle-end/78257 - missing memcmp optimization with constant arrays { dg-do compile } { dg-options "-O -Wall -fdump-tree-optimized" } - { dg-skip-if "missing data representation" { "pdp11-*-*" } } */ + { dg-skip-if "missing data representation" { "pdp11-*-*" } } + { dg-skip-if "test assumes structs are not packed" { default_packed } } */ #define offsetof(T, m) __builtin_offsetof (T, m) diff --git a/gcc/testsuite/gcc.dg/memcpy-6.c b/gcc/testsuite/gcc.dg/memcpy-6.c index 7ff735e..d4df039 100644 --- a/gcc/testsuite/gcc.dg/memcpy-6.c +++ b/gcc/testsuite/gcc.dg/memcpy-6.c @@ -6,7 +6,8 @@ of targets where it's known to pass (see PR testsuite/83483). { dg-do compile } { dg-options "-O0 -Wrestrict -fdump-tree-optimized" } - { dg-skip-if "skip non-x86 targets" { ! { i?86-*-* x86_64-*-* } } } */ + { dg-skip-if "skip non-x86 targets" { ! { i?86-*-* x86_64-*-* } } } + { dg-additional-options "-msse" { target i?86-*-* x86_64-*-* } } */ char a[32]; diff --git a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c index d045da9..a5d8bfd 100644 --- a/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c +++ b/gcc/testsuite/gcc.dg/optimize-bswaphi-1.c @@ -68,4 +68,4 @@ get_unaligned_16_be (unsigned char *p) /* { dg-final { scan-tree-dump-times "16 bit load in target endianness found at" 4 "bswap" } } */ -/* { dg-final { scan-tree-dump-times "16 bit bswap implementation found at" 5 "bswap" } } */ +/* { dg-final { scan-tree-dump-times "16 bit bswap implementation found at" 4 "bswap" } } */ diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c index 61dd490..2a8bf11 100644 --- a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c @@ -47,13 +47,13 @@ class gil_state_machine : public state_machine public: gil_state_machine (logger *logger); - bool inherited_state_p () const FINAL OVERRIDE { return false; } + bool inherited_state_p () const final override { return false; } bool on_stmt (sm_context *sm_ctxt, const supernode *node, - const gimple *stmt) const FINAL OVERRIDE; + const gimple *stmt) const final override; - bool can_purge_p (state_t s) const FINAL OVERRIDE; + bool can_purge_p (state_t s) const final override; void check_for_pyobject_usage_without_gil (sm_context *sm_ctxt, const supernode *node, @@ -81,7 +81,13 @@ public: class gil_diagnostic : public pending_diagnostic { public: - location_t fixup_location (location_t loc) const FINAL OVERRIDE + /* There isn't a warning ID for us to use. */ + int get_controlling_option () const final override + { + return 0; + } + + location_t fixup_location (location_t loc) const final override { /* Ideally we'd check for specific macros here, and only resolve certain macros. */ @@ -92,7 +98,7 @@ public: } label_text describe_state_change (const evdesc::state_change &change) - FINAL OVERRIDE + final override { if (change.is_global_p () && change.m_new_state == m_sm.m_released_gil) @@ -103,6 +109,21 @@ public: return label_text (); } + diagnostic_event::meaning + get_meaning_for_state_change (const evdesc::state_change &change) + const final override + { + if (change.is_global_p ()) + { + if (change.m_new_state == m_sm.m_released_gil) + return diagnostic_event::meaning (diagnostic_event::VERB_release, + diagnostic_event::NOUN_lock); + else if (change.m_new_state == m_sm.get_start_state ()) + return diagnostic_event::meaning (diagnostic_event::VERB_acquire, + diagnostic_event::NOUN_lock); + } + return diagnostic_event::meaning (); + } protected: gil_diagnostic (const gil_state_machine &sm) : m_sm (sm) { @@ -119,25 +140,25 @@ class double_save_thread : public gil_diagnostic : gil_diagnostic (sm), m_call (call) {} - const char *get_kind () const FINAL OVERRIDE + const char *get_kind () const final override { return "double_save_thread"; } - bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE + bool subclass_equal_p (const pending_diagnostic &base_other) const override { const double_save_thread &sub_other = (const double_save_thread &)base_other; return m_call == sub_other.m_call; } - bool emit (rich_location *rich_loc) FINAL OVERRIDE + bool emit (rich_location *rich_loc) final override { - return warning_at (rich_loc, 0, + return warning_at (rich_loc, get_controlling_option (), "nested usage of %qs", "Py_BEGIN_ALLOW_THREADS"); } - label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE + label_text describe_final_event (const evdesc::final_event &ev) final override { return ev.formatted_print ("nested usage of %qs here", "Py_BEGIN_ALLOW_THREADS"); @@ -156,12 +177,12 @@ class fncall_without_gil : public gil_diagnostic m_arg_idx (arg_idx) {} - const char *get_kind () const FINAL OVERRIDE + const char *get_kind () const final override { return "fncall_without_gil"; } - bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE + bool subclass_equal_p (const pending_diagnostic &base_other) const override { const fncall_without_gil &sub_other = (const fncall_without_gil &)base_other; @@ -170,23 +191,22 @@ class fncall_without_gil : public gil_diagnostic && m_arg_idx == sub_other.m_arg_idx); } - bool emit (rich_location *rich_loc) FINAL OVERRIDE + bool emit (rich_location *rich_loc) final override { auto_diagnostic_group d; - /* There isn't a warning ID for use to use. */ if (m_callee_fndecl) - return warning_at (rich_loc, 0, + return warning_at (rich_loc, get_controlling_option (), "use of PyObject as argument %i of %qE" " without the GIL", m_arg_idx + 1, m_callee_fndecl); else - return warning_at (rich_loc, 0, + return warning_at (rich_loc, get_controlling_option (), "use of PyObject as argument %i of call" " without the GIL", m_arg_idx + 1, m_callee_fndecl); } - label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE + label_text describe_final_event (const evdesc::final_event &ev) final override { if (m_callee_fndecl) return ev.formatted_print ("use of PyObject as argument %i of %qE here" @@ -211,26 +231,25 @@ class pyobject_usage_without_gil : public gil_diagnostic : gil_diagnostic (sm), m_expr (expr) {} - const char *get_kind () const FINAL OVERRIDE + const char *get_kind () const final override { return "pyobject_usage_without_gil"; } - bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE + bool subclass_equal_p (const pending_diagnostic &base_other) const override { return same_tree_p (m_expr, ((const pyobject_usage_without_gil&)base_other).m_expr); } - bool emit (rich_location *rich_loc) FINAL OVERRIDE + bool emit (rich_location *rich_loc) final override { auto_diagnostic_group d; - /* There isn't a warning ID for use to use. */ - return warning_at (rich_loc, 0, + return warning_at (rich_loc, get_controlling_option (), "use of PyObject %qE without the GIL", m_expr); } - label_text describe_final_event (const evdesc::final_event &ev) FINAL OVERRIDE + label_text describe_final_event (const evdesc::final_event &ev) final override { return ev.formatted_print ("PyObject %qE used here without the GIL", m_expr); diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c index d2babd3..38ecf0a 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-metadata.c @@ -5,5 +5,5 @@ extern char *gets (char *s); void test_cwe (void) { char buf[1024]; - gets (buf); /* { dg-warning "never use 'gets' \\\[CWE-242\\\]" } */ + gets (buf); /* { dg-warning "never use 'gets' \\\[CWE-242\\\] \\\[STR34-C\\\]" } */ } diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-5.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-5.c new file mode 100644 index 0000000..bd09391 --- /dev/null +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-5.c @@ -0,0 +1,56 @@ +/* { dg-do compile } */ +/* { dg-options "-fdiagnostics-format=sarif-file" } */ +/* { dg-excess-errors "The error is sent to the SARIF file, rather than stderr" } */ + +#include <stddef.h> +#include <stdlib.h> + +/* Minimal reimplementation of cpython API. */ +typedef struct PyObject {} PyObject; +extern int PyArg_ParseTuple (PyObject *args, const char *fmt, ...); +extern PyObject *PyList_New (int); +extern PyObject *PyLong_FromLong(long); +extern void PyList_Append(PyObject *list, PyObject *item); + +PyObject * +make_a_list_of_random_ints_badly(PyObject *self, + PyObject *args) +{ + PyObject *list, *item; + long count, i; + + if (!PyArg_ParseTuple(args, "i", &count)) { + return NULL; + } + + list = PyList_New(0); + + for (i = 0; i < count; i++) { + item = PyLong_FromLong(random()); + PyList_Append(list, item); + } + + return list; +} + +/* + { dg-final { scan-sarif-file "\"tool\": " } } + + We expect info about the plugin: + { dg-final { scan-sarif-file "\"extensions\": \\\[" } } + { dg-final { scan-sarif-file "\"name\": \"diagnostic_plugin_test_paths\"" } } + { dg-final { scan-sarif-file "\"fullName\": \"" } } + + { dg-final { scan-sarif-file "\"results\": \\\[" } } + { dg-final { scan-sarif-file "\"level\": \"error\"" } } + { dg-final { scan-sarif-file "\"text\": \"passing NULL as argument 1 to 'PyList_Append' which requires a non-NULL parameter\"" } } + + We expect a path for the diagnostic: + { dg-final { scan-sarif-file "\"codeFlows\": \\\[" } } + { dg-final { scan-sarif-file "\"threadFlows\": \\\[" } } + { dg-final { scan-sarif-file "\"locations\": \\\[" } } + { dg-final { scan-sarif-file "\"text\": \"when 'PyList_New' fails, returning NULL\"" } } + { dg-final { scan-sarif-file "\"text\": \"when 'i < count'\"" } } + { dg-final { scan-sarif-file "\"text\": \"when calling 'PyList_Append', passing NULL from \\(1\\) as argument 1\"" } } + +*/ diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.c index 67ca701..3396b38 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_group_plugin.c @@ -15,12 +15,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c index ac72503..d81fa57 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_show_trees.c @@ -17,12 +17,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c index d2bfca0..3627f7a 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_inlining.c @@ -15,12 +15,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c index a610891..b86a8b3 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_metadata.c @@ -15,12 +15,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" @@ -106,9 +106,16 @@ pass_test_metadata::execute (function *fun) if (gcall *call = check_for_named_call (stmt, "gets", 1)) { gcc_rich_location richloc (gimple_location (call)); - /* CWE-242: Use of Inherently Dangerous Function. */ diagnostic_metadata m; + + /* CWE-242: Use of Inherently Dangerous Function. */ m.add_cwe (242); + + /* Example of a diagnostic_metadata::rule. */ + diagnostic_metadata::precanned_rule + test_rule ("STR34-C", "https://example.com/"); + m.add_rule (test_rule); + warning_meta (&richloc, m, 0, "never use %qs", "gets"); } diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c index 5c2da02..8d97fe8 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_paths.c @@ -21,12 +21,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c index 482dbda..baa6b62 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c @@ -47,12 +47,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c index aa73dca..0269f72 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_string_literals.c @@ -17,12 +17,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c index 4a89d84..f546863 100644 --- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c +++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_tree_expression_range.c @@ -17,12 +17,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/finish_unit_plugin.c b/gcc/testsuite/gcc.dg/plugin/finish_unit_plugin.c index 1b4f7cc..05e1881 100644 --- a/gcc/testsuite/gcc.dg/plugin/finish_unit_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/finish_unit_plugin.c @@ -15,7 +15,6 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" -#include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" diff --git a/gcc/testsuite/gcc.dg/plugin/ggcplug.c b/gcc/testsuite/gcc.dg/plugin/ggcplug.c index c186d11..a75eed0 100644 --- a/gcc/testsuite/gcc.dg/plugin/ggcplug.c +++ b/gcc/testsuite/gcc.dg/plugin/ggcplug.c @@ -14,7 +14,6 @@ #include "ggc.h" #include "tree-ssa-alias.h" #include "internal-fn.h" -#include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" diff --git a/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c b/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c index 5294f28..0c040e5 100644 --- a/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c @@ -17,7 +17,6 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" -#include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c index bd1c0f0..84f2d31 100644 --- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c @@ -12,7 +12,6 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" -#include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp index 2ade945..63b117d 100644 --- a/gcc/testsuite/gcc.dg/plugin/plugin.exp +++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp @@ -102,6 +102,7 @@ set plugin_test_list [list \ diagnostic-test-paths-2.c \ diagnostic-test-paths-3.c \ diagnostic-test-paths-4.c \ + diagnostic-test-paths-5.c \ diagnostic-path-format-plain.c \ diagnostic-path-format-none.c \ diagnostic-path-format-separate-events.c \ diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c index 2adb644..13b3eca 100644 --- a/gcc/testsuite/gcc.dg/plugin/selfassign.c +++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c @@ -17,12 +17,12 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" +#include "gimple.h" +#include "gimple-iterator.h" #include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" -#include "gimple.h" -#include "gimple-iterator.h" #include "tree.h" #include "tree-pass.h" #include "intl.h" diff --git a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c index 61e9494..7b4f40e 100644 --- a/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/start_unit_plugin.c @@ -20,7 +20,6 @@ #include "basic-block.h" #include "tree-ssa-alias.h" #include "internal-fn.h" -#include "gimple-fold.h" #include "tree-eh.h" #include "gimple-expr.h" #include "is-a.h" diff --git a/gcc/testsuite/gcc.dg/pow-sqrt-synth-1.c b/gcc/testsuite/gcc.dg/pow-sqrt-synth-1.c index 4a94325..484b29a 100644 --- a/gcc/testsuite/gcc.dg/pow-sqrt-synth-1.c +++ b/gcc/testsuite/gcc.dg/pow-sqrt-synth-1.c @@ -1,5 +1,5 @@ /* { dg-do compile { target sqrt_insn } } */ -/* { dg-options "-fdump-tree-sincos -Ofast --param max-pow-sqrt-depth=8" } */ +/* { dg-options "-fdump-tree-powcabs -Ofast --param max-pow-sqrt-depth=8" } */ /* { dg-additional-options "-mfloat-abi=softfp -mfpu=neon-vfpv4" { target arm*-*-* } } */ double @@ -34,4 +34,4 @@ vecfoo (double *a) a[i] = __builtin_pow (a[i], 1.25); } -/* { dg-final { scan-tree-dump-times "synthesizing" 7 "sincos" } } */ +/* { dg-final { scan-tree-dump-times "synthesizing" 7 "powcabs" } } */ diff --git a/gcc/testsuite/gcc.dg/pr100680.c b/gcc/testsuite/gcc.dg/pr100680.c new file mode 100644 index 0000000..4b5ffc6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100680.c @@ -0,0 +1,31 @@ +/* PR middle-end/100680 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wstringop-overread" } */ + +struct s { + char a[8]; + int i; + long l; +}; + +extern char ea[8]; +static char sa[8] = { 1, 2, 3, 4 }; + +int +test (void) +{ + const struct s *ps = (const struct s *) 0x12345678L; + if (__builtin_memcmp (ps->a, ps->a, 8)) + return 0; + + if (__builtin_memcmp (ps->a, ea, 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + if (__builtin_memcmp (ps->a, sa, 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + if (__builtin_memcmp (ps->a, "abcdABCD", 8)) /* { dg-bogus "exceeds source size 0" } */ + return 0; + + return 1; +} diff --git a/gcc/testsuite/gcc.dg/pr100781.c b/gcc/testsuite/gcc.dg/pr100781.c index c0e008a..96f0a7a 100644 --- a/gcc/testsuite/gcc.dg/pr100781.c +++ b/gcc/testsuite/gcc.dg/pr100781.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 --param=evrp-mode=ranger -fcompare-debug " } */ +/* { dg-options "-O2 -fcompare-debug " } */ struct a { int b; diff --git a/gcc/testsuite/gcc.dg/pr100834.c b/gcc/testsuite/gcc.dg/pr100834.c new file mode 100644 index 0000000..4bd2691 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr100834.c @@ -0,0 +1,42 @@ +/* PR tree-optimization/100834 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wall" } */ + +#define PAGE_SIZE 4096 +#define STACK_SIZE PAGE_SIZE + +union registers +{ + struct + { + unsigned long r15, r14, r13, r12, r11, r10, r9, r8; + unsigned long rdi, rsi, rbp, unused, rbx, rdx, rcx, rax; + }; + unsigned long by_index[16]; +}; + +struct per_cpu +{ + union + { + unsigned char stack[STACK_SIZE]; + struct + { + unsigned char __fill[STACK_SIZE - sizeof (union registers)]; + union registers guest_regs; + }; + }; +} __attribute__((aligned (PAGE_SIZE))); + +static inline struct per_cpu * +this_cpu_data (void) +{ + return (struct per_cpu *) 0xdeadbeef; +} + +void +foo (void) +{ + struct per_cpu *cpu_data = this_cpu_data (); + __builtin_memset (&cpu_data->guest_regs, 0, sizeof (cpu_data->guest_regs)); /* { dg-bogus "is out of the bounds" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr101145-2.c b/gcc/testsuite/gcc.dg/pr101145-2.c index 6ecfeb2..dad192c 100644 --- a/gcc/testsuite/gcc.dg/pr101145-2.c +++ b/gcc/testsuite/gcc.dg/pr101145-2.c @@ -12,4 +12,6 @@ unsigned foo(unsigned val, unsigned start) return cnt; } -/* { dg-final { scan-tree-dump "cnt_\[0-9\] = start_\[0-9\]\\(D\\) >= val_\[0-9\]\\(D\\) \\? _\[0-9\] : 1;" "optimized" } } */ +/* Look for start >= val ? -start : 1 */ +/* { dg-final { scan-tree-dump " = start_\[0-9\]\\(D\\) >= val_\[0-9\]\\(D\\);" "optimized" } } */ +/* { dg-final { scan-tree-dump "cnt_\[0-9\] = _\[0-9\]+ \\? _\[0-9\]+ : 1;" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr102950.c b/gcc/testsuite/gcc.dg/pr102950.c new file mode 100644 index 0000000..3175683 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr102950.c @@ -0,0 +1,21 @@ +/* { dg-do link } */ +/* { dg-options "-O2" } */ + +extern void link_error(void); + +static signed char a; +static short d(unsigned e) { + signed char b; + short c; + a = b = e; + if (b) + return 0; + if (1 >= e) { + c = e == 0; + if (c) + link_error(); + } + return 0; +} +int main() { d(a ^ 233); } + diff --git a/gcc/testsuite/gcc.dg/pr102983.c b/gcc/testsuite/gcc.dg/pr102983.c index ef58af6..e1bd24b 100644 --- a/gcc/testsuite/gcc.dg/pr102983.c +++ b/gcc/testsuite/gcc.dg/pr102983.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-evrp" } */ +/* { dg-options "-O2 -fdump-tree-evrp -fno-tree-ccp" } */ void foo(void); static int a = 1; diff --git a/gcc/testsuite/gcc.dg/pr103775.c b/gcc/testsuite/gcc.dg/pr103775.c new file mode 100644 index 0000000..4a8c0d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103775.c @@ -0,0 +1,12 @@ +/* PR rtl-optimization/103775 */ +/* { dg-do assemble { target int128 } } */ +/* { dg-options "-Og -fno-forward-propagate -free -g" } */ + +int +foo (char a, short b, int c, __int128 d, char e, short f, int g, __int128 h) +{ + long i = __builtin_clrsbll ((char) h); + __builtin_memset ((char *) &h + 4, d, 3); + c &= (char) h; + return c + i; +} diff --git a/gcc/testsuite/gcc.dg/pr103845.c b/gcc/testsuite/gcc.dg/pr103845.c new file mode 100644 index 0000000..45ab518 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr103845.c @@ -0,0 +1,29 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fharden-compares -fno-ipa-pure-const" } */ + +int +baz (void); + +__attribute__ ((returns_twice)) void +bar (void) +{ +} + +int +quux (int y, int z) +{ + return (y || z >= 0) ? y : z; +} + +int +foo (int x) +{ + int a = 0, b = x == a; + + bar (); + + if (!!baz () < quux (b, a)) + ++x; + + return x; +} diff --git a/gcc/testsuite/gcc.dg/pr104381.c b/gcc/testsuite/gcc.dg/pr104381.c new file mode 100644 index 0000000..a3aec91 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104381.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -gtoggle -fdump-tree-optimized" } */ + +int foo (int x) +{ + int tem = x + 1; + int tem2 = tem - 1; + return tem2; +} + +int +__attribute__((optimize("no-tree-pre"))) +bar (int x) +{ + int tem = x + 1; + int tem2 = tem - 1; + return tem2; +} + +// { dg-final { scan-tree-dump-not "DEBUG " "optimized" } } diff --git a/gcc/testsuite/gcc.dg/pr104506-1.c b/gcc/testsuite/gcc.dg/pr104506-1.c new file mode 100644 index 0000000..5eb7191 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104506-1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu11" } */ +/* PR c/104506: we used to ICE after the error of + changing the type. */ + +void +foo (double x) +/* { dg-message "note: previous definition" "previous definition" { target *-*-* } .-1 } */ +{ + (void)x; + int x; /* { dg-error "redeclared as different kind of symbol" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr104506-2.c b/gcc/testsuite/gcc.dg/pr104506-2.c new file mode 100644 index 0000000..3c3aaaa --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104506-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu11" } */ +/* PR c/104506: we used to ICE after the error of + changing the type. */ +void +foo (double x) +/* { dg-message "note: previous definition" "previous definition" { target *-*-* } .-1 } */ +{ + x; + int x; /* { dg-error "redeclared as different kind of symbol" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr104506-3.c b/gcc/testsuite/gcc.dg/pr104506-3.c new file mode 100644 index 0000000..b14deb5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104506-3.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* PR c/104506: we used to ICE after the error of + changing the type. */ +double x; +/* { dg-message "note: previous declaration" "previous declaration" { target *-*-* } .-1 } */ +void +foo (void) +{ + x; +} +int x; /* { dg-error "conflicting types" } */ diff --git a/gcc/testsuite/gcc.dg/pr104558.c b/gcc/testsuite/gcc.dg/pr104558.c new file mode 100644 index 0000000..382fe57 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104558.c @@ -0,0 +1,15 @@ +/* PR middle-end/104558 */ +/* { dg-do compile } */ +/* { dg-options "-fabi-version=9" } */ + +struct __attribute__ ((aligned)) A {}; + +struct A a; + +void bar (int, int, int, int, int, int, int, struct A); + +void +foo (void) +{ + bar (0, 1, 2, 3, 4, 5, 6, a); +} diff --git a/gcc/testsuite/gcc.dg/pr104612.c b/gcc/testsuite/gcc.dg/pr104612.c new file mode 100644 index 0000000..7d055ed --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104612.c @@ -0,0 +1,27 @@ +/* PR target/104612 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-msse2 -mfpmath=sse" { target i?86-*-* x86_64-*-* } } */ + +struct V { float x, y; }; + +struct V +foo (struct V v) +{ + struct V ret; + ret.x = __builtin_copysignf (1.0e+0, v.x); + ret.y = __builtin_copysignf (1.0e+0, v.y); + return ret; +} + +float +bar (struct V v) +{ + return __builtin_copysignf (v.x, v.y); +} + +float +baz (struct V v) +{ + return v.x * __builtin_copysignf (1.0f, v.y); +} diff --git a/gcc/testsuite/gcc.dg/pr104644.c b/gcc/testsuite/gcc.dg/pr104644.c new file mode 100644 index 0000000..70bf3a4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104644.c @@ -0,0 +1,9 @@ +/* PR tree-optimization/104644 */ +/* { dg-do compile } */ +/* { dg-options "-Wno-overflow" } */ + +int +foo (void) +{ + return __builtin_bswap16 (1.31072e+5f) != (signed char) 1.31072e+5f; +} diff --git a/gcc/testsuite/gcc.dg/pr104675-1.c b/gcc/testsuite/gcc.dg/pr104675-1.c new file mode 100644 index 0000000..af0b439 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104675-1.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/104675 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +_Complex int +foo (_Complex int a) +{ + return (-1 + -1i) - a; +} + +_Complex int +bar (_Complex int a) +{ + return -a - (1 + 1i); +} + +_Complex int +baz (_Complex int a) +{ + _Complex int b = -1 + -1i; + return b - a; +} + +_Complex int +qux (_Complex int a) +{ + _Complex int b = 1 + 1i; + return -a - b; +} diff --git a/gcc/testsuite/gcc.dg/pr104675-2.c b/gcc/testsuite/gcc.dg/pr104675-2.c new file mode 100644 index 0000000..037d0c4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104675-2.c @@ -0,0 +1,18 @@ +/* PR tree-optimization/104675 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +void baz (int i); + +void +bar (_Complex int c, short s) +{ + c -= s; + baz (__real__ c + __imag__ c); +} + +void +foo (void) +{ + bar (-1 - 1i, 0); +} diff --git a/gcc/testsuite/gcc.dg/pr104675-3.c b/gcc/testsuite/gcc.dg/pr104675-3.c new file mode 100644 index 0000000..3b2eb64 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104675-3.c @@ -0,0 +1,29 @@ +/* PR tree-optimization/104675 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +_Complex unsigned int +foo (_Complex unsigned int x) +{ + return (x / 2) * 2; +} + +_Complex unsigned int +bar (_Complex unsigned int x) +{ + return (x * 2) / 2; +} + +_Complex unsigned int +baz (_Complex unsigned int x) +{ + _Complex unsigned int y = x / 2; + return y * 2; +} + +_Complex unsigned int +qux (_Complex unsigned int x) +{ + _Complex unsigned int y = x * 2; + return y / 2; +} diff --git a/gcc/testsuite/gcc.dg/pr104700-2.c b/gcc/testsuite/gcc.dg/pr104700-2.c new file mode 100644 index 0000000..e0759cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104700-2.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-ccp -fno-tree-dce -fno-tree-vrp" } */ + +int a, b; +int main() { + int c = 2, d, e = 0; + if (a) + e = 2; + int f, g = -(1L | (e && f && f & e)); + if (g) + L: + g = c; + c = 0; + d = e * g; + if (d) + goto L; + while (e) { + int i = (a && b) * i; + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr104786.c b/gcc/testsuite/gcc.dg/pr104786.c new file mode 100644 index 0000000..3076d23 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104786.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-std=gnu90" } */ + +void h(void *di, int num) +{ + char (*t)[num] = di; + __asm__ ("" : "=X"( *t)); +} diff --git a/gcc/testsuite/gcc.dg/pr104910.c b/gcc/testsuite/gcc.dg/pr104910.c new file mode 100644 index 0000000..10fed81 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104910.c @@ -0,0 +1,14 @@ +/* PR target/104910 */ +/* { dg-do compile } */ +/* { dg-options "-Os -fno-forward-propagate" } */ +/* { dg-additional-options "-fstack-protector-all" { target fstack_protector } } */ + +void +bar (void); + +void +foo (int x) +{ + if (x) + bar (); +} diff --git a/gcc/testsuite/gcc.dg/pr104975.c b/gcc/testsuite/gcc.dg/pr104975.c new file mode 100644 index 0000000..04532fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr104975.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fharden-compares -fno-inline -fno-ipa-pure-const" } */ + +__attribute__ ((pure, returns_twice)) int +bar (int); + +int +quux (void) +{ + return 0; +} + +int +foo (short int x) +{ + x = !x; + bar (quux ()); + + return x; +} diff --git a/gcc/testsuite/gcc.dg/pr105049.c b/gcc/testsuite/gcc.dg/pr105049.c new file mode 100644 index 0000000..b0518c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105049.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fno-tree-forwprop" } */ + +typedef short __attribute__((__vector_size__ (sizeof(short)))) V; +typedef short __attribute__((__vector_size__ (2*sizeof(short)))) U; +char c; + +U +foo (void) +{ + return __builtin_shufflevector ((V){}, (V){}, 0, 0) & c; +} diff --git a/gcc/testsuite/gcc.dg/pr105080.c b/gcc/testsuite/gcc.dg/pr105080.c new file mode 100644 index 0000000..77ee7ee --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105080.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O0 -Wall" } */ + +int main() +{ + char foo[3]; + int i; + + for (i = 0; i < 16; i++) + __builtin_snprintf(foo, sizeof(foo), "%d", i); /* { dg-bogus "truncated" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr105094.c b/gcc/testsuite/gcc.dg/pr105094.c new file mode 100644 index 0000000..da6dc17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105094.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/105094 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct S { short a; char b[~(__SIZE_TYPE__)0 / __CHAR_BIT__ - 1]; }; +void bar (struct S *); + +void +foo (void) +{ + struct S s = { 5 }; + bar (&s); +} diff --git a/gcc/testsuite/gcc.dg/pr105140.c b/gcc/testsuite/gcc.dg/pr105140.c new file mode 100644 index 0000000..7d30985 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105140.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-Os -w -Wno-psabi" } */ +/* { dg-skip-if "PR105147" { powerpc*-*-* s390*-*-* } } */ + +typedef char __attribute__((__vector_size__ (16 * sizeof (char)))) U; +typedef int __attribute__((__vector_size__ (16 * sizeof (int)))) V; + +void bar (); + +bar (int i, int j, int k, V v) +{ +} + +void +foo (void) +{ + bar ((V){}, (V){}, (V){}, (U){}); +} diff --git a/gcc/testsuite/gcc.dg/pr105149.c b/gcc/testsuite/gcc.dg/pr105149.c new file mode 100644 index 0000000..b748f45 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105149.c @@ -0,0 +1,16 @@ +/* PR c/105149 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +#include <stdarg.h> + +void +foo (int s, ...) +{ + int e; + va_list ap; + + va_start (ap, s); + e = va_arg (ap, int (void)) (); /* { dg-error "second argument to 'va_arg' is a function type" } */ + va_end (ap); +} diff --git a/gcc/testsuite/gcc.dg/pr105150.c b/gcc/testsuite/gcc.dg/pr105150.c new file mode 100644 index 0000000..900460c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105150.c @@ -0,0 +1,8 @@ +/* PR tree-optimization/105150 */ +/* { dg-options "-w -Ofast" } */ + +#define A(name) __typeof (__builtin_##name (0)) name (); \ + float name##1 () { return !name (1); } \ + double name##2 () { return name (1.0L); } +#define B(name) A(name) A(name##l) +B (sqrt) diff --git a/gcc/testsuite/gcc.dg/pr105165.c b/gcc/testsuite/gcc.dg/pr105165.c new file mode 100644 index 0000000..055a105 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105165.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +unsigned int _Complex a0; +unsigned int _Complex +foo (unsigned int _Complex a1, unsigned int _Complex a2) +{ + unsigned int _Complex x; + asm goto ("" : "=r" (x) : : : lab); /* { dg-message "sorry, unimplemented" } */ + a0 = x; + lab: + return x + a1 + a2 + 1; +} diff --git a/gcc/testsuite/gcc.dg/pr105173.c b/gcc/testsuite/gcc.dg/pr105173.c new file mode 100644 index 0000000..3effb29 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105173.c @@ -0,0 +1,12 @@ +/* { dg-do compile { target dfp } } */ +/* { dg-options "-Ofast" } */ + +int i; + +int +foo(char c, _Decimal32 d) +{ + d *= i; + d *= -(_Decimal64)c; + return d; +} diff --git a/gcc/testsuite/gcc.dg/pr105175.c b/gcc/testsuite/gcc.dg/pr105175.c new file mode 100644 index 0000000..d8d7edb --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105175.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wvector-operation-performance" } */ +/* { dg-additional-options "-mno-sse" { target x86_64-*-* i?86-*-* } } */ + +enum { QEMU_MIGRATION_COOKIE_PERSISTENT = 1 }; +struct { + unsigned flags; + unsigned flagsMandatory; +} qemuMigrationCookieGetPersistent_mig; +void qemuMigrationCookieGetPersistent() +{ + qemuMigrationCookieGetPersistent_mig.flags &= /* { dg-bogus "will be expanded" } */ + QEMU_MIGRATION_COOKIE_PERSISTENT; + qemuMigrationCookieGetPersistent_mig.flagsMandatory &= + QEMU_MIGRATION_COOKIE_PERSISTENT; +} diff --git a/gcc/testsuite/gcc.dg/pr105211.c b/gcc/testsuite/gcc.dg/pr105211.c new file mode 100644 index 0000000..9bafe6f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105211.c @@ -0,0 +1,11 @@ +/* PR rtl-optimization/105211 */ +/* { dg-do compile } */ +/* { dg-options "-Os -ffast-math" } */ +/* { dg-add-options float32 } */ +/* { dg-require-effective-target float32 } */ + +short +foo (_Float32 f) +{ + return __builtin_roundf (f); +} diff --git a/gcc/testsuite/gcc.dg/pr105218.c b/gcc/testsuite/gcc.dg/pr105218.c new file mode 100644 index 0000000..0070057 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105218.c @@ -0,0 +1,16 @@ +/* PR tree-optimization/105218 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g" } */ + +int a, c; +void bar (void); + +void +foo (void) +{ + int b = 131; + if (a) + b = c == 2 ? 1 : c; + while (b) + bar (); +} diff --git a/gcc/testsuite/gcc.dg/pr105226.c b/gcc/testsuite/gcc.dg/pr105226.c new file mode 100644 index 0000000..9c4941d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105226.c @@ -0,0 +1,23 @@ +/* { dg-do compile } */ +/* { dg-options "-Ofast" } */ +/* { dg-require-effective-target indirect_jumps } */ + +#include <setjmp.h> +struct longjmp_buf { + jmp_buf buf; +}; +void g (); +void f () +{ + int i, n; + long *a; + long *args; + struct longjmp_buf b; + setjmp (b.buf); + for (;;) + { + for (i = 0; i < n; i++) + a[i] = args[i]; + g (); + } +} diff --git a/gcc/testsuite/gcc.dg/pr105250.c b/gcc/testsuite/gcc.dg/pr105250.c new file mode 100644 index 0000000..4683e0e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105250.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-w -Wno-psabi -O2" } */ +/* { dg-skip-if "PR105266" { powerpc*-*-* s390*-*-* } } */ + +typedef int __attribute__((__vector_size__(4))) T; +typedef int __attribute__((__vector_size__(8))) U; +typedef int __attribute__((__vector_size__(16))) V; +typedef int __attribute__((__vector_size__(32))) W; +typedef _Float32 __attribute__((__vector_size__(16))) F; +typedef _Float64 __attribute__((__vector_size__(32))) G; +void foo(); + +foo(int, int, int, int, U, U, V, V, W, W, int, + T, int, U, U, V, V, W, W, T, + T, int, U, U, V, V, W, W, T, + T, int, W, W, T, T, int, int, int, + int, int, int, W, int, int, int, int, int, int, + V, W, T, int, int, U, F, int, int, int, + int, int, int, G) +{ + foo(0, 0, 0, 0, (U){}, (U){}, (V){}, (V){}, (W){}, + (W){}, 2, (T){}, 0, 0, 0, 0, (U){}, (U){}, + (V){}, (V){}, (W){}, (W){}, (T){}, + (T){}, 0, 0, 0, 0, (U){}, (U){}, (V){}, + (V){}, (W){}, (W){}, (T){}, (T){}, 0, 0, 0, + 0, 0, 0, (T){}, + (T){}, (W){}, + (W){}, (T){}, (T){}, 0, 0, 0, 0, 0, 0, (W){}, + (V){}, (W){}, (T){}, 0, 0, (U){}, (F){}); +} diff --git a/gcc/testsuite/gcc.dg/pr105257.c b/gcc/testsuite/gcc.dg/pr105257.c new file mode 100644 index 0000000..4232942 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105257.c @@ -0,0 +1,16 @@ +/* PR target/105257 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-fpic" { target fpic } } */ + +extern int sigsetjmp (void **, int); +void *buf[32]; +void (*fn) (void); + +const char * +bar (void) +{ + sigsetjmp (buf, 0); + fn (); + return ""; +} diff --git a/gcc/testsuite/gcc.dg/pr105263.c b/gcc/testsuite/gcc.dg/pr105263.c new file mode 100644 index 0000000..5cb7fcd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105263.c @@ -0,0 +1,15 @@ +/* { dg-do compile { target dfp } } */ +/* { dg-options "-O -ffast-math -w -Wno-psabi" } */ + +typedef _Decimal64 __attribute__((__vector_size__ (8))) U; +typedef _Decimal64 __attribute__((__vector_size__ (16))) V; + +V v; + +U +foo (U u) +{ + u *= u; + u *= -(U){ v[1] }; + return u; +} diff --git a/gcc/testsuite/gcc.dg/pr105331.c b/gcc/testsuite/gcc.dg/pr105331.c new file mode 100644 index 0000000..06cf6d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105331.c @@ -0,0 +1,11 @@ +/* PR target/105331 */ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized" } */ + +#include <stdarg.h> + +int +foo (va_list *va) +{ + return va_arg (*va, double _Complex); /* { dg-bogus "may be used uninitialized" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr105333.c b/gcc/testsuite/gcc.dg/pr105333.c new file mode 100644 index 0000000..bd8bd4c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105333.c @@ -0,0 +1,21 @@ +/* PR rtl-optimization/105333 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-Og -fno-tree-coalesce-vars -fno-tree-fre" } */ + +int g; +short s; + +static inline unsigned short +bar (short a, __int128 b) +{ + b ^= (unsigned long) -a; + __builtin_strncpy ((void *) &s, (void *) &a, 1); + b *= 14; + return b; +} + +void +foo (void) +{ + g *= (__int128) bar (1, 1); +} diff --git a/gcc/testsuite/gcc.dg/pr105376.c b/gcc/testsuite/gcc.dg/pr105376.c new file mode 100644 index 0000000..f19ecf4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105376.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target dfp } } */ +/* { dg-options "-O -g" } */ + +void +foo (_Decimal64 d, _Decimal64 e) +{ + d -= -d; + d *= -e; +} diff --git a/gcc/testsuite/gcc.dg/pr105414.c b/gcc/testsuite/gcc.dg/pr105414.c new file mode 100644 index 0000000..7877270 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105414.c @@ -0,0 +1,30 @@ +/* { dg-do run { target { *-*-linux* *-*-gnu* } } } */ +/* { dg-options "-O1 -fsignaling-nans -lm" } */ +/* { dg-add-options ieee } */ +/* { dg-require-effective-target issignaling } */ + + +#define _GNU_SOURCE +#include <stdio.h> +#include <math.h> + +int main() +{ + double a = __builtin_nans (""); + + if (issignaling (fmin (a, a))) + __builtin_abort (); + + if (issignaling (fmax (a, a))) + __builtin_abort (); + + double b = __builtin_nan (""); + + if (issignaling (fmin (a, b))) + __builtin_abort (); + + if (issignaling (fmax (a, b))) + __builtin_abort (); + + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr105415.c b/gcc/testsuite/gcc.dg/pr105415.c new file mode 100644 index 0000000..4603c0c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105415.c @@ -0,0 +1,26 @@ +/* PR debug/105415 */ +/* { dg-do compile } */ +/* { dg-require-effective-target pthread } */ +/* { dg-options "-O2 -ftree-parallelize-loops=2 -fcompare-debug" } */ + +int m; +static int n; + +void +foo (void) +{ + int s = 0; + + while (m < 1) + { + s += n; + ++m; + } +} + +void +bar (int *arr, int i) +{ + while (i < 1) + arr[i++] = 1; +} diff --git a/gcc/testsuite/gcc.dg/pr105455.c b/gcc/testsuite/gcc.dg/pr105455.c new file mode 100644 index 0000000..81e9154 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105455.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fharden-conditional-branches -funroll-loops --param max-loop-header-insns=1" } */ + +__attribute__ ((cold)) void +bar (void); + +void +foo (int x) +{ + if (x) + { + int i; + + for (i = 0; i < 101; ++i) + bar (); + } +} diff --git a/gcc/testsuite/gcc.dg/pr105458.c b/gcc/testsuite/gcc.dg/pr105458.c new file mode 100644 index 0000000..eb58bf2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105458.c @@ -0,0 +1,20 @@ +/* PR tree-optimization/105458 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -fexpensive-optimizations -fno-tree-dominator-opts " } */ + +void +yj (int j4) +{ + int t3; + + for (t3 = 0; t3 < 6; ++t3) + { + short int v4 = t3; + + if (v4 == j4 || v4 > t3) + for (;;) + { + } + } +} + diff --git a/gcc/testsuite/gcc.dg/pr105461.c b/gcc/testsuite/gcc.dg/pr105461.c new file mode 100644 index 0000000..1e6743c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105461.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fassociative-math -fsignaling-nans -fvar-tracking -w" } */ + +int +bar (float *x, int y) +{ + *x = y; + + return *x; +} + +__attribute__ ((optimize ("O2"))) void +foo (float *x, int y) +{ + int a = bar (x, y); +} diff --git a/gcc/testsuite/gcc.dg/pr105528.c b/gcc/testsuite/gcc.dg/pr105528.c new file mode 100644 index 0000000..e380d56 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105528.c @@ -0,0 +1,23 @@ +/* PR tree-optimization/105528 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-psabi -fcompare-debug" } */ +/* { dg-additional-options "-mavx512f" { target i?86-*-* x86_64-*-* } } */ + +typedef unsigned V __attribute__((__vector_size__ (64))); +V g; + +V +bar (V v) +{ + V w; + v <<= (V){(V){}[53]} >= v & 5; + w[w[5]] -= ~0; + v %= ~0; + return v + w; +} + +void +foo (void) +{ + g -= (V){bar((V){~0})[3]}; +} diff --git a/gcc/testsuite/gcc.dg/pr105591.c b/gcc/testsuite/gcc.dg/pr105591.c new file mode 100644 index 0000000..9554c42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105591.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-Wno-psabi -O" } */ +/* { dg-additional-options "-mavx" { target x86_64-*-* i?86-*-* } } */ +typedef unsigned long long __attribute__((__vector_size__ (16))) U; +typedef unsigned long long __attribute__((__vector_size__ (32))) V; + +V +foo (U u) +{ + U x = __builtin_shuffle (u, (U) { 0xBE2ED0AB630B33FE }); + return __builtin_shufflevector (u, x, 2, 1, 0, 3); +} diff --git a/gcc/testsuite/gcc.dg/pr105597.c b/gcc/testsuite/gcc.dg/pr105597.c new file mode 100644 index 0000000..e463ec6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105597.c @@ -0,0 +1,27 @@ +/* PR tree-optimization/105597 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wno-int-conversion" } */ + +typedef struct { + int allocated; +} vvec; + +int vvneeds_want, mgpssort; + +void vvinit(vvec *v, int minelems) { v->allocated = -minelems; } + +void vvneeds(vvec *v, int needed) { + if (needed > v->allocated) + if (v->allocated < 0) + ; + else { + int next = v->allocated + (v->allocated >> 1); + vvneeds_want = next; + } +} + +void mgpssort_1() { + vvinit((vvec *) &mgpssort, mgpssort_1); + vvneeds((vvec *) &mgpssort, mgpssort_1); +} + diff --git a/gcc/testsuite/gcc.dg/pr105630.c b/gcc/testsuite/gcc.dg/pr105630.c new file mode 100644 index 0000000..c39ca7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105630.c @@ -0,0 +1,22 @@ +/* PR debug/105630 */ +/* { dg-do compile { target pthread } } */ +/* { dg-options "-O1 -ftree-parallelize-loops=2 -fcompare-debug" } */ + +int m; +static int n; + +void +foo (void) +{ + int *arr[] = { &n, &n, &n }; + int unused = n; + + m = 0; +} + +void +bar (int *arr, int i) +{ + while (i < 1) + arr[i++] = 1; +} diff --git a/gcc/testsuite/gcc.dg/pr105635.c b/gcc/testsuite/gcc.dg/pr105635.c new file mode 100644 index 0000000..aa02f59 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105635.c @@ -0,0 +1,11 @@ +/* PR c/105635 */ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +void foo (int, int[*]); /* { dg-message "previous declaration of 'foo' with type" } */ + +foo (int x, int y) /* { dg-warning "return type defaults to 'int'" } */ +{ /* { dg-warning "conflicting types for 'foo'" "" { target *-*-* } .-1 } */ + /* { dg-message "declared here" "" { target *-*-* } .-2 } */ + return (x >= 0) != (y < 0); /* { dg-warning "'return' with a value, in function returning void" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr105763.c b/gcc/testsuite/gcc.dg/pr105763.c new file mode 100644 index 0000000..4c76b17 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105763.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int rl2_decode_png_bit_depth; +int *rl2_decode_png_p_data; +void png_destroy_read_struct (); +int __attribute__((returns_twice)) _setjmp (); +void rl2_decode_png_row_pointers() +{ + unsigned sample_type = 0; + _setjmp(); + switch (rl2_decode_png_bit_depth) + case 6: + sample_type = 7; + png_destroy_read_struct(); + for (;;) + switch (sample_type) + case 3: + case 5: + *rl2_decode_png_p_data; +} diff --git a/gcc/testsuite/gcc.dg/pr105770.c b/gcc/testsuite/gcc.dg/pr105770.c new file mode 100644 index 0000000..c1e0140 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105770.c @@ -0,0 +1,19 @@ +/* PR tree-optimization/105770 */ +/* { dg-do compile } */ +/* { dg-options "-O1 -funswitch-loops -fno-tree-forwprop" } */ + +char a; + +void +foo (void) +{ + while (a) + switch (a) + { + case ' ': + case '\t': + return; + } + + __builtin_unreachable (); +} diff --git a/gcc/testsuite/gcc.dg/pr105825.c b/gcc/testsuite/gcc.dg/pr105825.c new file mode 100644 index 0000000..d1eb829 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105825.c @@ -0,0 +1,13 @@ +/* PR target/105825 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ +/* { dg-additional-options "-mavx" { target avx } } */ + +__int128 j; +int i; + +void +foo (void) +{ + j <<= __builtin_parityll (i); +} diff --git a/gcc/testsuite/gcc.dg/pr105835.c b/gcc/testsuite/gcc.dg/pr105835.c new file mode 100644 index 0000000..354c81c --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105835.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O1 -fdump-tree-optimized" } */ + +void foo(); + +static int b; + +static short a(short c, unsigned short d) { return c - d; } + +int main() { + int e = -(0 < b); + if (a(1, e)) + b = 0; + else + foo(); +} + +/* { dg-final { scan-tree-dump-not "goto" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr105853.c b/gcc/testsuite/gcc.dg/pr105853.c new file mode 100644 index 0000000..4f234ac --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105853.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +struct { + struct { + short e16[3]; + } +} const eth_addr_zero = {{}}; /* { dg-warning "no semicolon at" } */ +void compose_nd_na_ipv6_src() { + packet_set_nd(eth_addr_zero); /* { dg-warning "implicit declaration" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr105856.c b/gcc/testsuite/gcc.dg/pr105856.c new file mode 100644 index 0000000..dd3aa2f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105856.c @@ -0,0 +1,10 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +#pragma pack(1) +struct { + unsigned f0; +} static g_251 = {6}; +void g_329_3() { + func_19(g_251); /* { dg-warning "implicit declaration" } */ +} + diff --git a/gcc/testsuite/gcc.dg/pr105911.c b/gcc/testsuite/gcc.dg/pr105911.c new file mode 100644 index 0000000..55df3f1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105911.c @@ -0,0 +1,16 @@ +/* PR target/105911 */ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2" } */ + +__int128 v, x; +unsigned __int128 w; + +void bar (__int128, __int128); + +void +foo (void) +{ + bar (v /= v, v >> (v &= 0x100000001)); + bar (w /= w, w >> (w &= 0x300000003)); + bar (x /= x, x << (x &= 0x700000007)); +} diff --git a/gcc/testsuite/gcc.dg/pr105969.c b/gcc/testsuite/gcc.dg/pr105969.c new file mode 100644 index 0000000..52c63fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr105969.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-Wall" } */ + +struct A +{ + char a[0][0][0]; +}; +extern struct A b[][2]; +void f (void) +{ + __builtin_sprintf (b[0][0].a[1][0], "%s", b[0][0].a[1][0]); /* { dg-warning "past the end" } */ + /* { dg-warning "overlaps destination" "" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/gcc.dg/pr106027.c b/gcc/testsuite/gcc.dg/pr106027.c new file mode 100644 index 0000000..735205f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106027.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O" } */ + +int +foo (unsigned int x, int y) +{ + return x <= (((y != y) < 0) ? y < 1 : 0); +} diff --git a/gcc/testsuite/gcc.dg/pr106063.c b/gcc/testsuite/gcc.dg/pr106063.c new file mode 100644 index 0000000..467b31d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106063.c @@ -0,0 +1,9 @@ +/* { dg-do compile { target int128 } } */ +/* { dg-options "-O2 -fno-tree-forwprop --disable-tree-evrp" } */ +typedef __int128 __attribute__((__vector_size__ (16))) V; + +V +foo (V v) +{ + return (v & (V){15}) == v; +} diff --git a/gcc/testsuite/gcc.dg/pr106114.c b/gcc/testsuite/gcc.dg/pr106114.c new file mode 100644 index 0000000..64c8b8d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106114.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-dom2" } */ + +int printf(const char *, ...); +char a = 139, b; +int main() { + char c = 173; + b = a; + while (c <= a || a < -117) + c = printf("0\n"); + return 0; +} + +/* { dg-final { scan-tree-dump-times "if" 2 "dom2" } } */ diff --git a/gcc/testsuite/gcc.dg/pr106189.c b/gcc/testsuite/gcc.dg/pr106189.c new file mode 100644 index 0000000..0eca834 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106189.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Warray-bounds=2 -w" } */ + +int a_n_0_0_a[][0]; +void a_n_0_0() { T(((char *)a_n_0_0_a)[1]); } diff --git a/gcc/testsuite/gcc.dg/pr106198.c b/gcc/testsuite/gcc.dg/pr106198.c new file mode 100644 index 0000000..00d2758 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106198.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O3" } */ + +int printf(const char *, ...); +long a; +int b; +volatile int c; +int main() { + long e = a; + int f = a; + L: + if (b > 0) { + printf("0"); + goto L; + } + if (f) { + printf("%ld", (long)b); + goto L; + } + e >= b && c; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr106249.c b/gcc/testsuite/gcc.dg/pr106249.c new file mode 100644 index 0000000..f97b07f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106249.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O -floop-unroll-and-jam --param unroll-jam-min-percent=0" } */ + +void +foo (double *arr) +{ + int i, j; + + for (i = 0; i < 4; ++i) + for (j = 0; j < 4; ++j) + arr[j] = 0; + + for (i = 1; i < 4; ++i) + for (j = 0; j < 4; ++j) + arr[j] = 1.0 / (i + 1); +} diff --git a/gcc/testsuite/gcc.dg/pr106264.c b/gcc/testsuite/gcc.dg/pr106264.c new file mode 100644 index 0000000..6b4af49 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106264.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -Wall" } */ +double frexp (double, int*); +double modf (double, double*); +double remquo (double, double, int*); + +int f (void) +{ + int y; + frexp (1.0, &y); + return y; +} + +double g (void) +{ + double y; + modf (1.0, &y); + return y; +} + +int h (void) +{ + int y; + remquo (1.0, 1.0, &y); + return y; +} + diff --git a/gcc/testsuite/gcc.dg/pr106278.c b/gcc/testsuite/gcc.dg/pr106278.c new file mode 100644 index 0000000..ab312b3 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106278.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +void __assert_fail(); +struct a { + int b; + int c; + int d; + int : 2; +}; +int e, f; +struct a g, i; +const struct a h; +int main() { + struct a j; + g = h; + if (e) + __assert_fail(); + if (f) + j = h; + i = j; + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr106379-1.c b/gcc/testsuite/gcc.dg/pr106379-1.c new file mode 100644 index 0000000..7f2575e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106379-1.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ +/* { dg-options "-O -fdump-tree-forwprop1" } */ + +_Bool foo (_Bool a, _Bool b) +{ + return !a == !b; +} + +/* { dg-final { scan-tree-dump "\[ab\]_\[0-9\]+\\(D\\) == \[ba\]_\[0-9\]+\\(D\\)" "forwprop1" } } */ diff --git a/gcc/testsuite/gcc.dg/pr106397.c b/gcc/testsuite/gcc.dg/pr106397.c new file mode 100644 index 0000000..2bc17f8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr106397.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fprefetch-loop-arrays --param l2-cache-size=0 --param prefetch-latency=3 -fprefetch-loop-arrays" } */ +/* { dg-additional-options "-march=i686 -msse" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */ + +int +bar (void) +{ + /* No return statement. */ +} + +__attribute__ ((simd)) int +foo (void) +{ + if (bar ()) + return 0; + + __builtin_unreachable (); +} diff --git a/gcc/testsuite/gcc.dg/pr23911.c b/gcc/testsuite/gcc.dg/pr23911.c index 3fa0412..691f350 100644 --- a/gcc/testsuite/gcc.dg/pr23911.c +++ b/gcc/testsuite/gcc.dg/pr23911.c @@ -16,5 +16,6 @@ test (void) /* After DCE2 which runs after FRE, the expressions should be fully constant folded. There should be no loads from b left. */ -/* { dg-final { scan-tree-dump-times "__complex__ \\\(1.0e\\\+0, 0.0\\\)" 2 "dce3" } } */ +/* { dg-final { scan-tree-dump-times {(?n)REALPART_EXPR.*= 1\.0e\+0} 2 "dce3" } } */ +/* { dg-final { scan-tree-dump-times {(?n)IMAGPART_EXPR.*= 0\.0} 2 "dce3" } } */ /* { dg-final { scan-tree-dump-times "= b" 0 "dce3" } } */ diff --git a/gcc/testsuite/gcc.dg/pr46647.c b/gcc/testsuite/gcc.dg/pr46647.c index 7eefc6e..a903273 100644 --- a/gcc/testsuite/gcc.dg/pr46647.c +++ b/gcc/testsuite/gcc.dg/pr46647.c @@ -25,5 +25,5 @@ func3 (void) return 0; } -/* The xfail for avr and cris-* is due to PR53535. */ -/* { dg-final { scan-tree-dump-not "memset" "optimized" { xfail avr-*-* cris-*-* } } } */ +/* The xfail for avr, cris-* and pru is due to PR53535. */ +/* { dg-final { scan-tree-dump-not "memset" "optimized" { xfail avr-*-* cris-*-* pru-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr86010-2.c b/gcc/testsuite/gcc.dg/pr86010-2.c new file mode 100644 index 0000000..4c82e65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr86010-2.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void f (void*); + +void g (char *a) +{ + __builtin_memset (a, 0, 8); + __builtin_memset (a, 0, 8); + + f (a); +} + +void h (char *a) +{ + __builtin_memset (a, 0, 8); + __builtin_memset (a, 0, 7); + + f (a); +} + +/* { dg-final { scan-tree-dump-times "__builtin_memset" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr86010.c b/gcc/testsuite/gcc.dg/pr86010.c new file mode 100644 index 0000000..ac27989 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr86010.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +void f (void*); + +void g (void) +{ + char a[8]; + __builtin_memset (a, 0, 8); + __builtin_memset (a, 0, 8); + + f (a); +} + +void h (void) +{ + char a[8]; + __builtin_memset (a, 0, 8); + __builtin_memset (a, 0, 7); + + f (a); +} + +/* { dg-final { scan-tree-dump-times "__builtin_memset" 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr90838.c b/gcc/testsuite/gcc.dg/pr90838.c index 41c5dab..7502b84 100644 --- a/gcc/testsuite/gcc.dg/pr90838.c +++ b/gcc/testsuite/gcc.dg/pr90838.c @@ -1,5 +1,8 @@ /* { dg-do compile } */ /* { dg-options "-O2 -fdump-tree-forwprop2-details" } */ +/* { dg-additional-options "-mbmi" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } */ +/* { dg-additional-options "-march=rv64gc_zbb" { target { rv64 } } } */ +/* { dg-additional-options "-march=rv32gc_zbb" { target { rv32 } } } */ int ctz1 (unsigned x) { @@ -56,4 +59,26 @@ int ctz4 (unsigned long x) return table[(lsb * magic) >> 58]; } +/* { dg-final { scan-tree-dump-times {= \.CTZ} 4 "forwprop2" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-times "tzcntq\t" 1 { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-times "tzcntl\t" 3 { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-times "andl\t" 2 { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-not "negq" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-not "imulq" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ +/* { dg-final { scan-assembler-not "shrq" { target { { i?86-*-* x86_64-*-* } && { ! { ia32 } } } } } } */ + /* { dg-final { scan-tree-dump-times {= \.CTZ} 4 "forwprop2" { target aarch64*-*-* } } } */ +/* { dg-final { scan-assembler-times "clz\t" 4 { target aarch64*-*-* } } } */ +/* { dg-final { scan-assembler-times "and\t" 2 { target aarch64*-*-* } } } */ +/* { dg-final { scan-assembler-not "cmp\t.*0" { target aarch64*-*-* } } } */ + +/* { dg-final { scan-tree-dump-times {= \.CTZ} 4 "forwprop2" { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "ctz\t" 1 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "ctzw\t" 3 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-times "andi\t" 2 { target { rv64 } } } } */ +/* { dg-final { scan-assembler-not "mul" { target { rv64 } } } } */ + +/* { dg-final { scan-tree-dump-times {= \.CTZ} 3 "forwprop2" { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "ctz\t" 3 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "andi\t" 1 { target { rv32 } } } } */ +/* { dg-final { scan-assembler-times "mul\t" 1 { target { rv32 } } } } */ diff --git a/gcc/testsuite/gcc.dg/pr91134.c b/gcc/testsuite/gcc.dg/pr91134.c new file mode 100644 index 0000000..8844f42 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr91134.c @@ -0,0 +1,32 @@ +/* PR c/91134 */ +/* { dg-options "-fdiagnostics-show-caret" } */ + +struct X { int member; } x; +struct Y { struct X **x; } y; + +int +foo (void) +{ + struct X *pointer = &x; + struct Y *yp = &y; + struct X **pointerpointer = &pointer; + int i = *pointerpointer->member; /* { dg-error "'pointerpointer' is a pointer to pointer; did you mean to dereference it before applying '->' to it\\\?" } */ +/* { dg-begin-multiline-output "" } + int i = *pointerpointer->member; + ^~ + (* ) + { dg-end-multiline-output "" } */ + int j = pointer.member; /* { dg-error "'pointer' is a pointer; did you mean to use '->'\\\?" } */ +/* { dg-begin-multiline-output "" } + int j = pointer.member; + ^ + -> + { dg-end-multiline-output "" } */ + int k = yp->x->member; /* { dg-error "'yp->x' is a pointer to pointer; did you mean to dereference it before applying '->' to it\\\?" } */ +/* { dg-begin-multiline-output "" } + int k = yp->x->member; + ^~ + (* ) + { dg-end-multiline-output "" } */ + return i + j + k; +} diff --git a/gcc/testsuite/gcc.dg/pr94026.c b/gcc/testsuite/gcc.dg/pr94026.c new file mode 100644 index 0000000..deb4efd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94026.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int f1(int x) { return ((x >> 8) & 6) != 0; } +int f2(int x) { return ((x << 2) & 24) != 0; } +int f3(unsigned x) { return ((x << 2) & 15) != 0; } +int f4(unsigned x) { return ((x >> 2) & 14) != 0; } + +int fifth (int c) +{ + int a = (c >> 8) & 7; + + if (a >= 2) { + return 1; + } else { + return 0; + } +} +/* { dg-final { scan-tree-dump-not " << " "optimized" } } */ +/* { dg-final { scan-tree-dump-not " >> " "optimized" } } */ + diff --git a/gcc/testsuite/gcc.dg/pr94899.c b/gcc/testsuite/gcc.dg/pr94899.c new file mode 100644 index 0000000..9fad057 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94899.c @@ -0,0 +1,49 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +typedef __INT16_TYPE__ int16_t; +typedef __INT32_TYPE__ int32_t; +typedef __UINT16_TYPE__ uint16_t; +typedef __UINT32_TYPE__ uint32_t; + +#define MAGIC (~ (uint32_t) 0 / 2 + 1) + +int +f_i16_i16 (int16_t x, int16_t y) +{ + return x + MAGIC < y + MAGIC; +} + +int +f_i16_i32 (int16_t x, int32_t y) +{ + return x + MAGIC < y + MAGIC; +} + +int +f_i32_i32 (int32_t x, int32_t y) +{ + return x + MAGIC < y + MAGIC; +} + +int +f_u32_i32 (uint32_t x, int32_t y) +{ + return x + MAGIC < y + MAGIC; +} + +int +f_u32_u32 (uint32_t x, uint32_t y) +{ + return x + MAGIC < y + MAGIC; +} + +int +f_i32_i32_sub (int32_t x, int32_t y) +{ + return x - MAGIC < y - MAGIC; +} + +/* The addition/subtraction of constants should be optimized away. */ +/* { dg-final { scan-tree-dump-not " \\+ " "optimized"} } */ +/* { dg-final { scan-tree-dump-not " \\- " "optimized"} } */ diff --git a/gcc/testsuite/gcc.dg/pr94920-2.c b/gcc/testsuite/gcc.dg/pr94920-2.c new file mode 100644 index 0000000..a2d2332 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr94920-2.c @@ -0,0 +1,15 @@ +/* PR tree-optimization/94920 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +/* Form from PR. */ +__attribute__((noipa)) unsigned int foo(int x) { + return x <= 0 ? -x : 0; +} + +/* Changed order. */ +__attribute__((noipa)) unsigned int bar(int x) { + return 0 >= x ? -x : 0; +} + +/* { dg-final {scan-tree-dump-times " MAX_EXPR " 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr98198.c b/gcc/testsuite/gcc.dg/pr98198.c new file mode 100644 index 0000000..489afae --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98198.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +static inline void sub_1 ( ) { + struct struct_1 var_9 , var_10 +} + +static int var_9[1] __attribute__ ( ( section ( ".data" ) ) ) ; +/* { dg-excess-errors "" } */ diff --git a/gcc/testsuite/gcc.dg/pr98211.c b/gcc/testsuite/gcc.dg/pr98211.c index cea371d..8f14c8f 100644 --- a/gcc/testsuite/gcc.dg/pr98211.c +++ b/gcc/testsuite/gcc.dg/pr98211.c @@ -13,15 +13,19 @@ test (int var_1, short int a, short int b, short int c, short int d) _Bool _28; short int _30; short int _32; + _Bool _29; + _Bool _31; __BB(2): _24 = test_var_3; tem_25 = _24 != 0; tem2_26 = var_1_11(D) != 0; _28 = tem_25 | tem2_26; - _30 = _28 != _Literal (_Bool) 0 ? a_16(D) : b_15(D); + _29 = _28 != _Literal (_Bool) 0; + _30 = _29 ? a_16(D) : b_15(D); arr_20[0u] = _30; - _32 = _28 != _Literal (_Bool) 0 ? c_19(D) : d_18(D); + _31 = _28 != _Literal (_Bool) 0; + _32 = _31 ? c_19(D) : d_18(D); arr_20[8u] = _32; arr_20[1u] = _30; arr_20[9u] = _32; diff --git a/gcc/testsuite/gcc.dg/pr98304-1.c b/gcc/testsuite/gcc.dg/pr98304-1.c new file mode 100644 index 0000000..dce54dd --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98304-1.c @@ -0,0 +1,57 @@ +/* PR tree-optimization/98304 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +/* Signed test function. */ +__attribute__((noipa)) int foo(int n) { + return n - (((n > 63) ? n : 63) & -64); +} + +/* Unsigned test function. */ +__attribute__((noipa)) unsigned int bar(unsigned int n) { + return n - (((n > 63) ? n : 63) & -64); +} + +/* Different power of 2. */ +__attribute__((noipa)) int goo(int n) { + return n - (((n > 31) ? n : 31) & -32); +} + +/* Commutative property (should be identical to foo) */ +__attribute__((noipa)) int baz(int n) { + return n - (((64 > n) ? 63 : n) & -64); +} + +/* < instead of >. */ +__attribute__((noipa)) int fred(int n) { + return n - (((63 < n) ? n : 63) & -64); +} + +/* Constant is not a power of 2 so should not simplify. */ +__attribute__((noipa)) int qux(int n) { + return n - (((n > 62) ? n : 62) & -63); +} + +/* Constant is not a power of 2 so should not simplify. */ +__attribute__((noipa)) unsigned int quux(unsigned int n) { + return n - (((n > 62) ? n : 62) & -63); +} + +/* Constant is a variable so should not simplify. */ +__attribute__((noipa)) int waldo(int n, int x) { + return n - (((n > 63) ? n : 63) & x); +} + +/* Difference between constants is not -1. */ +__attribute__((noipa)) int corge(int n) { + return n - (((n > 1) ? n : 1) & -64); +} + +/* Difference between constants is not -1. */ +__attribute__((noipa)) unsigned int thud(unsigned int n) +{ + return n - (((n > 1) ? n : 1) & -64); +} + +/* { dg-final { scan-tree-dump-times " - " 5 "optimized" } } */ +/* { dg-final { scan-tree-dump-times " <= " 4 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr98420.c b/gcc/testsuite/gcc.dg/pr98420.c new file mode 100644 index 0000000..c289b84 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98420.c @@ -0,0 +1,8 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -ffinite-math-only -frounding-math -fdump-tree-optimized" } */ +double foo (double a) +{ + return a - a; +} + +/* { dg-final { scan-tree-dump " = a_\[0-9\]\\(D\\) - a_\[0-9\]\\(D\\);" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr98865.c b/gcc/testsuite/gcc.dg/pr98865.c new file mode 100644 index 0000000..95f7270 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr98865.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +int foo(int x, int y) +{ + return -(x&1) & y; +} + +int bar(int x, int y) +{ + return (x&1) * y; +} + +/* { dg-final { scan-tree-dump-times " \\* " 2 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/pr99578-1.c b/gcc/testsuite/gcc.dg/pr99578-1.c new file mode 100644 index 0000000..c31d95d --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-1.c @@ -0,0 +1,26 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target int32 } } */ +/* { dg-options "-O2 -Warray-bounds" } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +void +foo (struct S *p) +{ + if (p) return; + __builtin_memset (p->b, 0, sizeof p->b); /* { dg-warning "offset \\\[0, 15\\\] is out of the bounds \\\[0, 0\\\]" } */ +} + +void +bar (struct T *p) +{ + if (p) return; + __builtin_memset (p->c, 0, sizeof p->c); /* { dg-warning "offset \\\[0, 15\\\] is out of the bounds \\\[0, 0\\\]" "" { xfail *-*-* } } */ +} + +void +baz (void) +{ + __builtin_memset ((void *) 0x8004, 0, 16); /* { dg-bogus "is out of the bounds" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99578-2.c b/gcc/testsuite/gcc.dg/pr99578-2.c new file mode 100644 index 0000000..462b606 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-2.c @@ -0,0 +1,26 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target int32 } } */ +/* { dg-options "-O2 -Wstringop-overflow" } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +void +foo (struct S *p) +{ + if (p) return; + __builtin_memset (p->b, 0, sizeof p->b); /* { dg-warning "writing 16 bytes into a region of size 0 overflows the destination" } */ +} + +void +bar (struct T *p) +{ + if (p) return; + __builtin_memset (p->c, 0, sizeof p->c); /* { dg-warning "writing 16 bytes into a region of size 0 overflows the destination" "" { xfail *-*-* } } */ +} + +void +baz (void) +{ + __builtin_memset ((void *) 0x8004, 0, 16); /* { dg-bogus "overflows the destination" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99578-3.c b/gcc/testsuite/gcc.dg/pr99578-3.c new file mode 100644 index 0000000..ef56324 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99578-3.c @@ -0,0 +1,13 @@ +/* PR middle-end/99578 */ +/* { dg-do compile { target size32plus } } */ +/* { dg-options "-O2 -Wstringop-overread" } */ + +struct S { unsigned int s; }; +extern struct S v; +extern void *memcpy (void *, const void *, __SIZE_TYPE__); + +void +foo (void) +{ + memcpy (&v, (void *)(0xe8ffc000), sizeof (struct S)); /* { dg-bogus "from a region of size 0" } */ +} diff --git a/gcc/testsuite/gcc.dg/pr99708.c b/gcc/testsuite/gcc.dg/pr99708.c new file mode 100644 index 0000000..b1eaf13 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr99708.c @@ -0,0 +1,7 @@ +/* PR target/99708 */ +/* { dg-do compile } */ + +#ifdef __SIZEOF_FLOAT128__ +__float128 f = 1.0; +#endif +long double l = 1.0; diff --git a/gcc/testsuite/gcc.dg/pragma-message.c b/gcc/testsuite/gcc.dg/pragma-message.c index 2f44b61..1b7cf09 100644 --- a/gcc/testsuite/gcc.dg/pragma-message.c +++ b/gcc/testsuite/gcc.dg/pragma-message.c @@ -42,9 +42,11 @@ #pragma message ("Okay " THREE) /* { dg-message "Okay 3" } */ /* Create a TODO() that prints a message on compilation. */ -#define DO_PRAGMA(x) _Pragma (#x) -#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) -TODO(Okay 4) /* { dg-message "TODO - Okay 4" } */ +#define DO_PRAGMA(x) _Pragma (#x) /* { dg-line pragma_loc1 } */ +#define TODO(x) DO_PRAGMA(message ("TODO - " #x)) /* { dg-line pragma_loc2 } */ +TODO(Okay 4) /* { dg-message "in expansion of macro 'TODO'" } */ +/* { dg-message "TODO - Okay 4" "test4.1" { target *-*-* } pragma_loc1 } */ +/* { dg-message "in expansion of macro 'DO_PRAGMA'" "test4.2" { target *-*-* } pragma_loc2 } */ #if 0 #pragma message ("Not printed") diff --git a/gcc/testsuite/gcc.dg/rtl/arm/mve-vxbi.c b/gcc/testsuite/gcc.dg/rtl/arm/mve-vxbi.c new file mode 100644 index 0000000..093283e --- /dev/null +++ b/gcc/testsuite/gcc.dg/rtl/arm/mve-vxbi.c @@ -0,0 +1,89 @@ +/* { dg-do compile { target arm*-*-* } } */ +/* { dg-require-effective-target arm_v8_1m_mve_ok } */ +/* { dg-add-options arm_v8_1m_mve } */ +/* { dg-additional-options "-O2" } */ + +void __RTL (startwith ("ira")) foo (void *ptr) +{ + (function "foo" + (param "ptr" + (DECL_RTL (reg/v:SI <0> [ ptr ])) + (DECL_RTL_INCOMING (reg:SI r0 [ ptr ])) + ) ;; param "n" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 5 [bb 2] NOTE_INSN_BASIC_BLOCK) + (insn 7 (set (reg:V4BI <1>) + (const_vector:V4BI [(const_int 1) + (const_int 0) + (const_int 0) + (const_int 1)])) (nil)) + (insn 8 (set (mem:V4BI (reg:SI <0>) [1 ptr+0 S2 A16]) (reg:V4BI <1>))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + ) ;; function +} + +void __RTL (startwith ("ira")) foo2 (void *ptr) +{ + (function "foo" + (param "ptr" + (DECL_RTL (reg/v:SI <0> [ ptr ])) + (DECL_RTL_INCOMING (reg:SI r0 [ ptr ])) + ) ;; param "n" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 5 [bb 2] NOTE_INSN_BASIC_BLOCK) + (insn 7 (set (reg:V8BI <1>) + (const_vector:V8BI [(const_int 1) + (const_int 0) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 1) + (const_int 0) + (const_int 1)])) (nil)) + (insn 8 (set (mem:V8BI (reg:SI <0>) [1 ptr+0 S2 A16]) (reg:V8BI <1>))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + ) ;; function +} + +void __RTL (startwith ("ira")) foo3 (void *ptr) +{ + (function "foo" + (param "ptr" + (DECL_RTL (reg/v:SI <0> [ ptr ])) + (DECL_RTL_INCOMING (reg:SI r0 [ ptr ])) + ) ;; param "n" + (insn-chain + (block 2 + (edge-from entry (flags "FALLTHRU")) + (cnote 5 [bb 2] NOTE_INSN_BASIC_BLOCK) + (insn 7 (set (reg:V16BI <1>) + (const_vector:V16BI [(const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0) + (const_int 0)])) (nil)) + (insn 8 (set (mem:V16BI (reg:SI <0>) [1 ptr+0 S2 A16]) (reg:V16BI <1>))) + (edge-to exit (flags "FALLTHRU")) + ) ;; block 2 + ) ;; insn-chain + ) ;; function +} diff --git a/gcc/testsuite/gcc.dg/sancov/cmp0.c b/gcc/testsuite/gcc.dg/sancov/cmp0.c index 8bbf06e..9fd7f5c 100644 --- a/gcc/testsuite/gcc.dg/sancov/cmp0.c +++ b/gcc/testsuite/gcc.dg/sancov/cmp0.c @@ -1,6 +1,6 @@ /* Basic test on number of inserted callbacks. */ /* { dg-do compile } */ -/* { dg-options "-fsanitize-coverage=trace-cmp -fdump-tree-optimized" } */ +/* { dg-options "-fsanitize-coverage=trace-cmp -fdump-tree-optimized -fno-thread-jumps" } */ /* { dg-skip-if "different type layout" { avr-*-* } } */ #if __SIZEOF_INT__ < 4 diff --git a/gcc/testsuite/gcc.dg/setjmp-7.c b/gcc/testsuite/gcc.dg/setjmp-7.c new file mode 100644 index 0000000..44b5bcb --- /dev/null +++ b/gcc/testsuite/gcc.dg/setjmp-7.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-guess-branch-probability -w" } */ +/* { dg-require-effective-target indirect_jumps } */ + +struct __jmp_buf_tag { }; +typedef struct __jmp_buf_tag jmp_buf[1]; +struct globals { jmp_buf listingbuf; }; +extern struct globals *const ptr_to_globals; +void foo() +{ + if ( _setjmp ( ((*ptr_to_globals).listingbuf ))) + ; +} diff --git a/gcc/testsuite/gcc.dg/sibcall-10.c b/gcc/testsuite/gcc.dg/sibcall-10.c index dcb3e6a..e78d88f 100644 --- a/gcc/testsuite/gcc.dg/sibcall-10.c +++ b/gcc/testsuite/gcc.dg/sibcall-10.c @@ -5,7 +5,7 @@ Copyright (C) 2002 Free Software Foundation Inc. Contributed by Hans-Peter Nilsson <hp@bitrange.com> */ -/* { dg-do run { xfail { { amdgcn*-*-* cris-*-* csky-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ +/* { dg-do run { xfail { { amdgcn*-*-* cris-*-* csky-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* nvptx*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ /* -mlongcall disables sibcall patterns. */ /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ /* -msave-restore disables sibcall patterns. */ diff --git a/gcc/testsuite/gcc.dg/sibcall-3.c b/gcc/testsuite/gcc.dg/sibcall-3.c index 80555cf..82ad8c7 100644 --- a/gcc/testsuite/gcc.dg/sibcall-3.c +++ b/gcc/testsuite/gcc.dg/sibcall-3.c @@ -5,7 +5,7 @@ Copyright (C) 2002 Free Software Foundation Inc. Contributed by Hans-Peter Nilsson <hp@bitrange.com> */ -/* { dg-do run { xfail { { cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ +/* { dg-do run { xfail { { cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* nvptx*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ /* -mlongcall disables sibcall patterns. */ /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ /* { dg-options "-O2 -foptimize-sibling-calls" } */ diff --git a/gcc/testsuite/gcc.dg/sibcall-4.c b/gcc/testsuite/gcc.dg/sibcall-4.c index 97086bb..5dcff3f 100644 --- a/gcc/testsuite/gcc.dg/sibcall-4.c +++ b/gcc/testsuite/gcc.dg/sibcall-4.c @@ -5,7 +5,7 @@ Copyright (C) 2002 Free Software Foundation Inc. Contributed by Hans-Peter Nilsson <hp@bitrange.com> */ -/* { dg-do run { xfail { { cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ +/* { dg-do run { xfail { { cris-*-* h8300-*-* hppa*64*-*-* m32r-*-* mcore-*-* mn10300-*-* msp430*-*-* nds32*-*-* xstormy16-*-* v850*-*-* vax-*-* xtensa*-*-* nvptx*-*-* } || { arm*-*-* && { ! arm32 } } } } } */ /* -mlongcall disables sibcall patterns. */ /* { dg-skip-if "" { powerpc*-*-* } { "-mlongcall" } { "" } } */ /* { dg-options "-O2 -foptimize-sibling-calls" } */ diff --git a/gcc/testsuite/gcc.dg/signbit-2.c b/gcc/testsuite/gcc.dg/signbit-2.c index b609f67..2f2dc44 100644 --- a/gcc/testsuite/gcc.dg/signbit-2.c +++ b/gcc/testsuite/gcc.dg/signbit-2.c @@ -4,6 +4,7 @@ /* This test does not work when the truth type does not match vector type. */ /* { dg-additional-options "-mno-avx512f" { target { i?86-*-* x86_64-*-* } } } */ /* { dg-additional-options "-march=armv8-a" { target aarch64_sve } } */ +/* { dg-skip-if "no fallback for MVE" { arm_mve } } */ #include <stdint.h> diff --git a/gcc/testsuite/gcc.dg/sso/memcpy-1.c b/gcc/testsuite/gcc.dg/sso/memcpy-1.c index b4e1c87..0dea955 100644 --- a/gcc/testsuite/gcc.dg/sso/memcpy-1.c +++ b/gcc/testsuite/gcc.dg/sso/memcpy-1.c @@ -3,20 +3,20 @@ typedef unsigned char uint8_t; typedef unsigned int uint32_t; -#define __big_endian__ scalar_storage_order("big-endian") -#define __little_endian__ scalar_storage_order("little-endian") +#define __big_endian_attr__ scalar_storage_order("big-endian") +#define __little_endian_attr__ scalar_storage_order("little-endian") typedef union { uint32_t val; uint8_t v[4]; -} __attribute__((__big_endian__)) upal_u32be_t; +} __attribute__((__big_endian_attr__)) upal_u32be_t; typedef union { uint32_t val; uint8_t v[4]; -} __attribute__((__little_endian__)) upal_u32le_t; +} __attribute__((__little_endian_attr__)) upal_u32le_t; static inline uint32_t native_to_big_endian(uint32_t t) { diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c index 1d7d1fe..21cce0f 100644 --- a/gcc/testsuite/gcc.dg/stack-usage-1.c +++ b/gcc/testsuite/gcc.dg/stack-usage-1.c @@ -105,6 +105,8 @@ # define SIZE 252 #elif defined (__CRIS__) # define SIZE 252 +#elif defined (__loongarch_lp64) +# define SIZE 240 /* 256 - 8 bytes for $fp, and 8 bytes for a temp value */ #else # define SIZE 256 #endif diff --git a/gcc/testsuite/gcc.dg/strlenopt-10.c b/gcc/testsuite/gcc.dg/strlenopt-10.c index ce959c3..6e2c259 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-10.c +++ b/gcc/testsuite/gcc.dg/strlenopt-10.c @@ -70,10 +70,10 @@ main () } /* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen1" } } */ -/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op +/* Some targets have BIGGEST_ALIGNMENT 8-bits, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn2. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { no_alignment_constraints} } } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-11.c b/gcc/testsuite/gcc.dg/strlenopt-11.c index abd9fae..952de07 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-11.c +++ b/gcc/testsuite/gcc.dg/strlenopt-11.c @@ -59,17 +59,17 @@ main () } /* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen1" } } */ -/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op +/* Some targets have BIGGEST_ALIGNMENT 8-bits, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn1. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { no_alignment_constraints } } } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* Where the memcpy is expanded, the assignemts to elements of l are propagated. */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen1" { target { no_alignment_constraints } } } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-13.c b/gcc/testsuite/gcc.dg/strlenopt-13.c index 27ecc79..4c6d526 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-13.c +++ b/gcc/testsuite/gcc.dg/strlenopt-13.c @@ -56,18 +56,18 @@ main () } /* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen1" } } */ -/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op +/* Some targets have BIGGEST_ALIGNMENT 8-bits, allowing fold_builtin_memory_op to expand the memcpy call at the end of fn1. */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen1" { target { no_alignment_constraints } } } } */ /* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen1" } } */ /* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen1" } } */ /* Where the memcpy is expanded, the assignemts to elements of l are propagated. */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen1" { target { avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen1" { target { ! no_alignment_constraints } } } } */ +/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen1" { target { no_alignment_constraints } } } } */ diff --git a/gcc/testsuite/gcc.dg/strlenopt-73.c b/gcc/testsuite/gcc.dg/strlenopt-73.c index 170b66a..6e15303 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-73.c +++ b/gcc/testsuite/gcc.dg/strlenopt-73.c @@ -69,7 +69,7 @@ void test_copy_cond_equal_length (void) T ( 0 ==, 33, 1, (i0 ? a32 : b32) + 32); } -#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) \ +#if (defined(__i386__) && defined(__SSE__)) || defined(__x86_64__) || defined(__aarch64__) \ || defined(__s390__) || defined(__powerpc64__) /* The following tests assume GCC transforms the memcpy calls into diff --git a/gcc/testsuite/gcc.dg/strlenopt-80.c b/gcc/testsuite/gcc.dg/strlenopt-80.c index a853402..a8adbf1 100644 --- a/gcc/testsuite/gcc.dg/strlenopt-80.c +++ b/gcc/testsuite/gcc.dg/strlenopt-80.c @@ -5,7 +5,8 @@ such a store. { dg-do compile { target { { aarch64*-*-* i?86-*-* x86_64-*-* } || { { powerpc*-*-* } && lp64 } } } } - { dg-options "-O2 -Wall -fdump-tree-optimized" } */ + { dg-options "-O2 -Wall -fdump-tree-optimized" } + { dg-additional-options "-msse" { target i?86-*-* x86_64-*-* } } */ #define CHAR_BIT __CHAR_BIT__ #define SIZE_MAX __SIZE_MAX__ diff --git a/gcc/testsuite/gcc.dg/torture/20220518-1.c b/gcc/testsuite/gcc.dg/torture/20220518-1.c new file mode 100644 index 0000000..1822aee --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20220518-1.c @@ -0,0 +1,39 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-funswitch-loops" } */ + +enum { + MOD_WVG_MASK_TEX_USE_INT, + MOD_WVG_MASK_TEX_USE_RED, + MOD_WVG_MASK_TEX_USE_BLUE, + MOD_WVG_MASK_TEX_USE_SAT, + MOD_WVG_MASK_TEX_USE_VAL, + MOD_WVG_MASK_TEX_USE_ALPHA +} foo_num; +float *foo_org_w; +int *foo_new_w; +float foo_fact; +int foo_tex_use_channel, foo_i, foo_texres_0; +void foo() +{ + for (; foo_num;) + switch (foo_tex_use_channel) { + case MOD_WVG_MASK_TEX_USE_INT: + foo_org_w[foo_i] = foo_new_w[foo_i] * foo_texres_0; + break; + case MOD_WVG_MASK_TEX_USE_RED: + foo_org_w[foo_i] = 0; + case MOD_WVG_MASK_TEX_USE_BLUE: + foo_org_w[foo_i] = foo_fact + foo_org_w[foo_i]; + break; + case MOD_WVG_MASK_TEX_USE_SAT: + foo_org_w[foo_i] = foo_fact; + break; + case MOD_WVG_MASK_TEX_USE_VAL: + foo_org_w[foo_i] = 0; + case MOD_WVG_MASK_TEX_USE_ALPHA: + foo_org_w[foo_i] = foo_fact + foo_org_w[foo_i]; + break; + default: + foo_org_w[foo_i] = foo_new_w[foo_i] * foo_texres_0; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/20220518-2.c b/gcc/testsuite/gcc.dg/torture/20220518-2.c new file mode 100644 index 0000000..af70d7f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20220518-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-funswitch-loops" } */ + +int Get_Spline_Val_sp_0, Get_Spline_Val_k; +double Get_Spline_Val_p, Get_Spline_Val_se_0_0_0; +double *Get_Spline_Val_v; +void Get_Spline_Val() { + int i; + for (;;) + if (i > Get_Spline_Val_sp_0) + Get_Spline_Val_k = Get_Spline_Val_se_0_0_0; + else if (Get_Spline_Val_sp_0 == 1) + Get_Spline_Val_v[Get_Spline_Val_k] = Get_Spline_Val_p; +} diff --git a/gcc/testsuite/gcc.dg/torture/20220525-1.c b/gcc/testsuite/gcc.dg/torture/20220525-1.c new file mode 100644 index 0000000..55dad31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/20220525-1.c @@ -0,0 +1,33 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-funswitch-loops" } */ + +int LIST_1, mb_pred_b_d4x4spatial_dec_picture_l0_rFrame, + mb_pred_b_d4x4spatial_dec_picture_l1_rFrame; +typedef struct { + char ref_idx[2]; +} PicMotionParams; +PicMotionParams mb_pred_b_d4x4spatial_dec_picture_mv_info; +int get_colocated_info_4x4___trans_tmp_1, get_colocated_info_4x4_list1_0; +int get_colocated_info_4x4() +{ + int moving = + get_colocated_info_4x4_list1_0 && get_colocated_info_4x4___trans_tmp_1; + return moving; +} +void mb_pred_b_d4x4spatial_dec_picture() +{ + char k; + for (;;) + { + k = 0; + for (; k < 4; k++) + if (mb_pred_b_d4x4spatial_dec_picture_l0_rFrame + || mb_pred_b_d4x4spatial_dec_picture_l1_rFrame == 0) + { + int is_not_moving = get_colocated_info_4x4(); + if (mb_pred_b_d4x4spatial_dec_picture_l1_rFrame) + if (is_not_moving) + mb_pred_b_d4x4spatial_dec_picture_mv_info.ref_idx[LIST_1] = 1; + } + } +} diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c new file mode 100644 index 0000000..3e4ecb5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp-2.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-require-effective-target dfprt } */ +/* { dg-options "-save-temps" } */ +/* { dg-add-options float16 } */ + +/* Test conversions from DFP to smaller types. */ + +_Decimal32 var32; +_Decimal64 var64; +_Decimal128 var128; +_Float16 var16; + +void __attribute__ ((__noinline__)) foo32 (_Decimal32 param32) +{ + var16 = param32; +} + +void __attribute__ ((__noinline__)) foo64 (_Decimal64 param64) +{ + var16 = param64; + var32 = param64; +} + +void __attribute__ ((__noinline__)) foo128 (_Decimal128 param128) +{ + var16 = param128; + var32 = param128; + var64 = param128; +} + +int main () +{ + foo32 (var32); + foo64 (var64); + foo128 (var128); + return 0; +} + +/* { dg-final { scan-assembler-times {\t__bid_truncsdhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_truncddhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_truncddsd2} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctdhf} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctdsd2} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_trunctddd2} 2 { target { dfp_bid } } } } */ diff --git a/gcc/testsuite/gcc.dg/torture/convert-dfp.c b/gcc/testsuite/gcc.dg/torture/convert-dfp.c new file mode 100644 index 0000000..ec13689 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/convert-dfp.c @@ -0,0 +1,63 @@ +/* { dg-do run } */ +/* { dg-require-effective-target float16_runtime } */ +/* { dg-require-effective-target dfprt } */ +/* { dg-options "-save-temps" } */ +/* { dg-add-options float16 } */ + +/* Test conversions to/from DFP values. */ + +extern void abort (); + +_Decimal32 var32 = 1.2df; + +int __attribute__ ((__noinline__)) foo32 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var32) + + (param64 == var32) + + (param128 == var32) + /* Small enough relative difference? */ + + ((((_Decimal32)param16 - var32) / var32) < 0.002df); +} + +_Decimal64 var64 = 1.2dd; + +int __attribute__ ((__noinline__)) foo64 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var64) + + (param64 == var64) + + (param128 == var64) + /* Small enough relative difference? */ + + ((((_Decimal64)param16 - var64) / var64) < 0.002dd); +} + +_Decimal128 var128 = 1.2dl; + +int __attribute__ ((__noinline__)) foo128 (_Decimal32 param32, _Decimal64 param64, _Decimal128 param128, _Float16 param16) +{ + return (param32 == var128) + + (param64 == var128) + + (param128 == var128) + /* Small enough relative difference? */ + + ((((_Decimal128)param16 - var128) / var128) < 0.002dl); +} + +int main() +{ + if (foo32 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + if (foo64 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + if (foo128 (1.2df, 1.2dd, 1.2dl, (_Float16)1.2) != 4) + abort (); + + return 0; +} + +/* { dg-final { scan-assembler-times {\t__bid_extendsddd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendsdtd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendddtd2} 3 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhfsd} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhfdd} 2 { target { dfp_bid } } } } */ +/* { dg-final { scan-assembler-times {\t__bid_extendhftd} 2 { target { dfp_bid } } } } */ diff --git a/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c b/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c index ec23274..1c28a9e 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c +++ b/gcc/testsuite/gcc.dg/torture/fp-double-convert-float-1.c @@ -1,6 +1,7 @@ /* PR57245 */ /* { dg-do run } */ /* { dg-require-effective-target fenv } */ +/* { dg-require-effective-target hard_float } */ /* { dg-additional-options "-frounding-math" } */ #include <fenv.h> diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c index 707d539..6f9a8d3 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c +++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* { dg-require-effective-target int128 } */ /* { dg-require-effective-target fenv } */ +/* { dg-require-effective-target hard_float } */ /* { dg-options "-frounding-math" } */ #include <fenv.h> diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c index 09600f9..15f478d 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c +++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c @@ -3,6 +3,7 @@ /* { dg-do run } */ /* { dg-require-effective-target int128 } */ /* { dg-require-effective-target fenv } */ +/* { dg-require-effective-target hard_float } */ /* { dg-options "-frounding-math" } */ #include <fenv.h> diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c index fadad8c..0c7bf00 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c +++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-1.c @@ -1,6 +1,7 @@ /* PR84407 */ /* { dg-do run } */ /* { dg-require-effective-target fenv } */ +/* { dg-require-effective-target hard_float } */ /* { dg-additional-options "-frounding-math -fexcess-precision=standard" } */ #include <fenv.h> diff --git a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c index 952f96b..ac24b35 100644 --- a/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c +++ b/gcc/testsuite/gcc.dg/torture/fp-uint64-convert-double-2.c @@ -1,6 +1,7 @@ /* PR84407 */ /* { dg-do run } */ /* { dg-require-effective-target fenv } */ +/* { dg-require-effective-target hard_float } */ /* { dg-additional-options "-frounding-math" } */ #include <fenv.h> diff --git a/gcc/testsuite/gcc.dg/torture/pr100786.c b/gcc/testsuite/gcc.dg/torture/pr100786.c index 42f4e48..7c03b08 100644 --- a/gcc/testsuite/gcc.dg/torture/pr100786.c +++ b/gcc/testsuite/gcc.dg/torture/pr100786.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-alias "" } */ const double a = 0; extern int b __attribute__((alias("a"))); diff --git a/gcc/testsuite/gcc.dg/torture/pr100810.c b/gcc/testsuite/gcc.dg/torture/pr100810.c new file mode 100644 index 0000000..63566f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr100810.c @@ -0,0 +1,34 @@ +/* { dg-do run } */ + +int a, b = 1, c = 1, e, f = 1, g, h, j; +volatile int d; +static void k() +{ + int i; + h = b; + if (c && a >= 0) { + while (a) { + i++; + h--; + } + if (g) + for (h = 0; h < 2; h++) + ; + if (!b) + i &&d; + } +} +static void l() +{ + for (; j < 1; j++) + if (!e && c && f) + k(); +} +int main() +{ + if (f) + l(); + if (h != 1) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr103037.c b/gcc/testsuite/gcc.dg/torture/pr103037.c new file mode 100644 index 0000000..8b3bb1e --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr103037.c @@ -0,0 +1,23 @@ +/* { dg-do run } */ + +static inline const unsigned short * +min(unsigned short *d, const unsigned short *e) +{ + return *e < *d ? e : d; +} + +unsigned short __attribute__((noipa)) +test(unsigned short arr, unsigned short val) +{ + unsigned short tem = 1; + unsigned short tem2 = *min(&arr, &tem); + return tem2 / (arr ? arr : val); +} + +int +main() +{ + if (test (2, 2) != 0) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr104676.c b/gcc/testsuite/gcc.dg/torture/pr104676.c new file mode 100644 index 0000000..0991b78 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr104676.c @@ -0,0 +1,35 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-loop-distribution -ftree-parallelize-loops=2" { target pthread } } */ + +struct S { + int f; +}; + +int n; + +int +foo (struct S *s) +{ + int arr[3]; + int v = 0; + + for (n = 0; n < 2; ++n) + { + int i; + + for (i = 0; i < 2; ++i) + { + int j; + + for (j = 0; j < s->f; ++j) + ++v; + } + + if (v) + arr[0] = 0; + + arr[n + 1] = 0; + } + + return arr[0]; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr104700-1.c b/gcc/testsuite/gcc.dg/torture/pr104700-1.c new file mode 100644 index 0000000..7b864d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr104700-1.c @@ -0,0 +1,38 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-pre" } */ + +int printf(const char *, ...); +int a, b, c = 2, d, e, *f, g; +void o() { + unsigned h = 1; + int j = -1, k, l = 1, m = 2, i; + while (c < 2) + ; +L1: + k = h; + h = -1; + if (k < 2 && !c) { + printf("%d", k); + goto L1; + } + if (!j) + l = printf("0"); + if (g) + k = 0; + if (a && k) + goto L2; + while (f) { + m = a; + d = i; + i = e; + f = &j; + L2: + if (d == l && !m) + l = b; + } + unsigned *n[1] = {&h}; +} +int main() { + o(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr104825.c b/gcc/testsuite/gcc.dg/torture/pr104825.c new file mode 100644 index 0000000..7affacc --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr104825.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Wno-stringop-overread" } */ + +int foo (fmt) +char* fmt; +{ + return (__builtin_strchr (fmt, '*') != 0 + || __builtin_strchr (fmt, 'n') != 0); +} +void bar () +{ + if (foo (1)) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105132.c b/gcc/testsuite/gcc.dg/torture/pr105132.c new file mode 100644 index 0000000..f8f0b16 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105132.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-march=skylake-avx512" { target x86_64-*-* i?86-*-* } } */ + +short a; +extern int b[]; +int c; +void d(long f[][5][5][17], int g[][5][5][17]) { + for (short e = 0; e < 17; e++) { + a = g[19][2][3][e]; + b[e] = c & (f[3][2][3][e] && g[19][2][3][e]); + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105148.c b/gcc/testsuite/gcc.dg/torture/pr105148.c new file mode 100644 index 0000000..3338b0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105148.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ + +extern void foo (void); + +static inline int +bar (int n) +{ + for (int i = 0; i < n; i++) + { + foo (); + int y[1][i]; + y[n][i] = 0; + } +} + +int +baz (void) +{ + return bar (5); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105163.c b/gcc/testsuite/gcc.dg/torture/pr105163.c new file mode 100644 index 0000000..23e0410 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105163.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target nonlocal_goto } */ + +#include <setjmp.h> + +extern int bar (unsigned int *); +extern jmp_buf *baz (void); +struct C { int c1; }; +void foo (struct C *x, int *z, int e) +{ + unsigned int d = 0; + long f; + setjmp (*baz()); + f = 1 + ~d; + d = 8; + if ((!0) && !e && bar(z)) *z = 1 + f; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105166.c b/gcc/testsuite/gcc.dg/torture/pr105166.c new file mode 100644 index 0000000..60e8b73 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105166.c @@ -0,0 +1,9 @@ +/* { dg-do compile } */ + +int bar (foo, a) + int (**foo) (); + int a; +{ + (foo)[1] = bar; + foo[1] (1); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105185.c b/gcc/testsuite/gcc.dg/torture/pr105185.c new file mode 100644 index 0000000..6ab3236 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105185.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +int foo (fmt) +char* fmt; +{ + return (__builtin_strchr (fmt, '*') != 0 + || __builtin_strchr (fmt, 'n') != 0); +} +void bar () +{ + if (foo ()) + __builtin_abort (); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105198.c b/gcc/testsuite/gcc.dg/torture/pr105198.c new file mode 100644 index 0000000..91f92af --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105198.c @@ -0,0 +1,26 @@ +/* { dg-do run } */ +/* { dg-additional-options "-fno-tree-pre -fpredictive-commoning" } */ + +static __attribute__ ((noipa)) void +next_set(int *x, int n, int k) +{ + int j = k - 1; + int tmp = x[j]++; + while (j > 0) + { + if (x[j] < n - (k - 1 -j)) + break; + j--; + x[j]++; + tmp = x[j]; + } + if (tmp != 2 || j != 1 || x[0] != 0 || x[1] != 2 || x[2] != 5) + __builtin_abort (); +} + +int main() +{ + int x[3] = {0, 1, 4}; + next_set(x, 5, 3); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105231.c b/gcc/testsuite/gcc.dg/torture/pr105231.c new file mode 100644 index 0000000..00121fd --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105231.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target dfp } */ +/* { dg-additional-options "-fsanitize-coverage=trace-pc -fnon-call-exceptions --param=max-cse-insns=1 -frounding-math" } */ +/* { dg-additional-options "-mstack-arg-probe" { target x86_64-*-* i?86-*-* } } */ + +void baz (int *); +void bar (double, double, _Decimal64); + +void +foo (void) +{ + int s __attribute__((cleanup (baz))); + bar (0xfffffffffffffffe, 0xebf3fff2fbebaf7f, 0xffffffffffffff); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105337.c b/gcc/testsuite/gcc.dg/torture/pr105337.c new file mode 100644 index 0000000..4a0bdf03 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105337.c @@ -0,0 +1,31 @@ +/* { dg-do run } */ + +__attribute__((noipa)) void +bar (int x) +{ + (void) x; +} + +int a; + +int +foo (void) +{ + int b, c; + for (b = 0; b < 3; b++) + { + if (!a) + break; + c--; + bar (c); + } + return b; +} + +int +main () +{ + if (foo ()) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105484.c b/gcc/testsuite/gcc.dg/torture/pr105484.c new file mode 100644 index 0000000..f2a5eb8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105484.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-fnon-call-exceptions -fno-tree-dce -fno-tree-forwprop" } */ +/* { dg-additional-options "-march=cannonlake" { target x86_64-*-* i?86-*-* } } */ + +typedef int __attribute__((__vector_size__ (16))) V; + +void bar (int i); + +void +foo (int i) +{ + V v; + __builtin_mul_overflow (7, i, &v[i]); + bar ((V){}[3]); +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105537.c b/gcc/testsuite/gcc.dg/torture/pr105537.c new file mode 100644 index 0000000..2e4825c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105537.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ffast-math -fsignaling-nans -fvar-tracking-assignments -fno-move-loop-stores -ftree-loop-distribution" } */ + +int n; + +double +ext1 (int); + +void +ext2 (double); + +int +sum (int v1, int v2) +{ + return v1 + v2; +} + +void +bar (void) +{ + ext2 (ext1 (n)); +} + +__attribute__ ((optimize ("-O3"))) void +foo (int *x) +{ + static int i; + + bar (); + for (i = 0; i != 2; i = sum (i, 1)) + n = *x = 0; +} + +/* { dg-message "other options take precedence" "" { target *-*-* } 0 } */ diff --git a/gcc/testsuite/gcc.dg/torture/pr105598.c b/gcc/testsuite/gcc.dg/torture/pr105598.c new file mode 100644 index 0000000..0a4ea3b --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105598.c @@ -0,0 +1,32 @@ +/* { dg-do run } */ + +typedef struct { unsigned int num; } info_t; +typedef struct { unsigned int flag, type; } block_t; +info_t info; +block_t blocks[] = { {2,0}, {3,0}, {1,0}, {1,0} }; + +static block_t * +f (info_t *i, block_t *b) +{ + while (1) { + unsigned int is_last = b->flag & 0x01; + i->num++; + if (b->flag & 0x02) { + if (b->type != 0x1) b->type = b->type; + b = f (i, b+1); + } + if (is_last) + break; + b++; + } + return b; +} + +int +main () +{ + f(&info, &blocks[0]); + if (info.num != 4) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105665.c b/gcc/testsuite/gcc.dg/torture/pr105665.c new file mode 100644 index 0000000..34cfc65 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105665.c @@ -0,0 +1,20 @@ +/* { dg-do run } */ + +int a, b, c[1], d[2], *e = c; +int main() { + int f = 0; + for (; b < 2; b++) { + int g; + if (f) + g++, b = 40; + a = d[b * b]; + for (f = 0; f < 3; f++) { + if (e) + break; + g--; + if (a) + a = g; + } + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr105786.c b/gcc/testsuite/gcc.dg/torture/pr105786.c new file mode 100644 index 0000000..64aacf7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr105786.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +void sink(const char*); +static const char *a; +int main() +{ + const char *b = a; + for (int i = 0; i < 2; ++i) + while (*b++) + ; + sink(b); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106070.c b/gcc/testsuite/gcc.dg/torture/pr106070.c new file mode 100644 index 0000000..f031516 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106070.c @@ -0,0 +1,22 @@ +/* { dg-do run } */ + +unsigned int a = 1; +int b = -1; +int c = 4; +unsigned long long d; + +void __attribute__((noipa)) +test (void) +{ + for (int i = 0; i < c; i += 2) + d = a != (int) b ? (unsigned long long) b : (unsigned long long) a; +} + +int +main () +{ + test (); + if (d != -1ULL) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106112.c b/gcc/testsuite/gcc.dg/torture/pr106112.c new file mode 100644 index 0000000..bd7f63c --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106112.c @@ -0,0 +1,16 @@ +/* { dg-do run } */ + +__INT32_TYPE__ a = 5, b, c, d; +__UINT64_TYPE__ e = 20862985922; +int main() +{ + __UINT32_TYPE__ f = 4294967292; + e = e | f; + c = -1 % ((~f ^ 4294967292) - (e - d)); + b = ~-~e % ~-d; + if (b) + a = 0; + if (a < 1) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106182.c b/gcc/testsuite/gcc.dg/torture/pr106182.c new file mode 100644 index 0000000..6b5c249 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106182.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-funswitch-loops" } */ + +short var_32; +int test_var_0; +unsigned char test_var_6; +char test_var_13; +void test(int var_2) +{ + for (;;) + for (short i_7; i_7 < test_var_13; i_7 += 1) + for (; test_var_0;) { + for (; var_2;) + var_32 = 0; + for (char i_19; i_19 < test_var_6 + 135; i_19 += 200) + ; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106196.c b/gcc/testsuite/gcc.dg/torture/pr106196.c new file mode 100644 index 0000000..56723de --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106196.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-ftree-vectorize -fno-vect-cost-model" } */ + +extern char a[]; +char *b; +void e() { + char *d; + int c; + d = a; + for (; c; c++) { + d[2] = d[1] = d[0] = b[c]; + d += 3; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106414-1.c b/gcc/testsuite/gcc.dg/torture/pr106414-1.c new file mode 100644 index 0000000..0974716 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106414-1.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ + +int a, c, e; +const int b = 1; +char d; +int main() { + a = ~(e || 0) ^ b & ~d; + d = ~(a | ~2); + if (d) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106414-2.c b/gcc/testsuite/gcc.dg/torture/pr106414-2.c new file mode 100644 index 0000000..bed6a40 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106414-2.c @@ -0,0 +1,12 @@ +/* { dg-do run } */ + +int a, b, c, d; +unsigned e; +int main() { + c = e = -((a && 1) ^ ~(b || 0)); + if (e < -1) + d = c; + if (!d) + __builtin_abort(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/torture/pr106971.c b/gcc/testsuite/gcc.dg/torture/pr106971.c new file mode 100644 index 0000000..33f2105 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr106971.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +void a() +{ + int b; + int c; + int d = (__INTPTR_TYPE__)a; + _Complex float *e = (_Complex float *)a; + for (;;) { + (*e += d) / b ?: 0; + } +} diff --git a/gcc/testsuite/gcc.dg/torture/pr89595.c b/gcc/testsuite/gcc.dg/torture/pr89595.c index f45dc98..3a4bed9 100644 --- a/gcc/testsuite/gcc.dg/torture/pr89595.c +++ b/gcc/testsuite/gcc.dg/torture/pr89595.c @@ -5,6 +5,7 @@ int __attribute__((noipa)) __GIMPLE(ssa,startwith("dom")) bar(int cond, int val) { int i; + _Bool _7; __BB(3): if (0 != 0) @@ -20,7 +21,8 @@ __BB(2): __BB(4): i_6 = val_2(D); - i_1 = val_2(D) > 0 ? i_6 : 0; + _7 = val_2(D) > 0; + i_1 = _7 ? i_6 : 0; goto __BB5; __BB(5): diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c index 5ec0558..552ca14 100644 --- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c +++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c @@ -9,7 +9,7 @@ /* arm_hf_eabi: Variadic funcs use Base AAPCS. Normal funcs use VFP variant. avr: Variadic funcs don't pass arguments in registers, while normal funcs do. */ -/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { csky*-*-* avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* } } } */ +/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { csky*-*-* avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* loongarch*-*-* } } } */ /* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* } { v850*-*-* } } */ /* { dg-require-effective-target untyped_assembly } */ diff --git a/gcc/testsuite/gcc.dg/torture/tls/pr104777.c b/gcc/testsuite/gcc.dg/torture/tls/pr104777.c new file mode 100644 index 0000000..abaf597 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/tls/pr104777.c @@ -0,0 +1,30 @@ +/* PR rtl-optimization/104777 */ +/* { dg-do compile } */ +/* { dg-require-effective-target tls } */ + +int savestate_r; +int savestate_ssb; +extern void abort(); +__thread int loop; +void f (void) +{ + int savestate_r0_5; + int savestate_r1_6; + + __asm__("" : "=m" (savestate_ssb), "=r" (savestate_r)); + savestate_r0_5 = savestate_r; + if (savestate_r0_5 == 0) + { + __asm__ __volatile__("" : : "m" (loop)); + abort (); + } + + __asm__("" : "=m" (savestate_ssb), "=r" (savestate_r)); + savestate_r1_6 = savestate_r; + if (savestate_r1_6 != 0) + return; + + __asm__ __volatile__("" : : "m" (loop)); + abort (); + +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c new file mode 100644 index 0000000..87a94f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-access-path-13.c @@ -0,0 +1,36 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-fre1" } */ + +struct inn +{ + int val; +}; + +struct biggerstruct +{ + int a, b; +}; + +union foo +{ + struct inn inn; + struct biggerstruct baz; +} *fooptr; + +struct bar +{ + union foo foo; + int val2; +} *barptr; + +int +test () +{ + union foo foo; + foo.inn.val = 0; + barptr->val2 = 123; + *fooptr = foo; + return barptr->val2; +} + +/* { dg-final { scan-tree-dump-times "return 123" 1 "fre1"} } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/divide-7.c b/gcc/testsuite/gcc.dg/tree-ssa/divide-7.c index c605515..c577ea3 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/divide-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/divide-7.c @@ -6,4 +6,5 @@ int f(int x) { } /* { dg-final { scan-tree-dump-not "1 / x_\[0-9]\+\\\(D\\\);" "optimized" } } */ -/* { dg-final { scan-tree-dump " <= 2 \\? x_\[0-9]\+\\\(D\\\) : 0;" "optimized" } } */ +/* { dg-final { scan-tree-dump " <= 2;" "optimized" } } */ +/* { dg-final { scan-tree-dump " \\? x_\[0-9]\+\\\(D\\\) : 0;" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp10.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp10.c new file mode 100644 index 0000000..6ca00e4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp10.c @@ -0,0 +1,30 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-evrp" }*/ + +typedef __INT32_TYPE__ int32_t; + +int32_t and(int32_t x, int32_t y) +{ + int32_t tx = x >> 24; + int32_t ty = y >> 24; + int32_t t = tx & ty; + return t; +} + +int32_t ior(int32_t x, int32_t y) +{ + int32_t tx = x >> 24; + int32_t ty = y >> 24; + int32_t t = tx | ty; + return t; +} + +int32_t xor(int32_t x, int32_t y) +{ + int32_t tx = x >> 24; + int32_t ty = y >> 24; + int32_t t = tx ^ ty; + return t; +} + +/* { dg-final { scan-tree-dump-times "\\\[-128, 127\\\]" 9 "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c index e3f4531..895109f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp4.c @@ -17,4 +17,4 @@ int bar (struct st *s) foo (&s->a); } -/* { dg-final { scan-tree-dump "\\\[1B, \\+INF\\\]" "evrp" } } */ +/* { dg-final { scan-tree-dump "\\\[1, \\+INF\\\]" "evrp" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c index dd1c0ac..6916843 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11.c @@ -34,4 +34,4 @@ int main () } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* msp430-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* msp430-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c index e2fb362..6326bf7 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-11a.c @@ -38,4 +38,4 @@ int main () } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c index 42171a2..b84f318 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-2.c @@ -36,5 +36,5 @@ int main () return 0; } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c index 60ec270..18fe1aa 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-25.c @@ -54,5 +54,5 @@ int main (void) return main_1 (n + 2, (int *) &n); } -/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { ! { avr-*-* msp430-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* msp430-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { target { ! { avr-*-* msp430-*-* pru-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* msp430-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c index 6f3c2b7..7106961 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-26.c @@ -29,7 +29,7 @@ int main () } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ /* IBM Z does not require special alignment for vectorization. */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* s390*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! { avr-*-* s390*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* pru-*-* s390*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! { avr-*-* pru-*-* s390*-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c index 7b26bbd..c5f1b5a 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-28.c @@ -37,7 +37,7 @@ int main (void) } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ /* IBM Z does not require special alignment for vectorization. */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* s390*-*-* } } } } } */ -/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! { avr-*-* s390*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* pru-*-* s390*-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Alignment of access forced using peeling" 1 "vect" { target { ! { avr-*-* pru-*-* s390*-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c index 378dd0b..62d2b50 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/gen-vect-32.c @@ -33,5 +33,5 @@ int main () } -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! avr-*-* } } } } */ -/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! avr-*-* } } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ +/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" { target { ! { avr-*-* pru-*-* } } } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-11.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-11.c new file mode 100644 index 0000000..3dffee04 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-11.c @@ -0,0 +1,28 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */ + +struct f { + int len; + int arr[4]; +}; + +int +test (struct f const *const f) +{ + if (f->arr[3] == 1) { + return 12; + } else if (f->arr[3] == 2) { + return 27; + } else if (f->arr[3] == 3) { + return 38; + } else if (f->arr[3] == 4) { + return 18; + } else if (f->arr[3] == 5) { + return 58; + } else if (f->arr[3] == 6) { + return 68; + } + return 0; +} + +/* { dg-final { scan-tree-dump "Canonical GIMPLE case clusters: 1 2 3 4 5 6" "iftoswitch" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c index 75f7b8f..2403a24 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-24.c @@ -20,5 +20,6 @@ void foo () } } -/* { dg-final { scan-tree-dump "generated memcpy" "ldist" } } */ -/* { dg-final { scan-tree-dump "generated memset zero" "ldist" } } */ +/* The cost modeling does not consider WAR as beneficial to split. */ +/* { dg-final { scan-tree-dump "generated memcpy" "ldist" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump "generated memset zero" "ldist" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-36.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-36.c index 07393f0..6d56006 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-36.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-36.c @@ -25,4 +25,5 @@ foo (struct st * restrict p) } } -/* { dg-final { scan-tree-dump-times "Loop nest . distributed: split to 0 loops and 3 library" 1 "ldist" } } */ +/* The cost modeling doesn't consider splitting a WAR re-use profitable. */ +/* { dg-final { scan-tree-dump-times "Loop nest . distributed: split to 1 loops and 1 library" 1 "ldist" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-6.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-6.c index 6044760..f9eb5c6 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/loop-6.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-6.c @@ -19,7 +19,7 @@ void xxx(void) /* Loop should be unswitched. */ -/* { dg-final { scan-tree-dump-times "Unswitching loop" 1 "unswitch" } } */ +/* { dg-final { scan-tree-dump-times "unswitching loop" 1 "unswitch" } } */ /* In effect there should be exactly three conditional jumps in the final program. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr104639-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr104639-1.c new file mode 100644 index 0000000..183fa37 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr104639-1.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/104639 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -g -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "PHI <" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "i_\[0-9]*\\\(D\\\) != 0;" 1 "optimized" } } */ + +_Bool +foo (int i) +{ + while (i == 4) + i += 2; + return i; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr104639-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr104639-2.c new file mode 100644 index 0000000..e251147 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr104639-2.c @@ -0,0 +1,54 @@ +/* PR tree-optimization/104639 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-tree-pre -g -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "PHI <" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "x_\[0-9]*\\\(D\\\) != 42;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "y_\[0-9]*\\\(D\\\) > 6;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "z_\[0-9]*\\\(D\\\) > 9;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "u_\[0-9]*\\\(D\\\) <= 7;" 1 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "v_\[0-9]*\\\(D\\\) <= 42;" 1 "optimized" } } */ + +int +f1 (int x) +{ + if (x == 4) + x = 6; + int xd = x; + return x != 42; +} + +int +f2 (int y) +{ + if (y == 4) + y = 6; + int yd = y; + return y > 6; +} + +int +f3 (int z) +{ + if (z == 4) + z = 6; + int zd = z; + return z >= 10; +} + +int +f4 (int u) +{ + if (u == 4) + u = 6; + int ud = u; + return u < 8; +} + +int +f5 (int v) +{ + if (v == 4) + v = 6; + int vd = v; + return v <= 42; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr104645.c b/gcc/testsuite/gcc.dg/tree-ssa/pr104645.c new file mode 100644 index 0000000..83c1dd4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr104645.c @@ -0,0 +1,28 @@ +/* PR tree-optimization/104645 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not " = PHI <" "optimized" } } */ + +int +foo (unsigned i) +{ + return i ? i % 2 : 0; +} + +int +bar (unsigned i) +{ + int b = 0; + if (i) + { + unsigned a = i & 1; + b = a; + } + return b; +} + +int +baz (unsigned i) +{ + return i ? i + 4 : 4; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105777.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105777.c new file mode 100644 index 0000000..418708b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105777.c @@ -0,0 +1,68 @@ +/* PR middle-end/105777 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "\.MUL_OVERFLOW " "optimized" } } */ +/* { dg-final { scan-tree-dump " \\+ 61356675;" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 122713350" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " \\+ 263524915338707880" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " > 527049830677415760" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " \\+ 51130563" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 102261126" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " \\+ 219604096115589900" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " > 439208192231179800" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " \\+ 55063683;" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 110127366" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " \\+ 236496718893712200" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " > 472993437787424400" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " \\+ 46684427" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 93368854" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " \\+ 200508087757712517" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " > 401016175515425034" "optimized" { target lp64 } } } */ + +__attribute__((noipa)) int +foo (int x) +{ + return __builtin_mul_overflow_p (x, 35, 0); +} + +__attribute__((noipa)) int +bar (long int x) +{ + return __builtin_mul_overflow_p (x, 35L, 0L); +} + +__attribute__((noipa)) int +baz (int x) +{ + return __builtin_mul_overflow_p (42, x, 0); +} + +__attribute__((noipa)) int +qux (long int x) +{ + return __builtin_mul_overflow_p (42, x, 0L); +} + +__attribute__((noipa)) int +corge (int x) +{ + return __builtin_mul_overflow_p (x, -39, 0); +} + +__attribute__((noipa)) int +garply (long int x) +{ + return __builtin_mul_overflow_p (x, -39L, 0L); +} + +__attribute__((noipa)) int +grault (int x) +{ + return __builtin_mul_overflow_p (-46, x, 0); +} + +__attribute__((noipa)) int +waldo (long int x) +{ + return __builtin_mul_overflow_p (-46, x, 0L); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c new file mode 100644 index 0000000..77bcb4a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105860.c @@ -0,0 +1,63 @@ +/* { dg-do run } */ +/* { dg-options "-O1" } */ + +struct S1 { + unsigned int _0; + unsigned int _1; +} ; +struct S2 { + struct S1 _s1; + unsigned long _x2; +} ; + +struct ufld_type1 { + unsigned int _u1t; + struct S2 _s2; +} ; + +struct ufld_type2 { + unsigned int _u2t; + struct S1 _s1; +} ; +struct parm_type { + union { + struct ufld_type1 var_1; + struct ufld_type2 var_2; + } U; +}; + +struct parm_type bad_function( struct parm_type arg0 ) +{ + struct parm_type rv; + struct S2 var4; + switch( arg0.U.var_2._u2t ) { + case 4294967041: + var4._s1 = arg0.U.var_1._s2._s1; + rv.U.var_1._u1t = 4294967041; + rv.U.var_1._s2 = var4; + break; + case 4294967043: + rv.U.var_2._u2t = 4294967043; + rv.U.var_2._s1 = arg0.U.var_2._s1; + break; + default: + break; + } + return rv; +} + +int main() { + struct parm_type val; + struct parm_type out; + val.U.var_2._u2t = 4294967043; + val.U.var_2._s1._0 = 0x01010101; + val.U.var_2._s1._1 = 0x02020202; + out = bad_function(val); + if (val.U.var_2._u2t != 4294967043) + __builtin_abort (); + if (out.U.var_2._s1._0 != 0x01010101) + __builtin_abort (); + if (val.U.var_2._s1._1 != 0x02020202 ) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr105983.c b/gcc/testsuite/gcc.dg/tree-ssa/pr105983.c new file mode 100644 index 0000000..46418c2 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr105983.c @@ -0,0 +1,17 @@ +/* PR tree-optimization/105983 */ +/* { dg-do compile } */ +/* { dg-options "-O2 --param=logical-op-non-short-circuit=1 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not " != 0;" "optimized" } } */ +/* { dg-final { scan-tree-dump-not " & " "optimized" } } */ + +int +foo (unsigned a, unsigned b) +{ + return b != 0 && a >= b; +} + +int +bar (unsigned a, unsigned b) +{ + return b != 0 & a >= b; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr106126.c b/gcc/testsuite/gcc.dg/tree-ssa/pr106126.c new file mode 100644 index 0000000..2f0fd44 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr106126.c @@ -0,0 +1,12 @@ +/* PR tree-optimization/106126 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +char *var_1; +void pool_conda_matchspec() { + for (; var_1 && *var_1 && + *var_1 != '<' && *var_1 != '>' && + *var_1 != '!' && *var_1 != '~';) + if (*var_1 >= 'A' && *var_1 <= 'Z') + *var_1 += 'A'; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr30314.c b/gcc/testsuite/gcc.dg/tree-ssa/pr30314.c new file mode 100644 index 0000000..10b0b85 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr30314.c @@ -0,0 +1,32 @@ +/* PR middle-end/30314 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "\.MUL_OVERFLOW " "optimized" } } */ +/* { dg-final { scan-tree-dump " > 122713351" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 527049830677415760" "optimized" { target lp64 } } } */ +/* { dg-final { scan-tree-dump " > 102261126" "optimized" { target int32 } } } */ +/* { dg-final { scan-tree-dump " > 439208192231179800" "optimized" { target lp64 } } } */ + +__attribute__((noipa)) int +foo (unsigned int x) +{ + return __builtin_mul_overflow_p (x, 35U, 0U); +} + +__attribute__((noipa)) int +bar (unsigned long int x) +{ + return __builtin_mul_overflow_p (x, 35UL, 0UL); +} + +__attribute__((noipa)) int +baz (unsigned int x) +{ + return __builtin_mul_overflow_p (42, x, 0U); +} + +__attribute__((noipa)) int +qux (unsigned long int x) +{ + return __builtin_mul_overflow_p (42, x, 0UL); +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c index f5af7a1..d412567 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_1.c @@ -38,7 +38,7 @@ int main () } /* Scan for c = 972195717) >> [0, 1] in function foo. */ -/* { dg-final { scan-tree-dump-times "486097858 : 972195717" 1 "vrp1" } } */ +/* { dg-final { scan-tree-dump-times "972195717 : 486097858" 1 "vrp1" } } */ /* Previously we were checking for two ?: with constant PHI arguments, but now we collapse them into one. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c index bc2126f..38cf792 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr61839_3.c @@ -1,6 +1,6 @@ /* PR tree-optimization/61839. */ /* { dg-do run } */ -/* { dg-options "-O2 -fdump-tree-vrp -fdump-tree-optimized -fdisable-tree-ethread -fdisable-tree-threadfull1" } */ +/* { dg-options "-O2 -fdump-tree-optimized -fdisable-tree-ethread -fdisable-tree-threadfull1" } */ __attribute__ ((noinline)) int foo (int a, unsigned b) @@ -21,6 +21,4 @@ int main () foo (-1, b); } -/* Scan for c [12, 13] << 8 in function foo. */ -/* { dg-final { scan-tree-dump-times "3072 : 3328" 1 "vrp1" } } */ /* { dg-final { scan-tree-dump-times "3072" 0 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr65855-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr65855-2.c new file mode 100644 index 0000000..d44ef51 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr65855-2.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-sccp" } */ + +int square(int x) { + int result = 0; + for (int i = 0; i < x; ++i) + result += x; + return result; +} + +/* { dg-final { scan-tree-dump " with expr: x_\[0-9\]\\(D\\) \\* x_\[0-9\]\\(D\\)" "sccp" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c new file mode 100644 index 0000000..2a6f4f5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-1.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +extern char str[]; + +unsigned int foo() +{ + __builtin_memset(str,'x',5); + str[5] = 0; + return __builtin_strlen (str); +} + +/* { dg-final { scan-tree-dump-not "strlen" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c new file mode 100644 index 0000000..cc27504 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr83907-2.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ + +extern char str[]; + +unsigned int foo() +{ + __builtin_memset(str,'x',5); + str[5] = 0; + str[6] = 'z'; + return __builtin_strlen (str); +} + +/* { dg-final { scan-tree-dump-not "strlen" "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c new file mode 100644 index 0000000..030f3bd --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr99578-1.c @@ -0,0 +1,22 @@ +/* PR middle-end/99578 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-optimized" } */ +/* { dg-final { scan-tree-dump-not "&MEM" "optimized" } } */ +/* { dg-final { scan-tree-dump-times "PHI <-?1\\\(\[0-9\]+\\\), -?1\\\(\[0-9\]+\\\)>" 2 "optimized" } } */ + +struct S { int a, b[4]; }; +struct T { int a, b[8192], c[4]; }; + +int +foo (struct S *p) +{ + if (p) return -1; + return p->b == (void *)4; +} + +int +bar (struct T *p) +{ + if (p) return -1; + return p->c == (void *)32772; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c index 4a27ede..33e34fa 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-39.c @@ -6,7 +6,7 @@ *PINDEX: C1 + (C2 * C3) + C4 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-slsr-details" } */ +/* { dg-options "-O2 -fno-tree-vectorize -fdump-tree-slsr-details" } */ typedef int arr_2[50][50]; diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c index fae5bde..ede3274 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-branch-1.c @@ -19,10 +19,9 @@ try_combine (rtx i1, rtx newpat) else if (i1 && foo ()); } -/* There should be four tests against i1. One from the hash table - dumps, one from the EVRP analyzer one from EVRP evaluation and one +/* There should be 3 tests against i1. Two from DOM machinery and one in the code itself. */ -/* { dg-final { scan-tree-dump-times "if .i1_" 4 "dom2"} } */ +/* { dg-final { scan-tree-dump-times "if .i1_" 3 "dom2"} } */ /* There should be no actual jump threads realized by DOM. The legitimize jump threads are handled in VRP and those discovered diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c index b64e71d..aa06db5 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c @@ -11,7 +11,7 @@ to change decisions in switch expansion which in turn can expose new jump threading opportunities. Skip the later tests on aarch64. */ /* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Jumps threaded: 7" "thread2" { target { ! aarch64*-*-* } } } } */ +/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" { target { ! aarch64*-*-* } } } } */ /* { dg-final { scan-tree-dump "Jumps threaded: 18" "thread2" { target { aarch64*-*-* } } } } */ enum STATE { diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-44.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-44.c new file mode 100644 index 0000000..aaec41d --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-44.c @@ -0,0 +1,19 @@ +/* { dg-do link } */ +/* { dg-options "-O -fdump-tree-dse1-details" } */ + +extern void foo(void); +int a, b; +static int c; +int main() +{ + if (c) + foo (); + int *g = &c; + int **h = &g; + int ***h1 = &h; + if (a) + while (b) + b = 0; +} + +/* { dg-final { scan-tree-dump "Deleted dead store: g = &c;" "dse1" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-45.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-45.c new file mode 100644 index 0000000..fd92d7b --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-45.c @@ -0,0 +1,24 @@ +/* { dg-do link } */ +/* { dg-options "-O" } */ + +extern void foo(void); +int a, b; +static int c; +static void f() { + while (a) + for (; b; b--) + ; +} +void i() { + if (c) + foo(); + int *g = &c; + { + int **h[1] = {&g}; + f(); + } +} +int main() { + i(); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c index 6b6255b..224dd4f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c @@ -5,7 +5,7 @@ When the condition is true, we distribute "(int) (a + b)" as "(int) a + (int) b", otherwise we keep the original. */ -/* { dg-do compile { target { ! mips64 } } } */ +/* { dg-do compile { target { ! mips64 } && { ! loongarch64 } } } */ /* { dg-options "-O -fno-tree-forwprop -fno-tree-ccp -fwrapv -fdump-tree-fre1-details" } */ /* From PR14844. */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-99.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-99.c new file mode 100644 index 0000000..101d0d6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-99.c @@ -0,0 +1,27 @@ +/* { dg-do compile } */ +/* Disable FRE1 because that for the sake of __builtin_object_size + will not consider the equality but still valueize 'i', defeating + the purpose of the check. */ +/* { dg-options "-O -fdump-tree-fre3 -fdisable-tree-fre1" } */ + +struct S { int a[4]; }; + +int i; +int bar (struct S *p) +{ + char *q = (char *)p + 4; + i = 1; + int *r = &((struct S *)p)->a[i]; + return q == (char *)r; +} +int baz (struct S *p) +{ + i = 1; + int *r = &((struct S *)p)->a[i]; + char *q = (char *)p + 4; + return q == (char *)r; +} + +/* Verify FRE can handle valueizing &p->a[i] and value-numbering it + equal to a POINTER_PLUS_EXPR. */ +/* { dg-final { scan-tree-dump-times "return 1;" 2 "fre3" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c index 016ff22..c483951 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-lim-12.c @@ -23,4 +23,4 @@ void bar (int x, int z) } } -/* { dg-final { scan-tree-dump-times "!= 0 ? " 2 "lim2" } } */ +/* { dg-final { scan-tree-dump-times " = _\[0-9\]+ ? " 2 "lim2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-19.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-19.c new file mode 100644 index 0000000..e98d13f --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-19.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-sink1-details -fdump-tree-cddce2-details" } */ + +static int b=4; +int c; + +int +main() +{ + int e[5] = {1,1,1,1,1}; + for (; b >= 0; b--) { + c = e[b]; + } + return 0; +} + +/* We should sink e[b] out of the loop which is possible after + applying store motion to c and b. */ +/* { dg-final { scan-tree-dump "Sinking # VUSE" "sink1" } } */ +/* And remove the loop after final value replacement. */ +/* { dg-final { scan-tree-dump "fix_loop_structure: removing loop" "cddce2" } } */ diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c index 91015da..c28ca47 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp24.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-evrp-details -fdump-tree-optimized -fno-tree-ccp" } */ +/* { dg-options "-O2 -fno-tree-forwprop -fdump-tree-evrp-details -fdump-tree-optimized -fno-tree-ccp --param logical-op-non-short-circuit=1" } */ struct rtx_def; @@ -89,5 +89,5 @@ L7: boolean operation. */ /* { dg-final { scan-tree-dump-times "Simplified relational" 2 "evrp" } } */ -/* { dg-final { scan-tree-dump-times "if " 4 "optimized" } } */ +/* { dg-final { scan-tree-dump-times "if " 3 "optimized" } } */ diff --git a/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c b/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c new file mode 100644 index 0000000..0159f5b --- /dev/null +++ b/gcc/testsuite/gcc.dg/ubsan/object-size-dyn.c @@ -0,0 +1,45 @@ +/* { dg-do run } */ +/* { dg-skip-if "" { *-*-* } { "*" } { "-O2" } } */ +/* { dg-options "-fsanitize=undefined" } */ +#include <stdio.h> + +int +__attribute__ ((noinline)) +dyn (int size, int i) +{ + __builtin_printf ("dyn\n"); + fflush (stdout); + int *alloc = __builtin_calloc (size, sizeof (int)); + int ret = alloc[i]; + __builtin_free (alloc); + return ret; +} + +int +__attribute__ ((noinline)) +off (int size, int i, int ret) +{ + char *mem = __builtin_alloca (size); + mem += size - 1; + + return (int) mem[i] & ret; +} + +int +main (void) +{ + int ret = dyn (2, 2); + + ret |= off (4, 4, 0); + + return ret; +} + +/* { dg-output "load of address \[^\n\r]* with insufficient space for an object of type 'int'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*load of address \[^\n\r]* with insufficient space for an object of type 'char'\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*note: pointer points here\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\[^\n\r]*(\n|\r\n|\r)" } */ +/* { dg-output "\[^\n\r]*\\^" } */ diff --git a/gcc/testsuite/gcc.dg/uninit-40.c b/gcc/testsuite/gcc.dg/uninit-40.c index 8708079..567707a 100644 --- a/gcc/testsuite/gcc.dg/uninit-40.c +++ b/gcc/testsuite/gcc.dg/uninit-40.c @@ -44,7 +44,7 @@ foo (int *q) /* memcpy folding is too target dependent to test it everywhere. */ V u[2], v[2]; u[0][0][0] = 1; - __builtin_memcpy (&v[1], &u[1], sizeof (V)); /* { dg-warning "'\\*\\(\(long \)?long unsigned int \\*\\)\\(&u\\\[1\\\]\\\[0\\\]\\\[0\\\]\\)' is used uninitialized" "" { target i?86-*-* x86_64-*-* } } */ + __builtin_memcpy (&v[1], &u[1], sizeof (V)); /* { dg-warning "'u' is used uninitialized" "" { target i?86-*-* x86_64-*-* } } */ baz (&v[1]); #endif } diff --git a/gcc/testsuite/gcc.dg/uninit-pr105109.c b/gcc/testsuite/gcc.dg/uninit-pr105109.c new file mode 100644 index 0000000..001003ca --- /dev/null +++ b/gcc/testsuite/gcc.dg/uninit-pr105109.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-options "-O -Wuninitialized" } */ + +static void foo(int dim,float _Complex f0[]) +{ + int d; + f0[0] -= 3.14; /* { dg-bogus "uninitialized" } */ + for (d = 0; d < dim; ++d) f0[0] += 3.14; +} +void bar(int dim, const float _Complex u_t[], float _Complex f0[]) +{ + float _Complex exp[1] = {0.}; + foo(dim, exp); + f0[0] = u_t[0] - exp[0]; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr101668.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101668.c new file mode 100644 index 0000000..eb44ad7 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr101668.c @@ -0,0 +1,59 @@ +/* { dg-do run } */ +/* { dg-additional-options "-w -Wno-psabi" } */ + +#include "tree-vect.h" + +typedef int v4si __attribute__((vector_size(16))); +typedef int v8si __attribute__((vector_size(32))); + +void __attribute__((noipa)) test_lo (v4si *dst, v8si src) +{ + (*dst)[0] = src[0]; + (*dst)[1] = src[1]; + (*dst)[2] = src[2]; + (*dst)[3] = src[3]; +} + +void __attribute__((noipa)) test_hi (v4si *dst, v8si src) +{ + (*dst)[0] = src[4]; + (*dst)[1] = src[5]; + (*dst)[2] = src[6]; + (*dst)[3] = src[7]; +} + +void __attribute__((noipa)) test_even (v4si *dst, v8si src) +{ + (*dst)[0] = src[0]; + (*dst)[1] = src[2]; + (*dst)[2] = src[4]; + (*dst)[3] = src[6]; +} + +void __attribute__((noipa)) test_odd (v4si *dst, v8si src) +{ + (*dst)[0] = src[1]; + (*dst)[1] = src[3]; + (*dst)[2] = src[5]; + (*dst)[3] = src[7]; +} + +int main() +{ + check_vect (); + v8si v = (v8si) { 0, 1, 2, 3, 4, 5, 6, 7 }; + v4si dst; + test_lo (&dst, v); + if (dst[0] != 0 || dst[1] != 1 || dst[2] != 2 || dst[3] != 3) + abort (); + test_hi (&dst, v); + if (dst[0] != 4 || dst[1] != 5 || dst[2] != 6 || dst[3] != 7) + abort (); + test_even (&dst, v); + if (dst[0] != 0 || dst[1] != 2 || dst[2] != 4 || dst[3] != 6) + abort (); + test_odd (&dst, v); + if (dst[0] != 1 || dst[1] != 3 || dst[2] != 5 || dst[3] != 7) + abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c new file mode 100644 index 0000000..1045f31 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr104240.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_int } */ +/* { dg-require-effective-target vect_cond_mixed } */ + +void foo (int *c, float *x, float *y) +{ + c = __builtin_assume_aligned (c, __BIGGEST_ALIGNMENT__); + x = __builtin_assume_aligned (x, __BIGGEST_ALIGNMENT__); + y = __builtin_assume_aligned (y, __BIGGEST_ALIGNMENT__); + c[0] = x[0] < y[0]; + c[1] = y[1] > x[1]; + c[2] = x[2] < y[2]; + c[3] = x[3] < y[3]; +} + +/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c new file mode 100644 index 0000000..218d7cc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr106019.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ + +void f(double *p, long i) +{ + p[i+0] += 1; + p[i+1] += 1; +} +void g(double *p, long i) +{ + double *q = p + i; + q[0] += 1; + q[1] += 1; +} + +/* { dg-final { scan-tree-dump-not "can't determine dependence" slp2 } } */ diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c index 6b213d4..56c4bbf 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-additional-options "-fno-tree-loop-vectorize -fno-tree-dominator-opts" } */ /* { dg-require-effective-target lp64 } */ double p[1000]; diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c index 599f718..67ee809 100644 --- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c +++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c @@ -1,7 +1,11 @@ /* { dg-do compile } */ -/* { dg-additional-options "-fno-tree-loop-vectorize" } */ +/* { dg-additional-options "-fno-tree-loop-vectorize -fno-tree-dominator-opts" } */ /* { dg-require-effective-target lp64 } */ +/* A ranger based DOM causes many more SSA names to be exported, which + causes slp1 to vectorize more things. Disabling DOM to avoid + disturbing this test. */ + void f1 (double *p, double *q, unsigned int n) { diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-double.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-double.c index f935405..5cff373 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-double.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-double.c @@ -6,7 +6,7 @@ #define N 200 #include "complex-add-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 2 "vect" { target { vect_complex_add_double } } } } */ -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 2 "vect" { target { vect_complex_add_double } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_double } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "vect" { target { vect_complex_add_double } } } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "vect" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-float.c index 71f391d..312df88 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-float.c @@ -6,7 +6,7 @@ #define N 200 #include "complex-add-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 2 "vect" { target { vect_complex_add_float } } } } */ -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 2 "vect" { target { vect_complex_add_float } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_float } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "vect" { target { vect_complex_add_float } } } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "vect" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-half-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-half-float.c index e5b826f..c656a2f 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-half-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-half-float.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_half } */ /* { dg-require-effective-target float16 } */ /* { dg-add-options arm_v8_3a_fp16_complex_neon } */ @@ -6,5 +7,7 @@ #define N 200 #include "complex-add-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 2 "vect" { target { vect_complex_add_half } } } } */ -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 2 "vect" { target { vect_complex_add_half } } } } */ +/* Vectorization is failing for these cases. They should work but for now ignore. */ + +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "slp1" { xfail *-*-* } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "slp1" { xfail *-*-* } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-double.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-double.c index 5b70d83..9c8b99b 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-double.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-double.c @@ -6,8 +6,7 @@ #define N 200 #include "complex-add-pattern-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 4 "vect" { target { vect_complex_add_double } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "vect" { target { vect_complex_add_double } } } } */ /* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_double } } } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "vect" } } */ -/* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "slp1" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-float.c index 3ef0564..ca5f5b2 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-float.c @@ -6,8 +6,7 @@ #define N 200 #include "complex-add-pattern-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 4 "vect" { target { vect_complex_add_float } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "vect" { target { vect_complex_add_float } } } } */ /* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_float } } } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "vect" } } */ -/* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "slp1" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-half-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-half-float.c index 06a9216..c6617f5 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-half-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-add-pattern-half-float.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-require-effective-target vect_float } */ +/* { dg-require-effective-target vect_complex_add_half } */ /* { dg-require-effective-target float16 } */ /* { dg-add-options arm_v8_3a_fp16_complex_neon } */ @@ -7,10 +7,8 @@ #define N 200 #include "complex-add-pattern-template.c" -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 4 "vect" { target { vect_complex_add_half } } } } */ -/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_half } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT90" 1 "vect" { target { vect_complex_add_half } } } } */ +/* { dg-final { scan-tree-dump-times "stmt.*COMPLEX_ADD_ROT270" 1 "vect" { target { vect_complex_add_half } && ! target { arm*-*-* } } } } */ -/* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "slp1" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT270" "vect" } } */ -/* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "slp1" } } */ /* { dg-final { scan-tree-dump "Found COMPLEX_ADD_ROT90" "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mla-half-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mla-half-float.c index 34146f3..7beb6b8 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mla-half-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mla-half-float.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ /* { dg-add-options arm_v8_3a_fp16_complex_neon } */ +/* { dg-require-effective-target vect_complex_add_half } */ +/* { dg-require-effective-target float16 } */ #define TYPE _Float16 #define N 200 diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-double.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-double.c index 0982a2b..fc4cd61 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-double.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-double.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_double } */ /* { dg-add-options arm_v8_3a_complex_neon } */ #define TYPE double diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-float.c index a069533..a931ca6 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-float.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ #define TYPE float diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-half-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-half-float.c index 89ac54c..dd153e4 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-half-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mls-half-float.c @@ -1,4 +1,6 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_half } */ +/* { dg-require-effective-target float16 } */ /* { dg-add-options arm_v8_3a_fp16_complex_neon } */ #define TYPE _Float16 diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-double.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-double.c index 56a8ea4..b6b2152 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-double.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-double.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_double } */ /* { dg-add-options arm_v8_3a_complex_neon } */ #define TYPE double diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-float.c index 969416d..aa8efb4c 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-float.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ #define TYPE float diff --git a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-half-float.c b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-half-float.c index da1b921..5133162 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-half-float.c +++ b/gcc/testsuite/gcc.dg/vect/complex/fast-math-complex-mul-half-float.c @@ -1,4 +1,6 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_complex_add_half } */ +/* { dg-require-effective-target float16 } */ /* { dg-add-options arm_v8_3a_fp16_complex_neon } */ #define TYPE _Float16 diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-1.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-1.c index 46b9a55..ae16b89 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-1.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-1.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-2.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-2.c index ffe646e..aeee34d 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-2.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-2.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-3.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-3.c index 5f98aa2..210540b 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-3.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-3.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-4.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-4.c index 8828517..b4c3d9e 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-4.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-4.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-5.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-5.c index 6a2d549..34bec58 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-5.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-5.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-6.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-6.c index 71e66db..8da0d86 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-6.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-6.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-7.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-7.c index 536672f..bac9cc1 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-7.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-7.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-8.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-8.c index 07b4814..ce70292 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-8.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-8.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ float f[12][100]; diff --git a/gcc/testsuite/gcc.dg/vect/complex/pr102819-9.c b/gcc/testsuite/gcc.dg/vect/complex/pr102819-9.c index 7655852..a513821 100644 --- a/gcc/testsuite/gcc.dg/vect/complex/pr102819-9.c +++ b/gcc/testsuite/gcc.dg/vect/complex/pr102819-9.c @@ -1,4 +1,5 @@ /* { dg-do compile } */ +/* { dg-require-effective-target vect_float } */ /* { dg-add-options arm_v8_3a_complex_neon } */ #include <stdio.h> diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c index 72b4930..c57f065 100644 --- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c +++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-vect-31a.c @@ -46,5 +46,5 @@ int main (void) return main1 (); } -/* { dg-final { scan-tree-dump-times "not vectorized: unsupported unaligned store" 1 "vect" { target { ! vect_hw_misalign } } } } */ +/* { dg-final { scan-tree-dump-times "unsupported unaligned access" 1 "vect" { target { ! vect_hw_misalign } } } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 0 "vect" { target { ! vect_hw_misalign } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-1.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-1.c new file mode 100644 index 0000000..992a845 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-1.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-msse -fdump-tree-slp2-details" } */ + +struct S { unsigned long a, b; } s; + +void +foo (unsigned long *a, unsigned long *b) +{ + unsigned long a_ = *a; + unsigned long b_ = *b; + s.a = a_; + s.b = b_; +} + +/* { dg-final { scan-tree-dump "basic block part vectorized" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-2.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-2.c new file mode 100644 index 0000000..d060135 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-2.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-msse -mtune=generic -fdump-tree-slp2-details" } */ + +struct S { unsigned long a, b; } s; + +void +foo (unsigned long a, unsigned long b) +{ + s.a = a; + s.b = b; +} + +/* { dg-final { scan-tree-dump-not "basic block part vectorized" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-3.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-3.c new file mode 100644 index 0000000..999c490 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-3.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-msse -fdump-tree-slp2-details" } */ + +struct S { double a, b; } s; + +void +foo (double a, double b) +{ + s.a = a; + s.b = b; +} + +/* { dg-final { scan-tree-dump "basic block part vectorized" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-4.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-4.c new file mode 100644 index 0000000..cc471e1 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr104582-4.c @@ -0,0 +1,15 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-msse -fdump-tree-slp2-details" } */ + +struct S { unsigned long a, b; } s; + +void +foo (signed long *a, unsigned long *b) +{ + unsigned long a_ = *a; + unsigned long b_ = *b; + s.a = a_; + s.b = b_; +} + +/* { dg-final { scan-tree-dump "basic block part vectorized" "slp2" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr103116-1.c b/gcc/testsuite/gcc.dg/vect/pr103116-1.c new file mode 100644 index 0000000..d3639fc --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr103116-1.c @@ -0,0 +1,50 @@ +/* { dg-require-effective-target mmap } */ + +#include <sys/mman.h> +#include <stdio.h> + +#define COUNT 128 +#define MMAP_SIZE 0x20000 +#define ADDRESS 0x1122000000 +#define TYPE unsigned int + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void __attribute__((noipa)) +loop (TYPE *restrict x, TYPE *restrict y) +{ + for (int i = 0; i < COUNT; ++i) + { + x[i * 4] = y[i * 2] + 1; + x[i * 4 + 1] = y[i * 2] + 2; + x[i * 4 + 2] = y[i * 2 + 1] + 3; + x[i * 4 + 3] = y[i * 2 + 1] + 4; + } +} + +TYPE x[COUNT * 4]; + +int +main (void) +{ + void *y; + TYPE *end_y; + + y = mmap ((void *) ADDRESS, MMAP_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (y == MAP_FAILED) + { + perror ("mmap"); + return 1; + } + + end_y = (TYPE *) ((char *) y + MMAP_SIZE); + + loop (x, end_y - COUNT * 2); + + return 0; +} + +/* { dg-final { scan-tree-dump "Data access with gaps requires scalar epilogue loop" "vect" { target { vect_perm && vect_int } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr103116-2.c b/gcc/testsuite/gcc.dg/vect/pr103116-2.c new file mode 100644 index 0000000..2f4ed0f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr103116-2.c @@ -0,0 +1,59 @@ +/* { dg-require-effective-target mmap } */ +/* { dg-additional-options "-mssse3" { target x86_64-*-* i?86-*-* } } */ + +#include <sys/mman.h> +#include <stdio.h> +#include "tree-vect.h" + +#define COUNT 128 +#define MMAP_SIZE 0x20000 +#define ADDRESS 0x1122000000 +#define TYPE unsigned short +#define GROUP_SIZE 2 + +#ifndef MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif + +void __attribute__((noipa)) +loop (TYPE *restrict x, TYPE *restrict y) +{ + for (int i = 0; i < COUNT; ++i) + { + x[i * 8] = y[i * GROUP_SIZE] + 1; + x[i * 8 + 1] = y[i * GROUP_SIZE] + 2; + x[i * 8 + 2] = y[i * GROUP_SIZE + 1] + 3; + x[i * 8 + 3] = y[i * GROUP_SIZE + 1] + 4; + x[i * 8 + 4] = y[i * GROUP_SIZE] + 5; + x[i * 8 + 5] = y[i * GROUP_SIZE] + 6; + x[i * 8 + 6] = y[i * GROUP_SIZE + 1] + 7; + x[i * 8 + 7] = y[i * GROUP_SIZE + 1] + 8; + } +} + +TYPE x[COUNT * 4]; + +int +main (void) +{ + void *y; + TYPE *end_y; + + check_vect (); + + y = mmap ((void *) ADDRESS, MMAP_SIZE, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (y == MAP_FAILED) + { + perror ("mmap"); + return 1; + } + + end_y = (TYPE *) ((char *) y + MMAP_SIZE); + + loop (x, end_y - COUNT * GROUP_SIZE); + + return 0; +} + +/* { dg-final { scan-tree-dump "peeling for gaps insufficient for access" "vect" { target { vect_perm_short } } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr103761.c b/gcc/testsuite/gcc.dg/vect/pr103761.c new file mode 100644 index 0000000..0982a63 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr103761.c @@ -0,0 +1,13 @@ +/* { dg-do compile } */ + +void f(long *restrict x, int *restrict y, short *restrict z, int *restrict a) +{ + for (int i = 0; i < 100; i += 4) + { + x[i] = (long) y[z[i]] + 1; + x[i + 1] = (long) y[z[i + 1]] + 2; + x[i + 2] = (long) y[z[i + 2]] + 3; + x[i + 3] = (long) y[z[i + 3]] + 4; + a[i] += 1; + } +} diff --git a/gcc/testsuite/gcc.dg/vect/pr104595.c b/gcc/testsuite/gcc.dg/vect/pr104595.c new file mode 100644 index 0000000..bb7d79a --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr104595.c @@ -0,0 +1,24 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target vect_condition } */ + +#define N 256 +typedef char T; +extern T a[N]; +extern T b[N]; +extern T c[N]; +extern _Bool pb[N]; +extern char pc[N]; + +void predicate_by_bool() +{ + for (int i = 0; i < N; i++) + c[i] = pb[i] ? a[i] : b[i]; +} + +void predicate_by_char() +{ + for (int i = 0; i < N; i++) + c[i] = pc[i] ? a[i] : b[i]; +} + +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/pr104782.c b/gcc/testsuite/gcc.dg/vect/pr104782.c new file mode 100644 index 0000000..7b8ca6c --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr104782.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-O3" } */ +/* { dg-additional-options "-march=armv8.2-a+sve -msve-vector-bits=128" { target aarch64-*-* } } */ + +int a, b, c; +static int d; +short *q; +void f() { + int *p = &d; + b = 9; + for (b = 9; b; b--) { + a = 2; + for (c = 2; c <= 9; c++) { + for (int i = 0; i < 3; i++) + *p |= (*q)++; + } + } +} diff --git a/gcc/testsuite/gcc.dg/vect/pr105219.c b/gcc/testsuite/gcc.dg/vect/pr105219.c new file mode 100644 index 0000000..4bca5bb --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr105219.c @@ -0,0 +1,30 @@ +/* { dg-do run } */ +/* { dg-additional-options "-O3" } */ +/* { dg-additional-options "-mtune=intel" { target x86_64-*-* i?86-*-* } } */ +/* { dg-additional-options "-mtune=thunderx" { target aarch64*-*-* } } */ + +#include "tree-vect.h" + +int data[128]; + +void __attribute((noipa)) +foo (int *data, int n) +{ + for (int i = 0; i < n; ++i) + data[i] = i; +} + +int main() +{ + check_vect (); + for (int start = 0; start < 16; ++start) + for (int n = 1; n < 3*16; ++n) + { + __builtin_memset (data, 0, sizeof (data)); + foo (&data[start], n); + for (int j = 0; j < n; ++j) + if (data[start + j] != j) + __builtin_abort (); + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr106250.c b/gcc/testsuite/gcc.dg/vect/pr106250.c new file mode 100644 index 0000000..7f25f55 --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr106250.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ + +int +foo (unsigned long int x, int y, int z) +{ + int ret = 0; + + while (y < 1) + { + x *= 2; + ret = x == z; + z = y; + ++y; + } + + return ret; +} diff --git a/gcc/testsuite/gcc.dg/vect/pr81196-2.c b/gcc/testsuite/gcc.dg/vect/pr81196-2.c index 8d5ce6b..b5861c1 100644 --- a/gcc/testsuite/gcc.dg/vect/pr81196-2.c +++ b/gcc/testsuite/gcc.dg/vect/pr81196-2.c @@ -1,5 +1,7 @@ /* { dg-do compile } */ /* { dg-require-effective-target vect_int } */ +/* For negative stride we need to reverse the aligned load. */ +/* { dg-require-effective-target vect_perm } */ void b (int *p) { diff --git a/gcc/testsuite/gcc.dg/vect/pr84201.c b/gcc/testsuite/gcc.dg/vect/pr84201.c new file mode 100644 index 0000000..1cc6d1f --- /dev/null +++ b/gcc/testsuite/gcc.dg/vect/pr84201.c @@ -0,0 +1,22 @@ +/* { dg-do compile } */ +/* { dg-additional-options "-Ofast --param vect-induction-float=0" } */ + +void foo (float *a, float f, float s, int n) +{ + for (int i = 0; i < n; ++i) + { + a[i] = f; + f += s; + } +} + +void bar (double *a, double f, double s, int n) +{ + for (int i = 0; i < n; ++i) + { + a[i] = f; + f += s; + } +} + +/* { dg-final { scan-tree-dump-times "vectorized 0 loops" 2 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/slp-11a.c b/gcc/testsuite/gcc.dg/vect/slp-11a.c index bcd3c86..e6632fa 100644 --- a/gcc/testsuite/gcc.dg/vect/slp-11a.c +++ b/gcc/testsuite/gcc.dg/vect/slp-11a.c @@ -9,14 +9,14 @@ int main1 () { int i; - unsigned int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; - unsigned int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; + int out[N*8], a0, a1, a2, a3, a4, a5, a6, a7, b1, b0, b2, b3, b4, b5, b6, b7; + int in[N*8] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63}; /* Different operations - not SLPable. */ for (i = 0; i < N; i++) { a0 = in[i*8] + 5; - a1 = in[i*8 + 1] * 6; + a1 = in[i*8 + 1] * 51072; a2 = in[i*8 + 2] + 7; a3 = in[i*8 + 3] + 8; a4 = in[i*8 + 4] + 9; @@ -25,7 +25,7 @@ main1 () a7 = in[i*8 + 7] + 12; b0 = a0 * 3; - b1 = a1 * 2; + b1 = a1 * 51072; b2 = a2 * 12; b3 = a3 * 5; b4 = a4 * 8; @@ -47,7 +47,7 @@ main1 () for (i = 0; i < N; i++) { if (out[i*8] != (in[i*8] + 5) * 3 - 2 - || out[i*8 + 1] != (in[i*8 + 1] * 6) * 2 - 3 + || out[i*8 + 1] != (in[i*8 + 1] * 51072) * 51072 - 3 || out[i*8 + 2] != (in[i*8 + 2] + 7) * 12 - 2 || out[i*8 + 3] != (in[i*8 + 3] + 8) * 5 - 1 || out[i*8 + 4] != (in[i*8 + 4] + 9) * 8 - 8 diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-10.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-10.c index fe4f677..e9ec960 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-10.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-10.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-11.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-11.c index b77f4d4..06c103d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-11.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-11.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-12.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-12.c index 30d36f4..36ec5a8 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-12.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-12.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do assemble } */ /* { dg-additional-options "-O3 -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-2.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-2.c index 58c0b92..059bfb3 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-2.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-2.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-23.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-23.c index 67119d3..5b4c3b6 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-23.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-23.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do assemble } */ /* { dg-additional-options "-O1 -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-3.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-3.c index 58c0b92..059bfb3 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-3.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-4.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-4.c index 6e2da41..91b82fb 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-4.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-5.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-5.c index 5ef0f46..59f339f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-5.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-5.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-6.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-6.c index 22e5f88..84df837 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-6.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-6.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-8.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-8.c index edff542..b3e0b5b 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-8.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-8.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-9.c b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-9.c index 319d80e..5fcde11 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-9.c +++ b/gcc/testsuite/gcc.dg/vect/vect-bic-bitmask-9.c @@ -1,3 +1,4 @@ +/* { dg-skip-if "missing optab for vectorization" { sparc*-*-* } } */ /* { dg-do run } */ /* { dg-additional-options "-O3 -save-temps -fdump-tree-dce -w" } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c b/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c index b09caeb..4782d3f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c +++ b/gcc/testsuite/gcc.dg/vect/vect-multitypes-12.c @@ -26,6 +26,7 @@ int main (void) for (i=0; i<N; i++) { x[i] = i; + __asm__ volatile ("" : : : "memory"); } foo (N,z+2); @@ -38,7 +39,4 @@ int main (void) return 0; } -/* bleah */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target vect_unpack } } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! vect_unpack } } } } */ - +/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c index 9e5f464..9a5141ee 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1-big-array.c @@ -58,9 +58,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 8} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 5} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c index c2d0797..f2d284c 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-1.c @@ -62,9 +62,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 8} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 5} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c index 37da7c9..6f89aac 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3-big-array.c @@ -59,9 +59,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 8} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 9} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c index 4138480..a1e1182 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-3.c @@ -57,9 +57,7 @@ int main (void) return 0; } -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 8} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 9} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c index 514337c..03a6e67 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4-big-array.c @@ -62,9 +62,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 8} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 5} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c index 3d536d5..0ef377f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c +++ b/gcc/testsuite/gcc.dg/vect/vect-over-widen-4.c @@ -66,9 +66,7 @@ int main (void) } /* { dg-final { scan-tree-dump-times "vect_recog_widen_shift_pattern: detected" 2 "vect" { target vect_widen_shift } } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 3} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 3} "vect" } } */ -/* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* << 8} "vect" } } */ /* { dg-final { scan-tree-dump {vect_recog_over_widening_pattern: detected:[^\n]* >> 5} "vect" } } */ /* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c index 7ce8696..34e25ab 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-10.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 unsigned #define SIGNEDNESS_2 unsigned @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c index 0f7cbbb..3af8df5 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-11.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 unsigned #define SIGNEDNESS_2 signed @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c index 0841261..77ceef3 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-12.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 unsigned #define SIGNEDNESS_2 signed @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c index 7ee0f45..d3c0c86 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-13.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 signed #define SIGNEDNESS_2 unsigned @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c index 2de1434..86a5c85 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-14.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 signed #define SIGNEDNESS_2 unsigned @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c index dc48f95..25de094 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-15.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 signed #define SIGNEDNESS_2 signed @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c index aec6287..4a1dec0 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-16.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #define SIGNEDNESS_1 signed #define SIGNEDNESS_2 signed @@ -10,4 +10,4 @@ #include "vect-reduc-dot-9.c" /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c index 38f86fe..90d2118 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-17.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" @@ -50,4 +50,4 @@ main (void) } /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c index 2e86ebe..81ecb15 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-18.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" @@ -50,4 +50,4 @@ main (void) } /* { dg-final { scan-tree-dump "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c index d00f24a..cbcd4f12 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-19.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c index 17adbca8..e81ed1d 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-20.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c index 6cc6a4f..81ce5cd 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-21.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c index e13d3d5..b8c9d3c 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-22.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c index d1049c9..e0b132f 100644 --- a/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c +++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-dot-9.c @@ -1,6 +1,6 @@ /* { dg-require-effective-target vect_int } */ -/* { dg-require-effective-target arm_v8_2a_i8mm_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ -/* { dg-add-options arm_v8_2a_i8mm } */ +/* { dg-require-effective-target arm_v8_2a_dotprod_neon_hw { target { aarch64*-*-* || arm*-*-* } } } */ +/* { dg-add-options arm_v8_2a_dotprod_neon } */ #include "tree-vect.h" @@ -50,4 +50,4 @@ main (void) } /* { dg-final { scan-tree-dump-not "vect_recog_dot_prod_pattern: detected" "vect" } } */ -/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_usdot_qi } } } */ +/* { dg-final { scan-tree-dump-times "vectorized 1 loop" 1 "vect" { target vect_sdot_qi } } } */ diff --git a/gcc/testsuite/gcc.dg/vect/vect.exp b/gcc/testsuite/gcc.dg/vect/vect.exp index 5271608..dcaef1e 100644 --- a/gcc/testsuite/gcc.dg/vect/vect.exp +++ b/gcc/testsuite/gcc.dg/vect/vect.exp @@ -121,7 +121,7 @@ et-dg-runtest dg-runtest [lsort \ set DEFAULT_VECTCFLAGS $SAVED_DEFAULT_VECTCFLAGS lappend DEFAULT_VECTCFLAGS "-ffast-math" et-dg-runtest dg-runtest [lsort \ - [glob -nocomplain $srcdir/$subdir/fast-math-\[ipsv\]*.\[cS\]]] \ + [glob -nocomplain $srcdir/$subdir/fast-math-\[ipsvc\]*.\[cS\]]] \ "" $DEFAULT_VECTCFLAGS # -ffast-math SLP tests diff --git a/gcc/testsuite/gcc.dg/weak/typeof-2.c b/gcc/testsuite/gcc.dg/weak/typeof-2.c index afce17f..c6e45624 100644 --- a/gcc/testsuite/gcc.dg/weak/typeof-2.c +++ b/gcc/testsuite/gcc.dg/weak/typeof-2.c @@ -40,6 +40,8 @@ int bar3 (int x) // { dg-final { if [string match {sh[elb1-9]*-*-*} $target_triplet ] {return} } } // Likewise for S/390 targets // { dg-final { if [string match s390*-*-* $target_triplet ] {return} } } +// Likewise for ARM targets +// { dg-final { if [string match arm*-*-* $target_triplet ] {return} } } // Likewise for CRIS targets. // { dg-final { if [string match cris-*-* $target_triplet ] {return} } } // Likewise for m68k targets. |