aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-12-03 12:12:10 -0800
committerIan Lance Taylor <iant@golang.org>2020-12-03 12:12:10 -0800
commitf012991e2db06cc95f7aac8ecb74a1ac5f51f3d2 (patch)
tree582e5d7b377b6e973666a71960b28a7d11d72b07 /gcc/testsuite/gcc.dg
parent8d703821c69062c0cd255787d793e44f1a95d463 (diff)
parent3089f5feef36810c625b5813370a97b4ecc841f8 (diff)
downloadgcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.zip
gcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.tar.gz
gcc-f012991e2db06cc95f7aac8ecb74a1ac5f51f3d2.tar.bz2
Merge from trunk revision 3089f5feef36810c625b5813370a97b4ecc841f8
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/20021029-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-43.c27
-rw-r--r--gcc/testsuite/gcc.dg/Wstring-compare-3.c106
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-11.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-12.c7
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-27.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-28.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-29.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-37.c26
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-46.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-47.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-54.c10
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-58.c260
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-59.c267
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-60.c72
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-61.c88
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-62.c363
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-63.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-64.c74
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-7.c124
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c34
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-5.c13
-rw-r--r--gcc/testsuite/gcc.dg/array-quals-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-4.c8
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-5.c16
-rw-r--r--gcc/testsuite/gcc.dg/binary-constants-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/binary-constants-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c43
-rw-r--r--gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c87
-rw-r--r--gcc/testsuite/gcc.dg/builtin-clear-padding-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/builtin-clear-padding-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/c11-binary-constants-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/c11-binary-constants-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-4.c25
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-5.c35
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-6.c17
-rw-r--r--gcc/testsuite/gcc.dg/c11-float-dfp-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/c2x-binary-constants-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-10.c33
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-2.c23
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-3.c27
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-5.c32
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-6.c49
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-7.c49
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-8.c7
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-9.c7
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c26
-rw-r--r--gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c25
-rw-r--r--gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c18
-rw-r--r--gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c52
-rw-r--r--gcc/testsuite/gcc.dg/cond-constqual-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line10.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/line9.c5
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr97989-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/cpp/pr97989-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/cr-decimal-dig-3.c14
-rw-r--r--gcc/testsuite/gcc.dg/darwin-sections.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c13
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c25
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c28
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c45
-rw-r--r--gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c45
-rw-r--r--gcc/testsuite/gcc.dg/fold-isfinite-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isfinite-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isinf-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isinf-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isnan-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-isnan-2.c21
-rw-r--r--gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/goacc/tile-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/guality/pr59776.c2
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/hwasan.exp36
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c53
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c27
-rw-r--r--gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c28
-rw-r--r--gcc/testsuite/gcc.dg/ipa/modref-2.c5
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-3_0.c17
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-3_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-4_0.c17
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-4_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/lvalue-11.c40
-rw-r--r--gcc/testsuite/gcc.dg/memchr-3.c25
-rw-r--r--gcc/testsuite/gcc.dg/nextafter-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/nextafter-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c436
-rw-r--r--gcc/testsuite/gcc.dg/plugin/gil-1.c90
-rw-r--r--gcc/testsuite/gcc.dg/plugin/gil.h32
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp2
-rw-r--r--gcc/testsuite/gcc.dg/pr25376.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr46309-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr60195.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr83072.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr85811.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr91029.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr95853.c59
-rw-r--r--gcc/testsuite/gcc.dg/pr96708-negative.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr96708-positive.c48
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-2.c57
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-3.c54
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-4.c57
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-5.c56
-rw-r--r--gcc/testsuite/gcc.dg/pr97459-6.c62
-rw-r--r--gcc/testsuite/gcc.dg/pr97515.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr97534.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr97579.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr97806.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr97830.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr97860.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr97897.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr97953.c24
-rw-r--r--gcc/testsuite/gcc.dg/pr97954.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr97955.c7
-rw-r--r--gcc/testsuite/gcc.dg/pr97979.c13
-rw-r--r--gcc/testsuite/gcc.dg/pr98099.c12
-rw-r--r--gcc/testsuite/gcc.dg/profile-info-section.c22
-rw-r--r--gcc/testsuite/gcc.dg/strncmp-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/system-binary-constants-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float16-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c11
-rw-r--r--gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h36
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97812.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97901.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-5.c8
-rw-r--r--gcc/testsuite/gcc.dg/torture/ssa-fre-6.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/stringop-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c76
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp20.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp21.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/evrp22.c43
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c42
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-5.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr23401.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr27810.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr78655.c37
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c68
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c98
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96480.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96789.c5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96929.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97849.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97964.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c52
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr98084.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr98094.c21
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/switch-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/typeof-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-43.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-8.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr91750.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97678.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97693.c15
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97730.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97835.c22
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97838.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr98048.c14
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-21.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-46.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-49.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-6.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-7.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-35-big-array.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-35.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c12
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-epilogues.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c8
225 files changed, 5791 insertions, 223 deletions
diff --git a/gcc/testsuite/gcc.dg/20021029-1.c b/gcc/testsuite/gcc.dg/20021029-1.c
index f11a6e4..57c2b48 100644
--- a/gcc/testsuite/gcc.dg/20021029-1.c
+++ b/gcc/testsuite/gcc.dg/20021029-1.c
@@ -3,6 +3,7 @@
/* { dg-do compile { target fpic } } */
/* { dg-options "-O2 -fpic" } */
/* { dg-final { scan-assembler-not ".data.rel.ro.local" } } */
+/* { dg-final { scan-assembler-symbol-section {ar} {^\.(const|rodata)|\[RO\]} } } */
/* { dg-require-effective-target label_values } */
/* { dg-require-effective-target indirect_jumps } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-43.c b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
index 8892921..0f521a7 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-43.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-43.c
@@ -5,20 +5,9 @@
#define NOIPA __attribute__ ((noipa))
-const char a0[] = "";
-const char a1[] = "1";
-const char a2[] = "12";
-const char a3[] = "123";
-const char a4[] = "1234";
-const char a5[] = "12345";
-const char a6[] = "123456";
-const char a7[] = "1234567";
-const char a8[] = "12345678";
const char a9[] = "123456789";
-void f (const char*, ...);
-
-int i0, i1, i2, i3, i4, i5, i6, i7, i8;
+void sink (const char*, ...);
NOIPA int g2 (int i)
{
@@ -28,7 +17,7 @@ NOIPA int g2 (int i)
const char *p1 = p0 + i;
const char *p2 = p1 + i;
- f (p0, p1, p2);
+ sink (p0, p1, p2);
return p2[8]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -42,7 +31,7 @@ NOIPA int g3 (int i)
const char *p2 = p1 + i;
const char *p3 = p2 + i;
- f (p0, p1, p2, p3);
+ sink (p0, p1, p2, p3);
return p3[7]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -57,7 +46,7 @@ NOIPA int g4 (int i)
const char *p3 = p2 + i;
const char *p4 = p3 + i;
- f (p0, p1, p2, p3, p4);
+ sink (p0, p1, p2, p3, p4);
return p4[6]; // { dg-warning "\\\[-Warray-bounds]" }
}
@@ -73,7 +62,7 @@ NOIPA int g5 (int i)
const char *p4 = p3 + i;
const char *p5 = p4 + i;
- f (p0, p1, p2, p3, p4, p5);
+ sink (p0, p1, p2, p3, p4, p5);
return p5[5];
}
@@ -90,7 +79,7 @@ NOIPA int g6 (int i)
const char *p5 = p4 + i;
const char *p6 = p5 + i;
- f (p0, p1, p2, p3, p4, p5, p6);
+ sink (p0, p1, p2, p3, p4, p5, p6);
return p6[4];
}
@@ -108,7 +97,7 @@ NOIPA int g7 (int i)
const char *p6 = p5 + i;
const char *p7 = p6 + i;
- f (p0, p1, p2, p3, p4, p5, p6, p7);
+ sink (p0, p1, p2, p3, p4, p5, p6, p7);
return p7[3];
}
@@ -127,7 +116,7 @@ NOIPA int g8 (int i)
const char *p7 = p6 + i;
const char *p8 = p7 + i;
- f (p0, p1, p2, p3, p4, p5, p6, p7, p8);
+ sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
return p8[2];
}
diff --git a/gcc/testsuite/gcc.dg/Wstring-compare-3.c b/gcc/testsuite/gcc.dg/Wstring-compare-3.c
new file mode 100644
index 0000000..d4d7121
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstring-compare-3.c
@@ -0,0 +1,106 @@
+/* PR middle-end/95673 - missing -Wstring-compare for an impossible strncmp test
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wstring-compare -ftrack-macro-expansion=0" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern int strcmp (const char*, const char*);
+extern int strncmp (const char*, const char*, size_t);
+
+void sink (int, ...);
+
+extern char a3[3];
+
+int nowarn_strcmp_one_use_ltz (int c)
+{
+ const char *s = c ? "1234" : a3;
+ int n = strcmp (s, "123");
+ return n < 0;
+}
+
+
+int nowarn_strcmp_one_use_eqnz (int c)
+{
+ const char *s = c ? "12345" : a3;
+ int n = strcmp (s, "123");
+ return n == 1;
+}
+
+
+int warn_strcmp_one_use_eqz (int c)
+{
+ const char *s = c ? "123456" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return n == 0; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_bang (int c)
+{
+ const char *s = c ? "1234567" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return !n; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_bang_bang (int c)
+{
+ const char *s = c ? "12345678" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return !!n; // { dg-message "in this expression" }
+}
+
+
+_Bool warn_one_use_bool (int c)
+{
+ const char *s = c ? "123456789" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return (_Bool)n; // { dg-message "in this expression" }
+}
+
+
+int warn_strcmp_one_use_cond (int c)
+{
+ const char *s = c ? "1234567890" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ return n ? 3 : 5; // { dg-message "in this expression" }
+}
+
+
+int nowarn_strcmp_multiple_uses (int c)
+{
+ const char *s = c ? "1234" : a3;
+ int n = strcmp (s, "123");
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n + 1);
+ return n;
+}
+
+
+int warn_strcmp_multiple_uses (int c)
+{
+ const char *s = c ? "12345" : a3;
+ int n = strcmp (s, "123"); // { dg-warning "'strcmp' of a string of length 3 and an array of size 3 evaluates to nonzero" }
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n == 0); // { dg-message "in this expression" }
+ return n;
+}
+
+
+int warn_strncmp_multiple_uses (int c)
+{
+ const char *s = a3;
+ int n = strncmp (s, "1234", 4); // { dg-warning "'strncmp' of a string of length 4, an array of size 3 and bound of 4 evaluates to nonzero" }
+ sink (n < 0);
+ sink (n > 0);
+ sink (n <= 0);
+ sink (n >= 0);
+ sink (n == 0); // { dg-message "in this expression" }
+ return n;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
index f5dac45..ec3c97e 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-11.c
@@ -72,7 +72,7 @@ void test_memset_array_range_cst_off (void)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
@@ -147,7 +147,7 @@ void test_memcpy_array_range_cst_off (const void *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
@@ -224,7 +224,7 @@ void test_strcpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 6);
T (SR (-1, 1), 1, 6);
- T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 8); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 0);
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 4);
@@ -290,7 +290,7 @@ void test_strncpy_array_range_cst_off (const char *s)
{
T (SR (-7, 7), 1, 7);
T (SR (-1, 1), 1, 7);
- T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" { xfail *-*-*} } */
+ T (SR (-1, 1), 1, 9); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" "pr89428" } */
T (SR ( 1, 2), 1, 1);
T (SR ( 1, 2), 1, 5);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
index 1e67b5f..7c3dc8c 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-12.c
@@ -25,7 +25,9 @@ void test_memcpy_array_cst_range_off (const void *s)
T (d + UR (1, 2), 5);
T (d + UR (0, 1), 6);
- T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" "pr89428" { xfail *-*-* } } */
+ /* The warning below should be "writing" but the [0, 1] range
+ is somehow lost and get_range_info() returns VR_VARYING. */
+ T (d + UR (0, 1), 7); /* { dg-warning ".memcpy. writing 7 bytes into a region of size 6 overflows the destination" "pr89428" { xfail *-*-* } } */
T (d + UR (1, 2), 6); /* { dg-warning ".memcpy. writing 6 bytes into a region of size 5 overflows the destination" } */
T (d + UR (1, 2), 7); /* { dg-warning "writing 7 bytes into a region of size 5 " } */
@@ -48,7 +50,8 @@ void test_memcpy_array_range_range_off (const void *s)
char *d = ga7 + UR (0, 1);
T (d + SR (-1, 0), 1);
T (d + SR (-1, 0), 7);
- T (d + SR (-1, 0), 9); /* { dg-warning "writing 1 byte into a region of size 0 " "pr89350" { xfail *-*-* } } */
+ T (d + SR (-1, 0), 8); /* { dg-warning "writing 8 bytes into a region of size 7 " } */
+ T (d + SR (-1, 0), 9); /* { dg-warning "writing 9 bytes into a region of size 7 " "pr89350" } */
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
index fb81420..9c05d04 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-17.c
@@ -13,7 +13,7 @@ void sink (void*);
void call_copy_n (const char *s)
{
- char a[7]; // { dg-message "declared here" }
+ char a[7]; // { dg-message "at offset 7 into destination object 'a'" }
copy_n (a, "1234567", 7);
sink (a);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
index 37c1ca2..607c279 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
@@ -261,8 +261,7 @@ void test_strcpy_warn (const char *s)
that the conversion from signed int to size_t doesn't prevent
the detection. */
int n = strlen (a);
- char *t = (char*)calloc (n, 1); // { dg-message "at offset 0 to an object with size 3 allocated by 'calloc' here" "calloc note 1" { xfail *-*-* } }
- // { dg-message "at offset 0 to an object with size at most 3 allocated by 'calloc' here" "calloc note 2" { target *-*-* } .-1 }
+ char *t = (char*)calloc (n, 1); // { dg-message "destination object of size 3 allocated by 'calloc'" "note" }
strcpy (t, a); // { dg-warning "writing 4 bytes into a region of size (between 0 and )?3 " }
sink (t);
@@ -271,8 +270,7 @@ void test_strcpy_warn (const char *s)
{
const char a[] = "1234";
size_t n = strlen (a);
- char *t = (char*)malloc (n); // { dg-message "at offset 0 to an object with size 4 allocated by 'malloc' here" "malloc note 1" { xfail *-*-* } }
- // { dg-message "at offset 0 to an object with size at most 4 allocated by 'malloc' here" "malloc note 2" { target *-*-* } .-1 }
+ char *t = (char*)malloc (n); // { dg-message "destination object of size 4 allocated by 'malloc'" "note" }
strcpy (t, a); // { dg-warning "writing 5 bytes into a region of size (between 0 and )?4 " }
sink (t);
}
@@ -280,14 +278,14 @@ void test_strcpy_warn (const char *s)
// Exercise PR middle-end/85484.
{
size_t len = strlen (s);
- char vla[len]; // { dg-message "at offset 0 to an object declared here" "vla note" }
+ char vla[len]; // { dg-message "destination object 'vla'" "vla note" }
strcpy (vla, s); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }
sink (vla);
}
{
size_t n = strlen (s);
- char *t = (char*)malloc (n); // { dg-message "at offset 0 to an object allocated by 'malloc' here" "malloc note" }
+ char *t = (char*)malloc (n); // { dg-message "allocated by 'malloc'" "malloc note" }
strcpy (t, s); // { dg-warning "writing one too many bytes into a region of a size that depends on 'strlen'" }
sink (t);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
index be7f51a..5009fb5 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-28.c
@@ -40,27 +40,27 @@ void same_size_and_offset_idx_cst (void)
const size_t n = UR (2, 3);
T (n, n, -4); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, n, -3);
T (n, n, -2);
T (n, n, -1);
T (n, n, 0);
T (n, n, 1); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[3, 4] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 3 into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
const size_t n = UR (3, 4);
T (n, n, -5); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, n, -4);
T (n, n, -3);
T (n, n, -2);
T (n, n, -1);
T (n, n, 0);
T (n, n, 1); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[4, 5] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
@@ -84,15 +84,15 @@ void different_size_and_offset_idx_cst (void)
const size_t i = UR (1, 2);
T (n, i, -4); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-3, -2] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-3, -2] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, i, -3); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-2, -1] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-2, -1] into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
T (n, i, -2);
T (n, i, -1);
T (n, i, 0);
T (n, i, 1);
T (n, i, 2); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[3, 4] to an object with size between 2 and 3 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 3 into destination object of size \\\[2, 3] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
{
@@ -100,20 +100,20 @@ void different_size_and_offset_idx_cst (void)
const size_t i = UR (2, 5);
T (n, i, -6); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[-4, -1] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[-4, -2] into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
- /* The offsets -5 and -4 are both necessarily invalid even if the sum
- (i - 5) and (i - 4) are (or could be) in bounds because they imply
- that the intermediate offset (p + i) is out of bounds. */
- T (n, i, -5); // { dg-warning "" "intermediate offset" { xfail *-*-* } }
- T (n, i, -4); // { dg-warning "" "intermediate offset" { xfail *-*-* } }
+ /* The offset -5 is necessarily invalid even if the sum (i - 5) is (or
+ could be) in bounds because it implies that the intermediate offset
+ (p + i) is out of bounds. */
+ T (n, i, -5); // { dg-warning "writing 1 byte into a region of size 0 " }
+ T (n, i, -4);
T (n, i, -3);
T (n, i, -2);
T (n, i, -1);
T (n, i, 0);
T (n, i, 1);
T (n, i, 2); // { dg-warning "writing 1 byte into a region of size 0" }
- // { dg-message "at offset \\\[4, 7] to an object with size between 3 and 4 allocated by 'alloc1'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "note" { target *-*-* } .-1 }
}
}
@@ -133,11 +133,8 @@ void different_size_and_offset_idx_var (void)
T (n, i, SR ( 0, 1));
T (n, i, SR ( 1, 2));
T (n, i, SR ( 2, 3));
- /* The warning is issued below but the offset and the size in
- the note are wrong. See the FIXME in compute_objsize(). */
T (n, i, SR ( 3, 4)); // { dg-warning "\\\[-Wstringop-overflow" }
- // { dg-message "at offset 4 to an object with size between 3 and 4 allocated by 'alloc1'" "pr92940 note: offset addition" { xfail *-*-* } .-1 }
- // { dg-message "at offset . to an object with size . allocated by 'alloc1'" "note: offset addition" { target *-*-* } .-2 }
+ // { dg-message "at offset 4 into destination object of size \\\[3, 4] allocated by 'alloc1'" "pr92940 note: offset addition" { target *-*-* } .-1 }
}
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
index c011d05..f13abbd 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-29.c
@@ -11,7 +11,7 @@ void sink (void*);
void direct_call (void)
{
- char *q = allocfn (0); // { dg-message "at offset 0 to an object with size 0 allocated by 'allocfn'" }
+ char *q = allocfn (0); // { dg-message "object of size 0 allocated by 'allocfn'" "note" }
q[0] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
sink (q);
}
@@ -20,7 +20,7 @@ void direct_call (void)
void local_ptr_call (void)
{
allocfn_t *ptr = allocfn;
- char *q = ptr (1); // { dg-message "at offset -1 to an object with size 1 allocated by 'allocfn'" }
+ char *q = ptr (1); // { dg-message "at offset -1 into destination object of size 1 allocated by 'allocfn'" "note" }
q[0] = 0;
q[-1] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
sink (q);
@@ -32,7 +32,7 @@ void global_ptr_call (void)
extern allocfn_t *ptralloc;
allocfn_t *ptr = ptralloc;
- char *q = ptr (2); // { dg-message "at offset 3 to an object with size 2 allocated by 'ptralloc'" }
+ char *q = ptr (2); // { dg-message "at offset 3 into destination object of size 2 allocated by 'ptralloc'" "note" }
q[0] = 0;
q[1] = 1;
q[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" }
@@ -44,7 +44,7 @@ void global_ptr_array_call (void)
extern allocfn_t * (arralloc[]);
allocfn_t *ptr = arralloc[0];
- char *q = ptr (2); // { dg-message "at offset 3 to an object with size 2 allocated by 'ptr'" }
+ char *q = ptr (2); // { dg-message "at offset 3 into destination object of size 2 allocated by 'ptr'" "note" }
q[0] = 1;
q[1] = 2;
q[3] = 3; // { dg-warning "\\\[-Wstringop-overflow" }
@@ -56,7 +56,7 @@ struct S { allocfn_t *ptralloc; };
void member_ptr_call (struct S *p)
{
- char *q = p->ptralloc (3); // { dg-message "at offset 5 to an object with size 3 allocated by 'ptralloc' here" }
+ char *q = p->ptralloc (3); // { dg-message "at offset 5 into destination object of size 3 allocated by 'ptralloc'" "note" }
q[0] = 0;
q[1] = 1;
q[2] = 2;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
index 46f8fed..d9cf32d 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
@@ -67,7 +67,7 @@ void* warn_malloc_3_5 (const char *s, unsigned n)
{
if (n < 3 || 5 < n)
n = 3;
- char *p = (char*)malloc (n); // { dg-message "at offset 1 into destination object of size \\\[3, 5] allocated by 'malloc'" }
+ char *p = (char*)malloc (n); // { dg-message "at offset 1 into destination object of size \\\[3, 5] allocated by 'malloc'" "note" }
// The size below should be a range like the one above.
strncpy (p + 1, s, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
return p;
@@ -89,7 +89,7 @@ void* warn_usr_alloc_3_5 (UsrAlloc *usr_alloc, const char *s, unsigned n)
{
if (n < 3 || 5 < n)
n = 3;
- char *p = (char*)usr_alloc (n, 3); // { dg-message "at offset 1 into destination object of size \\\[9, 15] allocated by 'usr_alloc'" }
+ char *p = (char*)usr_alloc (n, 3); // { dg-message "at offset 1 into destination object of size \\\[9, 15] allocated by 'usr_alloc'" "note" }
// The size below should be a range like the one above.
strncpy (p + 1, s, 15); // { dg-warning "writing 15 bytes into a region of size 14 " }
return p;
@@ -179,67 +179,67 @@ void test_note (const char *s)
extern void sink (void*);
{
- char a[1][1][2]; // { dg-message "destination object" }
+ char a[1][1][2]; // { dg-message "destination object" "note" }
strncpy (a[0][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][1][2]; // { dg-message "at offset 2 into " }
+ char a[1][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "destination object" }
+ char a[1][2][2]; // { dg-message "destination object" "note" }
strncpy (a[0][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "at offset 2 into " }
+ char a[1][2][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[1][2][2]; // { dg-message "at offset 4 into " }
+ char a[1][2][2]; // { dg-message "at offset 4 into " "note" }
strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[2][1][2]; // { dg-message "at offset 2 into " }
+ char a[2][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
{
- char a[2][1][2]; // { dg-message "at offset 2 into " }
+ char a[2][1][2]; // { dg-message "at offset 2 into " "note" }
strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
}
{
- char a[2][2][3]; // { dg-message "at offset 9 into " }
+ char a[2][2][3]; // { dg-message "at offset 9 into " "note" }
strncpy (a[1][1], s, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 12 into " }
+ char a[2][3][3]; // { dg-message "at offset 12 into " "note" }
strncpy (a[1][1], s, 5); // { dg-warning "writing 5 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 12 into " }
+ char a[2][3][3]; // { dg-message "at offset 12 into " "note" }
strncpy (a[1][1], s, 6); // { dg-warning "writing 6 bytes into a region of size 3 " }
sink (a);
}
{
- char a[2][3][3]; // { dg-message "at offset 15 into " }
+ char a[2][3][3]; // { dg-message "at offset 15 into " "note" }
strncpy (a[1][2], s, 7); // { dg-warning "writing 7 bytes into a region of size 3 " }
sink (a);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
index a4d78b2..b126fcb 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
@@ -53,7 +53,7 @@ void nowarn_memchr_anti_range_memset_cst (const void *s, size_t n)
void warn_memchr_cst_memset_cst (const void *s)
{
- char *p = malloc (4); // { dg-message "at offset \\\[0, 4] into destination object of size 4 " "note" }
+ char *p = malloc (4); // { dg-message "destination object of size 4 " "note" }
sink (p);
p = memchr (p, '1', 4);
@@ -62,7 +62,7 @@ void warn_memchr_cst_memset_cst (const void *s)
void warn_memchr_var_memset_cst (const void *s, unsigned n)
{
- char *p = malloc (4); // { dg-message "at offset \\\[0, 4] into destination object of size 4 " "note" }
+ char *p = malloc (4); // { dg-message "destination object of size 4 " "note" }
sink (p);
p = memchr (p, '1', n);
@@ -79,9 +79,9 @@ void warn_memchr_var_memset_range (const void *s, unsigned n)
as in the first two notes. The exact value probably isn't too
important. */
char *p0 = malloc (UR (5, 7));
- // { dg-message "at offset \\\[0, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-1 }
- // { dg-message "at offset \\\[1, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-2 }
- // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object of size \\\[5, 7]" "note 1" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[1, 7] into destination object of size \\\[5, 7]" "note 2" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 7] into destination object of size \\\[5, 7]" "note 3" { target *-*-* } .-3 }
sink (p0);
char *p1 = memchr (p0, '1', n);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
index 02b14ee..cb2c329 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
@@ -26,7 +26,7 @@ void nowarn_c32 (char c)
void warn_c32 (char c)
{
- extern char warn_a32[32]; // { dg-message "at offset 32 to object 'warn_a32' with size 32" }
+ extern char warn_a32[32]; // { dg-message "at offset 32 into destination object 'warn_a32' of size 32" "note" }
void *p = warn_a32 + 1;
*(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" }
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
index 26568f8..f5929c9 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
@@ -15,7 +15,7 @@ void sink (void*);
void char_flexarray_cst_off_cst_size (void)
{
extern struct { char n, a[]; }
- caxcc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'caxcc'" }
+ caxcc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'caxcc'" "note" }
char *p = caxcc.a;
size_t idx = DIFF_MAX - 4;
@@ -38,7 +38,7 @@ void char_flexarray_cst_off_cst_size (void)
void char_flexarray_var_off_cst_size (ptrdiff_t idx)
{
extern struct { char n, a[]; }
- caxvc; // { dg-message "destination object 'caxvc'" }
+ caxvc; // { dg-message "destination object 'caxvc'" "note" }
char *p = caxvc.a;
@@ -55,7 +55,7 @@ void char_flexarray_var_off_cst_size (ptrdiff_t idx)
void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
{
extern struct { char n, a[]; }
- caxvv; // { dg-message "destination object 'caxvv'" }
+ caxvv; // { dg-message "destination object 'caxvv'" "note" }
char *p = caxvv.a;
@@ -76,7 +76,7 @@ void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
void alloc_array_var_off_cst_size (size_t n, ptrdiff_t idx)
{
struct { char n, a[]; }
- *p = __builtin_malloc (n); // { dg-message "at offset \\d+ into destination object" }
+ *p = __builtin_malloc (n); // { dg-message "at offset \\d+ into destination object" "note" }
if (idx < DIFF_MAX - 4)
idx = DIFF_MAX - 4;
@@ -91,7 +91,7 @@ void alloc_array_var_off_cst_size (size_t n, ptrdiff_t idx)
void int_array_cst_off_cst_size (void)
{
extern struct { int n, a[]; }
- iaxc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" }
+ iaxc; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" "note" }
int *p = iaxc.a;
size_t idx = DIFF_MAX / sizeof *p - 1;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
new file mode 100644
index 0000000..b81186c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-58.c
@@ -0,0 +1,260 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Exercise warnings for writing into one of two or more declared objects.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+extern void* memset (void*, int, size_t);
+#define memset(d, c, n) sink (memset (d, c, n))
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+volatile int cond1, cond2;
+
+extern char ca0[0], ca1[1], ca2[2], ca3[3], ca4[4],
+ ca5[5], ca6[6], ca7[7], ca8[8], ca9[9], cax[];
+
+#define CHOOSE_DECL_2(n1, n2) \
+ (cond1 ? ca ## n1 : ca ## n2)
+#define CHOOSE_DECL_3(n1, n2, n3) \
+ (cond1 < 0 ? ca ## n1 : 0 < cond1 ? ca ## n2 : ca ## n3)
+
+
+void memset_decl_2 (void)
+{
+ {
+ char *p0_1 = CHOOSE_DECL_2 (0, 1);
+
+ memset (p0_1, 0, 0);
+ /* Writing more than the smallest destination should trigger a "may
+ write" warning if the access is unconditionally reachable from
+ the block where the pointer to either object is assigned. */
+ memset (p0_1, 0, 1);
+ memset (p0_1, 0, 2); // { dg-warning "memset' writing 2 bytes into a region of size 1 " }
+ memset (p0_1, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 1 " }
+ }
+
+ {
+ char *p0_x = CHOOSE_DECL_2 (0, x);
+
+ memset (p0_x, 0, 0);
+ memset (p0_x, 0, 1);
+ memset (p0_x, 0, 2);
+ memset (p0_x, 0, 9);
+ }
+
+ {
+ char *p3_5 = CHOOSE_DECL_2 (3, 5);
+
+ memset (p3_5, 0, 1);
+ memset (p3_5, 0, 3);
+ memset (p3_5, 0, 4);
+ memset (p3_5, 0, 5);
+ memset (p3_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3 = CHOOSE_DECL_2 (5, 3);
+
+ memset (p5_3, 0, 3);
+ memset (p5_3, 0, 4);
+ memset (p5_3, 0, 5);
+ memset (p5_3, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *px_3 = CHOOSE_DECL_2 (x, 3);
+
+ memset (px_3, 0, 1);
+ memset (px_3, 0, 3);
+ memset (px_3, 0, 4);
+ memset (px_3, 0, 1234);
+ }
+
+ {
+ char *p5_x = CHOOSE_DECL_2 (5, x);
+
+ memset (p5_x, 0, 1);
+ memset (p5_x, 0, 5);
+ memset (p5_x, 0, 6);
+ memset (p5_x, 0, 1234);
+ }
+
+}
+
+
+void memset_decl_3 (void)
+{
+ {
+ char *p0_1_2 = CHOOSE_DECL_3 (0, 1, 2);
+ memset (p0_1_2, 0, 0);
+ memset (p0_1_2, 0, 1);
+ memset (p0_1_2, 0, 2);
+ memset (p0_1_2, 0, 3); // { dg-warning "memset' writing 3 bytes into a region of size 2 " }
+ memset (p0_1_2, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 2 " }
+ }
+
+ {
+ char *p0_2_x = CHOOSE_DECL_3 (0, 2, x);
+
+ memset (p0_2_x, 0, 0);
+ memset (p0_2_x, 0, 1);
+ memset (p0_2_x, 0, 3);
+ memset (p0_2_x, 0, 9);
+ }
+
+ {
+ char *p3_4_5 = CHOOSE_DECL_3 (3, 4, 5);
+
+ memset (p3_4_5, 0, 3);
+ memset (p3_4_5, 0, 4);
+ memset (p3_4_5, 0, 5);
+ memset (p3_4_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3_4 = CHOOSE_DECL_3 (5, 3, 4);
+
+ memset (p5_3_4, 0, 3);
+ memset (p5_3_4, 0, 4);
+ memset (p5_3_4, 0, 5);
+ memset (p5_3_4, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p9_8_7 = CHOOSE_DECL_3 (9, 8, 7);
+
+ memset (p9_8_7, 0, 7);
+ memset (p9_8_7, 0, 8);
+ memset (p9_8_7, 0, 9);
+ memset (p9_8_7, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9 " }
+ }
+}
+
+
+/* Verify conditionally writing into one of two objects with the same
+ size. */
+
+void memset_decl_2_same_size (int i)
+{
+ {
+ char a4_1[4], a4_2[4];
+ char *p4 = cond1 ? a4_1 : a4_2;
+
+ memset (p4, 0, 1);
+ memset (p4, 0, 2);
+ memset (p4, 0, 3);
+ memset (p4, 0, 4);
+ memset (p4, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ char a4_1[4]; // { dg-message "destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ if (i < 1)
+ i = 1;
+
+ char a4_1[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 3);
+ memset (p4_i, 0, 4); // { dg-warning "memset' writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void memset_decl_2_off (void)
+{
+ int i1 = SR (1, INT_MAX);
+ int i2 = SR (2, INT_MAX);
+
+ {
+ char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5'
+ char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7'
+ char *p5_p1 = a5 + i1;
+ char *p7_p2 = a7 + i2;
+ char *p5_7 = cond1 ? p5_p1 : p7_p2;
+
+ memset (p5_7, 0, 1);
+ memset (p5_7, 0, 2);
+ memset (p5_7, 0, 3);
+ memset (p5_7, 0, 4);
+ memset (p5_7, 0, 5);
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ int i3 = SR (3, INT_MAX);
+
+ {
+ char a5[5];
+ // { dg-message "at offset \\\[3, 5] into destination object 'a5'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[2, 5] into destination object 'a5'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a5'" "note" { target *-*-* } .-4 }
+ char a9[9];
+ // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ char *p5_p2 = a5 + i2; // 3 bytes left
+ char *p9_p3 = a9 + i3; // 6 bytes left
+ char *p =
+ cond1 ? p5_p2 : p9_p3; // [3 - 6] bytes left
+ char *q = p + i1; // [2 - 5] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+
+ --q; // [3 - 6] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+
+ --q; // [4 - 7] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+
+ int m1_x = SR (-1, INT_MAX);
+ int m2_x = SR (-2, INT_MAX);
+
+ q += cond2 ? m1_x : m2_x; // [5 - 9] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8);
+ memset (q, 0, 9);
+ memset (q, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
new file mode 100644
index 0000000..c45a92d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-59.c
@@ -0,0 +1,267 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Exercise warnings for writing into one of two or more allocated objects.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+extern void* malloc (size_t);
+extern void* memset (void*, int, size_t);
+#define memset(d, c, n) sink (memset (d, c, n))
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+volatile int cond1, cond2, x;
+
+#define CHOOSE_MALLOC_2(n1, n2) \
+ (cond1 ? malloc (n1) : malloc (n2))
+#define CHOOSE_MALLOC_3(n1, n2, n3) \
+ (cond1 < 0 ? malloc (n1) : 0 < cond1 ? malloc (n2) : malloc (n3))
+
+
+void memset_malloc_2 (void)
+{
+ {
+ char *p0_1 = CHOOSE_MALLOC_2 (0, 1);
+
+ memset (p0_1, 0, 0);
+ /* Writing more than the smallest destination should trigger a "may
+ write" warning if the access is unconditionally reachable from
+ the block where the pointer to either object is assigned. */
+ memset (p0_1, 0, 1);
+ memset (p0_1, 0, 2); // { dg-warning "memset' writing 2 bytes into a region of size 1 " }
+ memset (p0_1, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 1 " }
+ }
+
+ {
+ char *p0_x = CHOOSE_MALLOC_2 (0, x);
+
+ memset (p0_x, 0, 0);
+ memset (p0_x, 0, 1);
+ memset (p0_x, 0, 2);
+ memset (p0_x, 0, 12345);
+ }
+
+ {
+ char *px_x = CHOOSE_MALLOC_2 (x, x);
+
+ memset (px_x, 0, 0);
+ memset (px_x, 0, 1);
+ memset (px_x, 0, 2);
+ memset (px_x, 0, 12345);
+ }
+
+ {
+ char *p3_5 = CHOOSE_MALLOC_2 (3, 5);
+
+ memset (p3_5, 0, 1);
+ memset (p3_5, 0, 3);
+ memset (p3_5, 0, 4);
+ memset (p3_5, 0, 5);
+ memset (p3_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3 = CHOOSE_MALLOC_2 (5, 3);
+
+ memset (p5_3, 0, 3);
+ memset (p5_3, 0, 4);
+ memset (p5_3, 0, 5);
+ memset (p5_3, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *px_3 = CHOOSE_MALLOC_2 (x, 3);
+
+ memset (px_3, 0, 1);
+ memset (px_3, 0, 3);
+ memset (px_3, 0, 4);
+ memset (px_3, 0, 1234);
+ }
+
+ {
+ char *p5_x = CHOOSE_MALLOC_2 (5, x);
+
+ memset (p5_x, 0, 1);
+ memset (p5_x, 0, 5);
+ memset (p5_x, 0, 6);
+ memset (p5_x, 0, 1234);
+ }
+
+}
+
+
+void memset_malloc_3 (void)
+{
+ {
+ char *p0_1_2 = CHOOSE_MALLOC_3 (0, 1, 2);
+ memset (p0_1_2, 0, 0);
+ memset (p0_1_2, 0, 1);
+ memset (p0_1_2, 0, 2);
+ memset (p0_1_2, 0, 3); // { dg-warning "memset' writing 3 bytes into a region of size 2 " }
+ memset (p0_1_2, 0, 9); // { dg-warning "memset' writing 9 bytes into a region of size 2 " }
+ }
+
+ {
+ char *p0_2_x = CHOOSE_MALLOC_3 (0, 2, x);
+
+ memset (p0_2_x, 0, 0);
+ memset (p0_2_x, 0, 1);
+ memset (p0_2_x, 0, 3);
+ memset (p0_2_x, 0, 9);
+ }
+
+ {
+ char *p3_4_5 = CHOOSE_MALLOC_3 (3, 4, 5);
+
+ memset (p3_4_5, 0, 3);
+ memset (p3_4_5, 0, 4);
+ memset (p3_4_5, 0, 5);
+ memset (p3_4_5, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p5_3_4 = CHOOSE_MALLOC_3 (5, 3, 4);
+
+ memset (p5_3_4, 0, 3);
+ memset (p5_3_4, 0, 4);
+ memset (p5_3_4, 0, 5);
+ memset (p5_3_4, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char *p9_8_7 = CHOOSE_MALLOC_3 (9, 8, 7);
+
+ memset (p9_8_7, 0, 7);
+ memset (p9_8_7, 0, 8);
+ memset (p9_8_7, 0, 9);
+ memset (p9_8_7, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9 " }
+ }
+}
+
+
+/* Verify conditionally writing into one of two objects with the same
+ size. */
+
+void memset_malloc_2_same_size (int i)
+{
+ {
+ char a4_1[4], a4_2[4];
+ char *p4 = cond1 ? a4_1 : a4_2;
+
+ memset (p4, 0, 1);
+ memset (p4, 0, 2);
+ memset (p4, 0, 3);
+ memset (p4, 0, 4);
+ memset (p4, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ char a4_1[4]; // { dg-message "destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 5); // { dg-warning "memset' writing 5 bytes into a region of size 4" }
+ }
+
+ {
+ if (i < 1)
+ i = 1;
+
+ char a4_1[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_1" "note" }
+ char a4_2[4]; // { dg-message "at offset \\\[1, 4] into destination object 'a4_2" "note" }
+ char *p4 = cond1 ? a4_1 : a4_2;
+ char *p4_i = p4 + i;
+
+ memset (p4_i, 0, 3);
+ memset (p4_i, 0, 4); // { dg-warning "memset' writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void memset_malloc_2_off (void)
+{
+ int i1 = SR (1, INT_MAX);
+ int i2 = SR (2, INT_MAX);
+
+ {
+ char a5[5]; // { dg-warning "at offset [1, 5] into destination object 'a5'
+ char a7[7]; // { dg-warning "at offset [2, 7] into destination object 'a7'
+ char *p5_p1 = a5 + i1;
+ char *p7_p2 = a7 + i2;
+ char *p5_7 = cond1 ? p5_p1 : p7_p2;
+
+ memset (p5_7, 0, 1);
+ memset (p5_7, 0, 2);
+ memset (p5_7, 0, 3);
+ memset (p5_7, 0, 4);
+ memset (p5_7, 0, 5);
+ memset (p5_7, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5 " }
+ }
+
+ int i3 = SR (3, INT_MAX);
+
+ {
+ char a5[5];
+ // { dg-message "at offset \\\[3, 5] into destination object 'a5'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[2, 5] into destination object 'a5'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[1, 5] into destination object 'a5'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a5'" "note" { target *-*-* } .-4 }
+ char a9[9];
+ // { dg-message "at offset \\\[4, 9] into destination object 'a9'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset \\\[3, 9] into destination object 'a9'" "note" { target *-*-* } .-2 }
+ // { dg-message "at offset \\\[2, 9] into destination object 'a9'" "note" { target *-*-* } .-3 }
+ // { dg-message ": destination object 'a9'" "note" { target *-*-* } .-4 }
+ char *p5_p2 = a5 + i2; // 3 bytes left
+ char *p9_p3 = a9 + i3; // 6 bytes left
+ char *p =
+ cond1 ? p5_p2 : p9_p3; // [3 - 6] bytes left
+ char *q = p + i1; // [2 - 5] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "memset' writing 6 bytes into a region of size 5" }
+
+ --q; // [3 - 6] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "memset' writing 7 bytes into a region of size 6" }
+
+ --q; // [4 - 7] bytes left
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "memset' writing 8 bytes into a region of size 7" }
+
+ int m1_x = SR (-1, INT_MAX);
+ int m2_x = SR (-2, INT_MAX);
+
+ q += cond2 ? m1_x : m2_x; // [5 - 9] bytes left
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5);
+ memset (q, 0, 6);
+ memset (q, 0, 7);
+ memset (q, 0, 8);
+ memset (q, 0, 9);
+ memset (q, 0, 10); // { dg-warning "memset' writing 10 bytes into a region of size 9" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c
new file mode 100644
index 0000000..8c9de20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-60.c
@@ -0,0 +1,72 @@
+/* Test derived from Glibc's getifaddrs_internal. The code could be
+ rewritten to avoid the warning for the memcpy call but since unions
+ are designed to have their members treated as interchangeable there
+ isn't a whole lot to be gained from issuing one.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+extern void* memcpy (void*, const void*, size_t);
+
+struct sockaddr
+{
+ short sa_family;
+ char sa_data[14];
+};
+
+struct in_addr
+{
+ int s_addr;
+};
+
+struct in6_addr
+{
+ union
+ {
+ char __u6_addr8[16];
+ short __u6_addr16[8];
+ int __u6_addr32[4];
+ } __in6_u;
+};
+
+struct sockaddr_in
+{
+ short sin_family;
+ short sin_port;
+ struct in_addr sin_addr;
+ unsigned char sin_zero[sizeof (struct sockaddr) -
+ (sizeof (short)) -
+ sizeof (short) -
+ sizeof (struct in_addr)];
+};
+
+struct sockaddr_in6
+{
+ short sin6_family;
+ short sin6_port;
+ int sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ int sin6_scope_id;
+};
+
+union
+{
+ struct sockaddr sa;
+ struct sockaddr_in s4;
+ struct sockaddr_in6 s6;
+} u1, u2;
+
+struct sockaddr *sa;
+
+void test_unconditional (void *p)
+{
+ sa = &u1.sa;
+ memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
+}
+
+void test_conditional (void *p, int i)
+{
+ sa = i ? &u1.sa : &u2.sa;
+ memcpy (&((struct sockaddr_in6 *) sa)->sin6_addr, p, 16);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
new file mode 100644
index 0000000..7601679
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-61.c
@@ -0,0 +1,88 @@
+/* { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void* memcpy (void*, const void*, size_t);
+size_t strlen (const char *);
+
+// Test case reduced from gcc/attribs.c.
+
+char* sorted_attr_string (char *argv[])
+{
+ size_t n = 0;
+ unsigned int i;
+
+ for (i = 0; argv[i]; ++i)
+ n += strlen (argv[i]);
+
+ char *s = (char*)malloc (n);
+ n = 0;
+ for (i = 0; argv[i]; ++i)
+ {
+ const char *str = argv[i];
+ size_t len = strlen (str);
+ memcpy (s + n, str, len);
+ n += len + 1;
+ }
+
+ /* Replace "=,-" with "_". */
+ for (i = 0; i < strlen (s); i++)
+ if (s[i] == '=')
+ s[i] = '_'; // { dg-bogus "\\\[-Wstringop-overflow" }
+
+ return s;
+}
+
+
+void f (void*);
+
+void nowarn_cond_escape (int c, int *x)
+{
+ extern char a3[3], a5[5];
+
+ char *p;
+ if (c)
+ {
+ p = a3;
+ *x = 2;
+ }
+ else
+ {
+ p = a5;
+ *x = 4;
+ }
+
+ f (p); // may modify *x
+
+ if (*x == 2)
+ p[2] = 0;
+ else if (*x == 4)
+ p[4] = 0; // { dg-bogus "\\\[-Wstringop-overflow" }
+}
+
+void warn_cond_escape (int c, int *x)
+{
+ extern char a3_2[3];
+ extern char a5_2[5]; // { dg-message "at offset 5 into destination object 'a5_2'" }
+
+ char *p;
+ if (c)
+ {
+ p = a3_2;
+ *x = 2;
+ }
+ else
+ {
+ p = a5_2;
+ *x = 5;
+ }
+
+ f (p); // may modify *x
+
+ if (*x == 2)
+ p[2] = 0;
+ else if (*x == 5)
+ p[5] = 0; // { dg-warning "\\\[-Wstringop-overflow" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c
new file mode 100644
index 0000000..318d9bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-62.c
@@ -0,0 +1,363 @@
+/* Test for MIN and MAX expressions involving pointers.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
+#define MAX(x, y) ((x) < (y) ? (y) : (x))
+
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void*, int, size_t);
+#define memset(...) sink (memset (__VA_ARGS__))
+
+void sink (void*, ...);
+
+volatile int cond, vi;
+char* volatile ptr;
+
+void test_min (void)
+{
+ const int i1 = SR (1, INT_MAX);
+ const int i2 = SR (2, INT_MAX);
+
+ {
+ /* Exercise both pointers pointing to a different unknown object plus
+ positive constant offset. Since PTR is volatile P1 and P2 cannot
+ normally be considered to point to the same object. It can only
+ be inferred from the MIN expression. */
+ char *p1 = ptr + 1;
+ char *p2 = ptr + 2;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, INT_MAX);
+ // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
+ memset (q, 0, DIFF_MAX - 2);
+ memset (q, 0, DIFF_MAX);
+ // { dg-warning "writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 }
+ // { dg-warning "writing 9223372036854775807 bytes into a region of size 9223372036854775806" "lp64" { target lp64 } .-2 }
+ }
+
+ {
+ /* Exercise both pointers pointing to a different unknown object plus
+ variable offset. */
+ char *p1 = ptr + vi;
+ char *p2 = ptr + vi;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, INT_MAX);
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus constant
+ offset. */
+ char a2[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
+ char *p1 = a2 + 1;
+ char *p2 = a2 + 2;
+
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 1 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus offset
+ in a known range. */
+ char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
+ char *pi = a3 + i1;
+ char *pj = a3 + i2;
+
+ char *q = MIN (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus variable
+ offset. Verify that no offset is mentioned in the note (since
+ its unknown, printing its full range is unnecessary). */
+ char a4[4]; // { dg-message ": destination object 'a4'" "note" }
+ char *pi = a4 + vi;
+ char *pj = a4 + vi;
+
+ char *q = MIN (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object. */
+ char a5[5]; // { dg-message ": destination object 'a5'" "note" }
+ char *p = ptr;
+ char *q = MIN (p, a5);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object. */
+ char a6[6]; // { dg-message ": destination object 'a6'" "note" }
+ char *p1 = ptr;
+ char *p2 = a6 + 1;
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object plus constant offset. */
+ char a7[7]; // { dg-message ": destination object 'a7'" "note" }
+ char *p1 = a7;
+ char *p2 = ptr + 1;
+ /* Since p1 points to a7[0] it must be less than any pointer to a7
+ plus positive offset, and so Q == P1. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object plus a different constant
+ offset. */
+ char a8[8]; // { dg-message "at offset 1 into destination object 'a8'" "note" }
+ char *p1 = a8 + 1;
+ char *p2 = ptr + 2;
+ /* Since P1 points to A8[1] it must be less than or equal to any
+ pointer to A8 plus positive offset. Either way, Q must point
+ to A8[1]. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 7);
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 7 " }
+ }
+
+ {
+ /* Same as above but with larger offsets. */
+ char a9[9]; // { dg-message "at offset 3 into destination object 'a9'" "note" }
+ char *p1 = a9 + 3;
+ char *p2 = ptr + 4;
+ /* Since P1 points to A9[3] it must be less than or equal to any
+ pointer anywhere into A9 plus 4, so Q must point to A9[3]. */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Same as above but with the offsets reversed. */
+ char a10[10]; // { dg-message "at offset 5 into destination object 'a10'" "note" }
+ char *p1 = a10 + 10;
+ char *p2 = ptr + 5;
+ /* Since P1 points just past the end of A10 it could be either less
+ or equal to another pointer anywhere into A10 plus 3 because
+ the other pointer itself could start at a non-zero offset that's
+ not reflected in the determined offset). */
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ char a3[3]; // { dg-message ": destination object 'a3'" "note" }
+ char *p1 = ptr;
+ char *p2 = a3 + i1;
+ char *q = MIN (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4); // { dg-warning "writing 4 bytes into a region of size 3 " }
+ }
+}
+
+
+void test_max (void)
+{
+ const int i1 = SR (1, INT_MAX);
+ const int i2 = SR (2, INT_MAX);
+
+ {
+ /* Exercise both pointers pointing to the same object plus constant
+ offset. */
+ char a2[2]; // { dg-message "at offset 1 into destination object 'a2' of size 2" "note" }
+ char *pi = a2 + 1;
+ char *pj = a2 + 2;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2); // { dg-warning "writing 2 bytes into a region of size 1 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus offset
+ in a known range. */
+ char a3[3]; // { dg-message "at offset \\\[1, 3] into destination object 'a3'" "note" }
+ char *pi = a3 + i1;
+ char *pj = a3 + i2;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ }
+
+ {
+ /* Exercise both pointers pointing to the same object plus variable
+ offset. Verify that no offset is mentioned in the note (since
+ its unknown, printing its full range is unnecessary). */
+ char a4[4]; // { dg-message ": destination object 'a4'" "note" }
+ char *pi = a4 + vi;
+ char *pj = a4 + vi;
+
+ char *q = MAX (pi, pj);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 3);
+ memset (q, 0, 4);
+ memset (q, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object. */
+ char a5[5]; // { dg-message ": destination object 'a5'" "note" }
+ char *p = ptr;
+ char *q = MAX (p, a5);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object. */
+ char a6[6]; // { dg-message "at offset 1 into destination object 'a6'" "note" }
+ char *p1 = ptr;
+ char *p2 = a6 + 1;
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object with one pointing
+ to an unknown object plus constant offset. */
+ char a7[7]; // { dg-message "at offset 1 into destination object 'a7'" "note" }
+ char *p1 = a7;
+ char *p2 = ptr + 1;
+ /* Since p1 points to a7[0] it must be less than any pointer to a7
+ plus positive offset, and so Q == P2. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Exercise a pointer pointing to a known object plus constant offset
+ with one pointing to an unknown object plus a different constant
+ offset. */
+ char a8[8]; // { dg-message "at offset 2 into destination object 'a8'" "note" }
+ char *p1 = a8 + 1;
+ char *p2 = ptr + 2;
+ /* Since P1 points to A8[1] it must be less than or equal to any
+ pointer to A8 plus positive offset. Either way, Q must point
+ to A8[2]. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 6);
+ memset (q, 0, 7); // { dg-warning "writing 7 bytes into a region of size 6 " }
+ memset (q, 0, 8); // { dg-warning "writing 8 bytes into a region of size 6 " }
+ }
+
+ {
+ /* Same as above but with larger offsets. */
+ char a9[9]; // { dg-message "at offset 4 into destination object 'a9'" "note" }
+ char *p1 = a9 + 3;
+ char *p2 = ptr + 4;
+ /* Since P1 points to A9[3] it must be less than or equal to any
+ pointer anywhere into A9 plus 4, so Q must point to A9[4]. */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 5);
+ memset (q, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ }
+
+ {
+ /* Same as above but with the offsets reversed. */
+ char a10[10]; // { dg-message "at offset 10 into destination object 'a10'" "note" }
+ char *p1 = a10 + 10;
+ char *p2 = ptr + 5;
+ /* Since P1 points just past the end of A10 it could be either less
+ or equal to another pointer anywhere into A10 plus 3 because
+ the other pointer itself could start at a non-zero offset that's
+ not reflected in the determaxed offset). */
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1); // { dg-warning "writing 1 byte into a region of size 0 " }
+ }
+
+ {
+ char a11[11]; // { dg-message "at offset \\\[1, 11] into destination object 'a11'" "note" }
+ char *p1 = ptr;
+ char *p2 = a11 + i1;
+ char *q = MAX (p1, p2);
+
+ memset (q, 0, 1);
+ memset (q, 0, 2);
+ memset (q, 0, 10);
+ memset (q, 0, 11); // { dg-warning "writing 11 bytes into a region of size 10 " }
+ }
+}
+
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c
new file mode 100644
index 0000000..c98721d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-63.c
@@ -0,0 +1,33 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ Test case derived from gcc/opts-common.c.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+char* f (const void*, ...);
+
+const char *
+candidates_list_and_hint (const char *arg, char **str, const char *a[])
+{
+ size_t len = 0;
+ int i;
+
+ for (i = 0; a[i]; ++i)
+ len += __builtin_strlen (a[i]) + 1;
+
+ char *p = (char*)__builtin_malloc (len);
+ *str = p;
+
+ for (i = 0; a[i]; ++i)
+ {
+ len = __builtin_strlen (a[i]);
+ __builtin_memcpy (p, a[i], len);
+ p[len] = ' ';
+ p += len + 1;
+ }
+
+ p[-1] = '\0'; // { dg-bogus "\\\[-Wstringop-overflow" }
+
+ return f (arg, &a);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c
new file mode 100644
index 0000000..88b9d29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-64.c
@@ -0,0 +1,74 @@
+/* PR middle-end/92936 - missing warning on a past-the-end store to a PHI
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void* memset (void*, int, size_t);
+
+extern char a3[3], a5[5], a9[9];
+
+extern int cnd[];
+
+void* f2 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : p0;
+
+ return memset (p1, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p0 : p1;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3_2 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p1 : p0;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f3_3 (void)
+{
+ char *p0 = cnd[0] ? a5 : 0;
+ char *p1 = cnd[1] ? p0 : a5;
+ char *p2 = cnd[2] ? p1 : p0;
+
+ return memset (p2, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f4 (void)
+{
+ char *p0 = cnd[0] ? a3 : 0;
+ char *p1 = cnd[1] ? a5 : 0;
+ char *p2 = cnd[2] ? p0 : 0;
+ char *p3 = cnd[3] ? p1 : p2;
+
+ return memset (p3, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
+
+void* f9 (void)
+{
+ char *p0 = cnd[0] ? a5 : 0;
+ char *p1 = cnd[1] ? a5 + 1 : 0;
+ char *p2 = cnd[2] ? a5 + 2 : 0;
+ char *p3 = cnd[3] ? a5 + 3 : 0;
+ char *p4 = cnd[4] ? a5 + 4 : 0;
+
+ char *p5 = cnd[5] ? p0 : p1;
+ char *p6 = cnd[6] ? p5 : p2;
+ char *p7 = cnd[7] ? p6 : p3;
+ char *p8 = cnd[8] ? p7 : p4;
+ char *p9 = cnd[9] ? p8 : p5;
+
+ return memset (p9, 0, 6); // { dg-warning "writing 6 bytes into a region of size 5" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c
new file mode 100644
index 0000000..cb2addf3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-7.c
@@ -0,0 +1,124 @@
+/* Test to verify that --param ssa_name_def_chain_limit can be used to
+ limit the maximum number of SSA_NAME assignments the warning follows.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds --param ssa-name-def-chain-limit=5" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void* memset (void*, int, __SIZE_TYPE__);
+
+char a9[9];
+
+void sink (const char*, ...);
+
+NOIPA void g2 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+
+ sink (p0, p1, p2);
+
+ memset (p2, 0, 8); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g3 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+
+ sink (p0, p1, p2, p3);
+
+ memset (p3, 0, 7); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g4 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+
+ sink (p0, p1, p2, p3, p4);
+
+ memset (p4, 0, 6); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g5 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+
+ sink (p0, p1, p2, p3, p4, p5);
+
+ memset (p5, 0, 5); // { dg-warning "\\\[-Wstringop-overflow" }
+}
+
+NOIPA void g6 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6);
+
+ memset (p6, 0, 4);
+}
+
+NOIPA void g7 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+ char *p7 = p6 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6, p7);
+
+ memset (p7, 0, 4);
+}
+
+NOIPA void g8 (int i)
+{
+ if (i < 1) i = 1;
+
+ char *p0 = a9;
+ char *p1 = p0 + i;
+ char *p2 = p1 + i;
+ char *p3 = p2 + i;
+ char *p4 = p3 + i;
+ char *p5 = p4 + i;
+ char *p6 = p5 + i;
+ char *p7 = p6 + i;
+ char *p8 = p7 + i;
+
+ sink (p0, p1, p2, p3, p4, p5, p6, p7, p8);
+
+ memset (p8, 0, 2);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c b/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c
new file mode 100644
index 0000000..08e5272
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/invalid-shift-1.c
@@ -0,0 +1,34 @@
+/* PR tree-optimization/97424. */
+
+#include <stdint.h>
+
+static inline uint32_t
+_dl_hwcaps_subdirs_build_bitmask (int subdirs, int active)
+{
+ /* Leading subdirectories that are not active. */
+ int inactive = subdirs - active;
+ if (inactive == 32)
+ return 0;
+
+ uint32_t mask;
+ if (subdirs != 32)
+ mask = (1 << subdirs) - 1; /* { dg-message "shift by count \\('33'\\) >= precision of type \\('\[0-9\]+'\\)" } */
+ else
+ mask = -1;
+ return mask ^ ((1U << inactive) - 1); /* { dg-message "shift by negative count \\('-1'\\)" } */
+}
+
+void f1 (int);
+
+void
+f2 (void)
+{
+ f1 (_dl_hwcaps_subdirs_build_bitmask (1, 2));
+ f1 (_dl_hwcaps_subdirs_build_bitmask (33, 31));
+}
+
+static int __attribute__((noinline)) op3 (int op, int c) { return op << c; } /* { dg-message "shift by negative count \\('-1'\\)" } */
+int test_3 (void) { return op3 (1, -1); }
+
+static int __attribute__((noinline)) op4 (int op, int c) { return op << c; }
+int test_4 (void) { return op4 (1, 0); }
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index 38ce1a5..c5bf1227c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -30,14 +30,14 @@ void test_2a (void *ptr)
int *test_3 (void)
{
int *ptr = (int *)malloc (sizeof (int));
- *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
int *test_3a (void)
{
int *ptr = (int *)__builtin_malloc (sizeof (int));
- *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ *ptr = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
@@ -47,7 +47,7 @@ int *test_4 (void)
if (ptr)
*ptr = 42;
else
- *ptr = 43; /* { dg-warning "dereference of NULL 'ptr'" } */
+ *ptr = 43; /* { dg-warning "dereference of NULL 'ptr' \\\[CWE-476\\\]" } */
return ptr;
}
@@ -260,14 +260,14 @@ void test_22 (void)
int *test_23 (int n)
{
int *ptr = (int *)calloc (n, sizeof (int));
- ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
int *test_23a (int n)
{
int *ptr = (int *)__builtin_calloc (n, sizeof (int));
- ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr'" } */
+ ptr[0] = 42; /* { dg-warning "dereference of possibly-NULL 'ptr' \\\[CWE-690\\\]" } */
return ptr;
}
@@ -302,7 +302,7 @@ struct coord {
struct coord *test_27 (void)
{
struct coord *p = (struct coord *) malloc (sizeof (struct coord)); /* { dg-message "this call could return NULL" } */
- p->x = 0.f; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ p->x = 0.f; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
/* Only the first such usage should be reported: */
p->y = 0.f;
@@ -313,7 +313,7 @@ struct coord *test_27 (void)
struct coord *test_28 (void)
{
struct coord *p = NULL;
- p->x = 0.f; /* { dg-warning "dereference of NULL 'p'" } */
+ p->x = 0.f; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
/* Only the first such usage should be reported: */
p->y = 0.f;
@@ -416,7 +416,7 @@ void test_36 (void)
void *test_37a (void)
{
void *ptr = malloc(4096); /* { dg-message "this call could return NULL" } */
- __builtin_memset(ptr, 0, 4096); /* { dg-warning "use of possibly-NULL 'ptr' where non-null expected" } */
+ __builtin_memset(ptr, 0, 4096); /* { dg-warning "use of possibly-NULL 'ptr' where non-null expected \\\[CWE-690\\\]" } */
return ptr;
}
@@ -427,7 +427,7 @@ int test_37b (void)
if (p) {
__builtin_memset(p, 0, 4096); /* Not a bug: checked */
} else {
- __builtin_memset(q, 0, 4096); /* { dg-warning "use of possibly-NULL 'q' where non-null expected" } */
+ __builtin_memset(q, 0, 4096); /* { dg-warning "use of possibly-NULL 'q' where non-null expected \\\[CWE-690\\\]" } */
}
free(p);
free(q);
@@ -452,7 +452,7 @@ int *
test_39 (int i)
{
int *p = (int*)malloc(sizeof(int*)); /* { dg-message "this call could return NULL" } */
- *p = i; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ *p = i; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
return p;
}
@@ -460,7 +460,7 @@ int *
test_40 (int i)
{
int *p = (int*)malloc(sizeof(int*));
- i = *p; /* { dg-warning "dereference of possibly-NULL 'p'" } */
+ i = *p; /* { dg-warning "dereference of possibly-NULL 'p' \\\[CWE-690\\\]" } */
/* TODO: (it's also uninitialized) */
return p;
}
@@ -476,8 +476,8 @@ test_41 (int flag)
buffer = NULL;
}
- buffer[0] = 'a'; /* { dg-warning "dereference of possibly-NULL 'buffer'" "possibly-NULL" } */
- /* { dg-warning "dereference of NULL 'buffer'" "NULL" { target *-*-* } .-1 } */
+ buffer[0] = 'a'; /* { dg-warning "dereference of possibly-NULL 'buffer' \\\[CWE-690\\\]" "possibly-NULL" } */
+ /* { dg-warning "dereference of NULL 'buffer' \\\[CWE-476\\\]" "NULL" { target *-*-* } .-1 } */
return buffer;
}
@@ -594,7 +594,7 @@ int test_47 (void)
void test_48 (void)
{
int *p = NULL; /* { dg-message "'p' is NULL" } */
- *p = 1; /* { dg-warning "dereference of NULL 'p'" } */
+ *p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
}
/* As test_48, but where the assignment of NULL is not at the start of a BB. */
@@ -606,6 +606,6 @@ int test_49 (int i)
x = i * 2;
p = NULL; /* { dg-message "'p' is NULL" } */
- *p = 1; /* { dg-warning "dereference of NULL 'p'" } */
+ *p = 1; /* { dg-warning "dereference of NULL 'p' \\\[CWE-476\\\]" } */
return x;
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
index bf5b9bf..4787fa3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
@@ -51,18 +51,25 @@ void outer (void)
| | |
| | (4) 'setjmp' called here
|
+ 'inner': event 5
+ |
+ | NN | }
+ | | ^
+ | | |
+ | | (5) stack frame is popped here, invalidating saved environment
+ |
<------+
|
- 'outer': events 5-6
+ 'outer': events 6-7
|
| NN | inner ();
| | ^~~~~~~~
| | |
- | | (5) returning to 'outer' from 'inner'
+ | | (6) returning to 'outer' from 'inner'
| NN |
| NN | longjmp (env, 42);
| | ~~~~~~~~~~~~~~~~~
| | |
- | | (6) here
+ | | (7) 'longjmp' called after enclosing function of 'setjmp' returned at (5)
|
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/array-quals-1.c b/gcc/testsuite/gcc.dg/array-quals-1.c
index 3981c91..31aa1d3 100644
--- a/gcc/testsuite/gcc.dg/array-quals-1.c
+++ b/gcc/testsuite/gcc.dg/array-quals-1.c
@@ -6,26 +6,46 @@
/* { dg-options "-Wno-discarded-array-qualifiers" } */
/* The MMIX port always switches to the .data section at the end of a file. */
/* { dg-final { scan-assembler-not "\\.data(?!\\.rel\\.ro)" { xfail powerpc*-*-aix* mmix-*-* x86_64-*-mingw* } } } */
+/* { dg-final { scan-assembler-symbol-section {^_?a$} {^\.(const|rodata)|\[RO\]} } } */
static const int a[2] = { 1, 2 };
+/* { dg-final { scan-assembler-symbol-section {^_?a1$} {^\.(const|rodata)|\[RO\]} } } */
const int a1[2] = { 1, 2 };
typedef const int ci;
+/* { dg-final { scan-assembler-symbol-section {^_?b$} {^\.(const|rodata)|\[RO\]} } } */
static ci b[2] = { 3, 4 };
+/* { dg-final { scan-assembler-symbol-section {^_?b1$} {^\.(const|rodata)|\[RO\]} } } */
ci b1[2] = { 3, 4 };
typedef int ia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?c$} {^\.(const|rodata)|\[RO\]} } } */
static const ia c = { 5, 6 };
+/* { dg-final { scan-assembler-symbol-section {^_?c1$} {^\.(const|rodata)|\[RO\]} } } */
const ia c1 = { 5, 6 };
typedef const int cia[2];
+/* { dg-final { scan-assembler-symbol-section {^_?d$} {^\.(const|rodata)|\[RO\]} } } */
static cia d = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?d1$} {^\.(const|rodata)|\[RO\]} } } */
cia d1 = { 7, 8 };
+/* { dg-final { scan-assembler-symbol-section {^_?e$} {^\.(const|rodata)|\[RO\]} } } */
static cia e[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?e1$} {^\.(const|rodata)|\[RO\]} } } */
cia e1[2] = { { 1, 2 }, { 3, 4 } };
+/* { dg-final { scan-assembler-symbol-section {^_?p$} {^\.(const|rodata)|\[RW\]} } } */
void *const p = &a;
+/* { dg-final { scan-assembler-symbol-section {^_?q$} {^\.(const|rodata)|\[RW\]} } } */
void *const q = &b;
+/* { dg-final { scan-assembler-symbol-section {^_?r$} {^\.(const|rodata)|\[RW\]} } } */
void *const r = &c;
+/* { dg-final { scan-assembler-symbol-section {^_?s$} {^\.(const|rodata)|\[RW\]} } } */
void *const s = &d;
+/* { dg-final { scan-assembler-symbol-section {^_?t$} {^\.(const|rodata)|\[RW\]} } } */
void *const t = &e;
+/* { dg-final { scan-assembler-symbol-section {^_?p1$} {^\.(const|rodata)|\[RW\]} } } */
void *const p1 = &a1;
+/* { dg-final { scan-assembler-symbol-section {^_?q1$} {^\.(const|rodata)|\[RW\]} } } */
void *const q1 = &b1;
+/* { dg-final { scan-assembler-symbol-section {^_?r1$} {^\.(const|rodata)|\[RW\]} } } */
void *const r1 = &c1;
+/* { dg-final { scan-assembler-symbol-section {^_?s1$} {^\.(const|rodata)|\[RW\]} } } */
void *const s1 = &d1;
+/* { dg-final { scan-assembler-symbol-section {^_?t1$} {^\.(const|rodata)|\[RW\]} } } */
void *const t1 = &e1;
diff --git a/gcc/testsuite/gcc.dg/attr-access-3.c b/gcc/testsuite/gcc.dg/attr-access-3.c
new file mode 100644
index 0000000..45dd1aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-3.c
@@ -0,0 +1,21 @@
+/* PR middle-end/97879 - ICE on invalid mode in attribute access
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define A(...) __attribute__ ((access (__VA_ARGS__)))
+
+A (" ", 1) void f1 (int *); // { dg-error "attribute 'access' mode '\" \"' is not an identifier; expected one of 'read_only', 'read_write', 'write_only', or 'none'" }
+ void f1 (int *);
+
+
+A ("none", 1) void f2 (char *); // { dg-error "not an identifier" }
+ void f2 (char *);
+
+A (1) void f3 (); // { dg-error "not an identifier" }
+
+A (1, 2) void f4 (); // { dg-error "not an identifier" }
+A (2., 3.) void f5 (); // { dg-error "not an identifier" }
+
+// Verify that copying a valid access attribute doesn't cause errors.
+A (read_only, 1, 2) void f6 (void*, int);
+__attribute__ ((copy (f6))) void f7 (void*, int);
diff --git a/gcc/testsuite/gcc.dg/attr-access-4.c b/gcc/testsuite/gcc.dg/attr-access-4.c
new file mode 100644
index 0000000..7a2870a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-4.c
@@ -0,0 +1,8 @@
+/* PR middle-end/97861 - ICE on an invalid redeclaration of a function
+ with attribute access
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+__attribute__ ((access (read_only, 2)))
+void f (int, int*);
+void f (int a) { } // { dg-error "conflicting types for 'f'" }
diff --git a/gcc/testsuite/gcc.dg/attr-access-5.c b/gcc/testsuite/gcc.dg/attr-access-5.c
new file mode 100644
index 0000000..e78b360
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-5.c
@@ -0,0 +1,16 @@
+/* { dg-do compile }
+ { dg-options "-fdump-tree-gimple" } */
+
+__attribute__ ((aligned (32)))
+__attribute__ ((access (write_only, 2, 1)))
+void f (int n, void *p)
+{
+ __builtin_memset (p, 0, n);
+}
+
+/* Verify the DECL_ATTRIBUTE "aligned" is mentioned:
+ { dg-final { scan-tree-dump "__attribute__\\(\\(aligned" "gimple" } }
+ and the TYPE_ATTRIBUTE "access" is also mentioned:
+ { dg-final { scan-tree-dump "__attribute__\\(\\(access" "gimple" } }
+ and the function signature including its return type is mentioned:
+ { dg-final { scan-tree-dump "void f *\\(int n, void *\\* *p\\)" "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/binary-constants-2.c b/gcc/testsuite/gcc.dg/binary-constants-2.c
index 6c3928a..5339d57 100644
--- a/gcc/testsuite/gcc.dg/binary-constants-2.c
+++ b/gcc/testsuite/gcc.dg/binary-constants-2.c
@@ -9,8 +9,8 @@
int
foo (void)
{
-#if FOO /* { dg-warning "binary constants are a GCC extension" } */
+#if FOO /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
return 23;
#endif
- return 0b1101; /* { dg-warning "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/binary-constants-3.c b/gcc/testsuite/gcc.dg/binary-constants-3.c
index 410fc4c..5b49cb4 100644
--- a/gcc/testsuite/gcc.dg/binary-constants-3.c
+++ b/gcc/testsuite/gcc.dg/binary-constants-3.c
@@ -9,8 +9,8 @@
int
foo (void)
{
-#if FOO /* { dg-error "binary constants are a GCC extension" } */
+#if FOO /* { dg-error "binary constants are a C2X feature or GCC extension" } */
return 23;
#endif
- return 0b1101; /* { dg-error "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-error "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
new file mode 100644
index 0000000..ab7d82a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-4.c
@@ -0,0 +1,43 @@
+/* PR c/90628 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+_Atomic int a = 1, b = 2, c = 3;
+_Atomic long d = 4, e = 5, f = 6;
+_Atomic long long g = 7, h = 8, i = 9;
+
+void
+f1 ()
+{
+ __builtin_add_overflow (a, b, &c); /* { dg-error "argument 3 in call to function '__builtin_add_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f2 ()
+{
+ __builtin_sub_overflow (d, e, &f); /* { dg-error "argument 3 in call to function '__builtin_sub_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f3 ()
+{
+ __builtin_mul_overflow (g, h, &i); /* { dg-error "argument 3 in call to function '__builtin_mul_overflow' has pointer to '_Atomic' type" } */
+}
+
+void
+f4 ()
+{
+ __builtin_sadd_overflow (a, b, &c); /* { dg-warning "passing argument 3 of '__builtin_sadd_overflow' from incompatible pointer type" } */
+}
+
+void
+f5 ()
+{
+ __builtin_ssubl_overflow (d, e, &f); /* { dg-warning "passing argument 3 of '__builtin_ssubl_overflow' from incompatible pointer type" } */
+}
+
+void
+f6 ()
+{
+ __builtin_smulll_overflow (g, h, &i); /* { dg-warning "passing argument 3 of '__builtin_smulll_overflow' from incompatible pointer type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c b/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c
new file mode 100644
index 0000000..b43fd18
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-arith-overflow-5.c
@@ -0,0 +1,87 @@
+/* PR rtl-optimization/95862 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+f1 (int a, int b)
+{
+ unsigned long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f2 (int a, unsigned b)
+{
+ unsigned long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f3 (unsigned a, unsigned b)
+{
+ long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+int
+f4 (int a, unsigned b)
+{
+ long long c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f5 (short a, short b)
+{
+ unsigned c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f6 (short a, unsigned short b)
+{
+ unsigned c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f7 (unsigned short a, unsigned short b)
+{
+ int c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+short
+f8 (short a, unsigned short b)
+{
+ int c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f9 (signed char a, signed char b)
+{
+ unsigned short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f10 (signed char a, unsigned char b)
+{
+ unsigned short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f11 (unsigned char a, unsigned char b)
+{
+ short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
+
+signed char
+f12 (signed char a, unsigned char b)
+{
+ short c;
+ return __builtin_mul_overflow (a, b, &c);
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c b/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c
new file mode 100644
index 0000000..27ffc0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-clear-padding-1.c
@@ -0,0 +1,10 @@
+/* PR libstdc++/88101 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (int n)
+{
+ struct S { char a; int b[n]; long long c; } s;
+ __builtin_clear_padding (&s); /* { dg-message "unimplemented: __builtin_clear_padding not supported for variable length aggregates" } */
+}
diff --git a/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c b/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
new file mode 100644
index 0000000..641d47d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/builtin-clear-padding-2.c
@@ -0,0 +1,15 @@
+/* PR middle-end/97943 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); };
+struct T { int a; struct S b; int c; };
+union U { int a; struct S b; };
+struct V { int a; union U b; int : 15; int c; };
+
+void
+foo (struct T *t, struct V *v)
+{
+ __builtin_clear_padding (t); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+ __builtin_clear_padding (v); /* { dg-error "flexible array member 'b' does not have well defined padding bits for '__builtin_clear_padding'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c11-binary-constants-1.c b/gcc/testsuite/gcc.dg/c11-binary-constants-1.c
new file mode 100644
index 0000000..fdc7df4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-binary-constants-1.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are diagnosed in C11 mode: -pedantic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic" } */
+
+int a = 0b1; /* { dg-warning "binary constants" } */
+#if 0b101 /* { dg-warning "binary constants" } */
+#endif
+
+int b = 0B1; /* { dg-warning "binary constants" } */
+#if 0B101 /* { dg-warning "binary constants" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-binary-constants-2.c b/gcc/testsuite/gcc.dg/c11-binary-constants-2.c
new file mode 100644
index 0000000..6b48a5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-binary-constants-2.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are diagnosed in C11 mode: -pedantic-errors. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int a = 0b1; /* { dg-error "binary constants" } */
+#if 0b101 /* { dg-error "binary constants" } */
+#endif
+
+int b = 0B1; /* { dg-error "binary constants" } */
+#if 0B101 /* { dg-error "binary constants" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
new file mode 100644
index 0000000..b1c05cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-1.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ accepted in C11 mode. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q;
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q;
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q;
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q;
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p;
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p;
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p;
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p;
+}
diff --git a/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
new file mode 100644
index 0000000..8e809e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-compare-incomplete-2.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C11 mode with -Wc99-c11-compat. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors -Wc99-c11-compat" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c11-float-4.c b/gcc/testsuite/gcc.dg/c11-float-4.c
new file mode 100644
index 0000000..ceac6ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-4.c
@@ -0,0 +1,25 @@
+/* Test infinity and NaN macros not defined for C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef INFINITY
+#error "INFINITY defined"
+#endif
+
+#ifdef NAN
+#error "NAN defined"
+#endif
+
+#ifdef FLT_SNAN
+#error "FLT_SNAN defined"
+#endif
+
+#ifdef DBL_SNAN
+#error "DBL_SNAN defined"
+#endif
+
+#ifdef LDBL_SNAN
+#error "LDBL_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-5.c b/gcc/testsuite/gcc.dg/c11-float-5.c
new file mode 100644
index 0000000..bb48695
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-5.c
@@ -0,0 +1,35 @@
+/* Test sNaN macros for _FloatN and _FloatNx not defined for C11 with
+ __STDC_WANT_IEC_60559_TYPES_EXT__. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <float.h>
+
+#ifdef FLT16_SNAN
+#error "FLT16_SNAN defined"
+#endif
+
+#ifdef FLT32_SNAN
+#error "FLT32_SNAN defined"
+#endif
+
+#ifdef FLT64_SNAN
+#error "FLT64_SNAN defined"
+#endif
+
+#ifdef FLT128_SNAN
+#error "FLT128_SNAN defined"
+#endif
+
+#ifdef FLT32X_SNAN
+#error "FLT32X_SNAN defined"
+#endif
+
+#ifdef FLT64X_SNAN
+#error "FLT64X_SNAN defined"
+#endif
+
+#ifdef FLT128X_SNAN
+#error "FLT128X_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-6.c b/gcc/testsuite/gcc.dg/c11-float-6.c
new file mode 100644
index 0000000..b0381e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-6.c
@@ -0,0 +1,17 @@
+/* Test *_IS_IEC_60559 not defined for C11. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+#include <float.h>
+
+#ifdef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 defined"
+#endif
+
+#ifdef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 defined"
+#endif
+
+#ifdef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c11-float-dfp-2.c b/gcc/testsuite/gcc.dg/c11-float-dfp-2.c
new file mode 100644
index 0000000..e63ebbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c11-float-dfp-2.c
@@ -0,0 +1,6 @@
+/* Test DFP macros not defined in <float.h> for C11. Infinity and NaN
+ macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11" } */
+
+#include "c2x-float-no-dfp-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c
new file mode 100644
index 0000000..bbb2bc8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-1.c
@@ -0,0 +1,5 @@
+/* Test C2x binary constants. Valid syntax and types. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include "binary-constants-1.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c
new file mode 100644
index 0000000..4379427
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-2.c
@@ -0,0 +1,11 @@
+/* Test that binary constants are accepted in C2X mode: compat warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -Wc11-c2x-compat" } */
+
+int a = 0b1; /* { dg-warning "C2X feature" } */
+#if 0b101 /* { dg-warning "C2X feature" } */
+#endif
+
+int b = 0B1; /* { dg-warning "C2X feature" } */
+#if 0B101 /* { dg-warning "C2X feature" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c b/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c
new file mode 100644
index 0000000..7604791f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-binary-constants-3.c
@@ -0,0 +1,9 @@
+/* Test C2x binary constants. Invalid constants. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+int a = 0b; /* { dg-error "invalid suffix" } */
+int b = 0B2; /* { dg-error "invalid suffix" } */
+int c = 0B02; /* { dg-error "invalid digit" } */
+int d = 0b1.1; /* { dg-error "invalid prefix" } */
+int e = 0B0p0; /* { dg-error "invalid suffix" } */
diff --git a/gcc/testsuite/gcc.dg/c2x-float-10.c b/gcc/testsuite/gcc.dg/c2x-float-10.c
new file mode 100644
index 0000000..7b53a6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-10.c
@@ -0,0 +1,33 @@
+/* Test *_IS_IEC_60559 macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+
+#ifndef FLT_IS_IEC_60559
+#error "FLT_IS_IEC_60559 undefined"
+#endif
+
+#ifndef DBL_IS_IEC_60559
+#error "DBL_IS_IEC_60559 undefined"
+#endif
+
+#ifndef LDBL_IS_IEC_60559
+#error "LDBL_IS_IEC_60559 undefined"
+#endif
+
+#if defined __pdp11__ || defined __vax__
+_Static_assert (FLT_IS_IEC_60559 == 0);
+_Static_assert (DBL_IS_IEC_60559 == 0);
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (FLT_IS_IEC_60559 == 2);
+_Static_assert (DBL_IS_IEC_60559 == 2);
+#if LDBL_MANT_DIG == 106 || LDBL_MIN_EXP == -16382
+/* IBM long double and m68k extended format do not meet the definition
+ of an IEC 60559 interchange or extended format. */
+_Static_assert (LDBL_IS_IEC_60559 == 0);
+#else
+_Static_assert (LDBL_IS_IEC_60559 == 2);
+#endif
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-2.c b/gcc/testsuite/gcc.dg/c2x-float-2.c
new file mode 100644
index 0000000..4f669fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-2.c
@@ -0,0 +1,23 @@
+/* Test INFINITY macro. Generic test even if infinities not
+ supported. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -w" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+#ifndef INFINITY
+#error "INFINITY undefined"
+#endif
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (INFINITY, float : 0);
+ if (!(INFINITY >= FLT_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-3.c b/gcc/testsuite/gcc.dg/c2x-float-3.c
new file mode 100644
index 0000000..7c6298b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-3.c
@@ -0,0 +1,27 @@
+/* Test INFINITY macro. Test when infinities supported. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target inff } */
+
+#include <float.h>
+
+#ifndef INFINITY
+#error "INFINITY undefined"
+#endif
+
+volatile float f = INFINITY;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (INFINITY, float : 0);
+ if (!(INFINITY > FLT_MAX))
+ abort ();
+ if (!(f > FLT_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-4.c b/gcc/testsuite/gcc.dg/c2x-float-4.c
new file mode 100644
index 0000000..bca8435
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-4.c
@@ -0,0 +1,33 @@
+/* Test NAN macro. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+/* This should be defined if and only if quiet NaNs are supported for
+ type float. If the testsuite gains effective-target support for
+ targets not supporting NaNs, or not supporting them for all types,
+ this test should be split into versions for targets with and
+ without NaNs for float. */
+#ifndef NAN
+#error "NAN undefined"
+#endif
+
+volatile float f = NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (NAN, float : 0);
+ if (!__builtin_isnan (NAN))
+ abort ();
+ if (!__builtin_isnan (f))
+ abort ();
+ if (!__builtin_isnan (f + f))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-5.c b/gcc/testsuite/gcc.dg/c2x-float-5.c
new file mode 100644
index 0000000..477f9cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-5.c
@@ -0,0 +1,32 @@
+/* Test NAN macro. Runtime exceptions test, to verify NaN is quiet
+ not signaling. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+/* { dg-add-options ieee } */
+
+#include <fenv.h>
+#include <float.h>
+
+/* This should be defined if and only if quiet NaNs are supported for
+ type float. If the testsuite gains effective-target support for
+ targets not supporting NaNs, or not supporting them for all types,
+ this test should only be run for targets supporting quiet NaNs for
+ float. */
+#ifndef NAN
+#error "NAN undefined"
+#endif
+
+volatile float f = NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ f += f;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-6.c b/gcc/testsuite/gcc.dg/c2x-float-6.c
new file mode 100644
index 0000000..573540b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-6.c
@@ -0,0 +1,49 @@
+/* Test SNAN macros. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -pedantic-errors -fsignaling-nans" } */
+/* { dg-add-options ieee } */
+
+#include <float.h>
+
+/* These should be defined if and only if signaling NaNs are supported
+ for the given types. If the testsuite gains effective-target
+ support for targets not supporting signaling NaNs, or not
+ supporting them for all types, this test should be made
+ appropriately conditional. */
+#ifndef FLT_SNAN
+#error "FLT_SNAN undefined"
+#endif
+#ifndef DBL_SNAN
+#error "DBL_SNAN undefined"
+#endif
+#ifndef LDBL_SNAN
+#error "LDBL_SNAN undefined"
+#endif
+
+volatile float f = FLT_SNAN;
+volatile double d = DBL_SNAN;
+volatile long double ld = LDBL_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (FLT_SNAN, float : 0);
+ (void) _Generic (DBL_SNAN, double : 0);
+ (void) _Generic (LDBL_SNAN, long double : 0);
+ if (!__builtin_isnan (FLT_SNAN))
+ abort ();
+ if (!__builtin_isnan (f))
+ abort ();
+ if (!__builtin_isnan (DBL_SNAN))
+ abort ();
+ if (!__builtin_isnan (d))
+ abort ();
+ if (!__builtin_isnan (LDBL_SNAN))
+ abort ();
+ if (!__builtin_isnan (ld))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-7.c b/gcc/testsuite/gcc.dg/c2x-float-7.c
new file mode 100644
index 0000000..0c90ff2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-7.c
@@ -0,0 +1,49 @@
+/* Test SNAN macros. Runtime exceptions test, to verify NaN is
+ signaling. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x -pedantic-errors -fsignaling-nans" } */
+/* { dg-add-options ieee } */
+
+#include <fenv.h>
+#include <float.h>
+
+/* These should be defined if and only if signaling NaNs are supported
+ for the given types. If the testsuite gains effective-target
+ support for targets not supporting signaling NaNs, or not
+ supporting them for all types, this test should be made
+ appropriately conditional. */
+#ifndef FLT_SNAN
+#error "FLT_SNAN undefined"
+#endif
+#ifndef DBL_SNAN
+#error "DBL_SNAN undefined"
+#endif
+#ifndef LDBL_SNAN
+#error "LDBL_SNAN undefined"
+#endif
+
+volatile float f = FLT_SNAN;
+volatile double d = DBL_SNAN;
+volatile long double ld = LDBL_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ f += f;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d += d;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ ld += ld;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-float-8.c b/gcc/testsuite/gcc.dg/c2x-float-8.c
new file mode 100644
index 0000000..b10cb85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-8.c
@@ -0,0 +1,7 @@
+/* Test including <math.h> then <float.h> does not result in errors
+ from duplicate NAN and INFINITY macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <math.h>
+#include <float.h>
diff --git a/gcc/testsuite/gcc.dg/c2x-float-9.c b/gcc/testsuite/gcc.dg/c2x-float-9.c
new file mode 100644
index 0000000..0a54bc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-9.c
@@ -0,0 +1,7 @@
+/* Test including <float.h> then <math.h> does not result in errors
+ from duplicate NAN and INFINITY macros. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include <float.h>
+#include <math.h>
diff --git a/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c
new file mode 100644
index 0000000..aa790c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-3.c
@@ -0,0 +1,26 @@
+/* Test DFP macros not defined in <float.h> if no DFP support.
+ Infinity and NaN macros. */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifdef DEC_INFINITY
+# error "DEC_INFINITY defined"
+#endif
+
+#ifdef DEC_NAN
+# error "DEC_NAN defined"
+#endif
+
+#ifdef DEC32_SNAN
+# error "DEC32_SNAN defined"
+#endif
+
+#ifdef DEC64_SNAN
+# error "DEC64_SNAN defined"
+#endif
+
+#ifdef DEC128_SNAN
+# error "DEC128_SNAN defined"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c
new file mode 100644
index 0000000..855922a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-float-no-dfp-4.c
@@ -0,0 +1,10 @@
+/* Test DFP macros not defined in <float.h> if no DFP support.
+ Infinity and NaN macros. Test with feature test macros
+ defined. */
+/* { dg-do compile { target { ! dfp } } } */
+/* { dg-options "-std=c2x" } */
+
+#define __STDC_WANT_DEC_FP__
+#define __STDC_WANT_IEC_60559_DFP_EXT__
+
+#include "c2x-float-no-dfp-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c
new file mode 100644
index 0000000..fe06abf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-1.c
@@ -0,0 +1,28 @@
+/* Test __has_c_attribute. Test basic properties. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#ifdef __has_c_attribute
+/* OK. */
+#else
+#error "__has_c_attribute not defined"
+#endif
+
+#ifndef __has_c_attribute
+#error "__has_c_attribute not defined"
+#endif
+
+#if defined __has_c_attribute
+/* OK. */
+#else
+#error "__has_c_attribute not defined"
+#endif
+
+#if __has_c_attribute(foo)
+#error "foo attribute supported"
+#endif
+
+#if 0
+#elif __has_c_attribute(foo)
+#error "foo attribute supported"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
new file mode 100644
index 0000000..d6c4c6d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-2.c
@@ -0,0 +1,41 @@
+/* Test __has_c_attribute. Test supported attributes. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute ( nodiscard ) != 202003L
+#error "bad result for nodiscard"
+#endif
+
+#if __has_c_attribute ( __nodiscard__ ) != 202003L
+#error "bad result for __nodiscard__"
+#endif
+
+#if __has_c_attribute(maybe_unused) != 201904L
+#error "bad result for maybe_unused"
+#endif
+
+#if __has_c_attribute(__maybe_unused__) != 201904L
+#error "bad result for __maybe_unused__"
+#endif
+
+#if __has_c_attribute (deprecated) != 201904L
+#error "bad result for deprecated"
+#endif
+
+#if __has_c_attribute (__deprecated__) != 201904L
+#error "bad result for __deprecated__"
+#endif
+
+#if __has_c_attribute (fallthrough) != 201904L
+#error "bad result for fallthrough"
+#endif
+
+#if __has_c_attribute (__fallthrough__) != 201904L
+#error "bad result for __fallthrough__"
+#endif
+
+/* Macros in the attribute name are expanded. */
+#define foo deprecated
+#if __has_c_attribute (foo) != 201904L
+#error "bad result for foo"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c
new file mode 100644
index 0000000..36842ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-3.c
@@ -0,0 +1,25 @@
+/* Test __has_c_attribute. Test GNU attributes. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute (gnu::packed) != 1
+#error "bad result for gnu::packed"
+#endif
+
+#if __has_c_attribute (__gnu__::__packed__) != 1
+#error "bad result for __gnu__::__packed__"
+#endif
+
+#if __has_c_attribute (gnu::__packed__) != 1
+#error "bad result for gnu::__packed__"
+#endif
+
+#if __has_c_attribute (__gnu__::packed) != 1
+#error "bad result for __gnu__::packed"
+#endif
+
+/* GNU attributes should not be reported as accepted without a scope
+ specified. */
+#if __has_c_attribute (packed) != 0
+#error "bad result for packed"
+#endif
diff --git a/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c
new file mode 100644
index 0000000..acd35d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c2x-has-c-attribute-4.c
@@ -0,0 +1,18 @@
+/* Test __has_c_attribute. Test syntax errors. */
+/* { dg-do preprocess } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#if __has_c_attribute /* { dg-error "missing '\\('" } */
+#endif
+
+#if __has_c_attribute 0 /* { dg-error "missing '\\('" } */
+#endif
+
+#if __has_c_attribute (0 /* { dg-error "requires an identifier" } */
+#endif
+
+#if __has_c_attribute (x /* { dg-error "missing '\\)'" } */
+#endif
+
+#if __has_c_attribute (x::0) /* { dg-error "required after scope" } */
+#endif
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
new file mode 100644
index 0000000..dfafc39
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-1.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C99 mode: -pedantic. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-warning "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-warning "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
new file mode 100644
index 0000000..5ae7f30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-compare-incomplete-2.c
@@ -0,0 +1,52 @@
+/* Test comparisons of pointers to complete and incomplete types are
+ diagnosed in C99 mode: -pedantic-errors. */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -pedantic-errors" } */
+
+int
+f (int (*p)[], int (*q)[3])
+{
+ return p < q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f2 (int (*p)[], int (*q)[3])
+{
+ return p <= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f3 (int (*p)[], int (*q)[3])
+{
+ return p > q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+f4 (int (*p)[], int (*q)[3])
+{
+ return p >= q; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g (int (*p)[], int (*q)[3])
+{
+ return q < p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g2 (int (*p)[], int (*q)[3])
+{
+ return q <= p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g3 (int (*p)[], int (*q)[3])
+{
+ return q > p; /* { dg-error "complete and incomplete" } */
+}
+
+int
+g4 (int (*p)[], int (*q)[3])
+{
+ return q >= p; /* { dg-error "complete and incomplete" } */
+}
diff --git a/gcc/testsuite/gcc.dg/cond-constqual-1.c b/gcc/testsuite/gcc.dg/cond-constqual-1.c
index 3354c72..b5a09cb 100644
--- a/gcc/testsuite/gcc.dg/cond-constqual-1.c
+++ b/gcc/testsuite/gcc.dg/cond-constqual-1.c
@@ -11,5 +11,5 @@ test (void)
__typeof__ (1 ? foo (0) : 0) texpr;
__typeof__ (1 ? i : 0) texpr2;
texpr = 0; /* { dg-bogus "read-only variable" "conditional expression with call to const function" } */
- texpr2 = 0; /* { dg-error "read-only variable" "conditional expression with const variable" } */
+ texpr2 = 0; /* { dg-bogus "read-only variable" "conditional expression with const variable" } */
}
diff --git a/gcc/testsuite/gcc.dg/cpp/line10.c b/gcc/testsuite/gcc.dg/cpp/line10.c
new file mode 100644
index 0000000..9f5f079
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line10.c
@@ -0,0 +1,5 @@
+/* Test #line overflow checks: bug 97602. */
+/* { dg-do preprocess } */
+/* { dg-options "-pedantic" } */
+
+#line 4294967296 /* { dg-warning "line number out of range" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/line9.c b/gcc/testsuite/gcc.dg/cpp/line9.c
new file mode 100644
index 0000000..8060aff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/line9.c
@@ -0,0 +1,5 @@
+/* Test #line overflow checks: bug 97602. */
+/* { dg-do preprocess } */
+/* { dg-options "-pedantic" } */
+
+#line 5000000000 /* { dg-warning "line number out of range" } */
diff --git a/gcc/testsuite/gcc.dg/cpp/pr97989-1.c b/gcc/testsuite/gcc.dg/cpp/pr97989-1.c
new file mode 100644
index 0000000..108dcba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr97989-1.c
@@ -0,0 +1,8 @@
+/* PR debug/97989 */
+/* { dg-do preprocess } */
+/* { dg-options "-g3 -g2 -P" } */
+
+#define foo bar
+int i;
+
+/* { dg-final { scan-file-not pr97989-1.i "(^|\\n)#define foo bar($|\\n)" } } */
diff --git a/gcc/testsuite/gcc.dg/cpp/pr97989-2.c b/gcc/testsuite/gcc.dg/cpp/pr97989-2.c
new file mode 100644
index 0000000..77a295a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cpp/pr97989-2.c
@@ -0,0 +1,8 @@
+/* PR debug/97989 */
+/* { dg-do preprocess } */
+/* { dg-options "-g2 -g3 -P" } */
+
+#define foo bar
+int i;
+
+/* { dg-final { scan-file pr97989-2.i "(^|\\n)#define foo bar($|\\n)" } } */
diff --git a/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c b/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c
new file mode 100644
index 0000000..8e07b67
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/cr-decimal-dig-3.c
@@ -0,0 +1,14 @@
+/* Test C2x CR_DECIMAL_DIG: defined for __STDC_WANT_IEC_60559_EXT__. */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x" } */
+
+#define __STDC_WANT_IEC_60559_EXT__
+#include <float.h>
+
+#ifndef CR_DECIMAL_DIG
+#error "CR_DECIMAL_DIG not defined"
+#endif
+
+#if CR_DECIMAL_DIG < DECIMAL_DIG + 3
+#error "CR_DECIMAL_DIG too small"
+#endif
diff --git a/gcc/testsuite/gcc.dg/darwin-sections.c b/gcc/testsuite/gcc.dg/darwin-sections.c
index dbe3702..5fc2860 100644
--- a/gcc/testsuite/gcc.dg/darwin-sections.c
+++ b/gcc/testsuite/gcc.dg/darwin-sections.c
@@ -10,7 +10,9 @@ typedef struct _empty {} e_s;
/* These should go in .comm */
char ub;
e_s ea;
+/* { dg-final { scan-assembler-symbol-section {^_a$} {\.data} } } */
/* { dg-final { scan-assembler ".comm\[\t \]_ub,1" } } */
+/* { dg-final { scan-assembler-symbol-section {^_b$} {\.data} } } */
/* { dg-final { scan-assembler ".comm\[\t \]_ea,1" } } */
/* These should go into __DATA,__common */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c
new file mode 100644
index 0000000..c07b904
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr97060.c
@@ -0,0 +1,13 @@
+/* PR debug/97060 */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" } */
+/* { dg-final { scan-assembler-times "DW_AT_declaration" 2 } } */
+
+extern int foo (unsigned int, unsigned int);
+
+int
+bar (void)
+{
+ foo (1, 2);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c
new file mode 100644
index 0000000..58ee74d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-4.c
@@ -0,0 +1,25 @@
+/* Test DEC_INFINITY defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC_INFINITY
+# error "DEC_INFINITY not defined"
+#endif
+
+volatile _Decimal32 d = DEC_INFINITY;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC_INFINITY, _Decimal32 : 0);
+ if (!(DEC_INFINITY > DEC32_MAX))
+ abort ();
+ if (!(d > DEC32_MAX))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c
new file mode 100644
index 0000000..8d09725
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-5.c
@@ -0,0 +1,25 @@
+/* Test DEC_NAN defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC_NAN
+# error "DEC_NAN not defined"
+#endif
+
+volatile _Decimal32 d = DEC_NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC_NAN, _Decimal32 : 0);
+ if (!__builtin_isnan (DEC_NAN))
+ abort ();
+ if (!__builtin_isnan (d))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c
new file mode 100644
index 0000000..4533c61
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-6.c
@@ -0,0 +1,28 @@
+/* Test DEC_NAN macro. Runtime exceptions test, to verify NaN is
+ quiet not signaling. (This would only actually fail for a
+ signaling NaN in the hardware DFP case, because the software DFP
+ support in libgcc does not integrate with hardware exceptions.) */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+#include <float.h>
+
+#ifndef DEC_NAN
+# error "DEC_NAN not defined"
+#endif
+
+volatile _Decimal32 d = DEC_NAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ d += d;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c
new file mode 100644
index 0000000..dec6b50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-7.c
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros defined in <float.h> with DFP support. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x" } */
+
+#include <float.h>
+
+#ifndef DEC32_SNAN
+# error "DEC32_SNAN not defined"
+#endif
+
+#ifndef DEC64_SNAN
+# error "DEC64_SNAN not defined"
+#endif
+
+#ifndef DEC128_SNAN
+# error "DEC128_SNAN not defined"
+#endif
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ (void) _Generic (DEC32_SNAN, _Decimal32 : 0);
+ if (!__builtin_isnan (DEC32_SNAN))
+ abort ();
+ if (!__builtin_isnan (d32))
+ abort ();
+ (void) _Generic (DEC64_SNAN, _Decimal64 : 0);
+ if (!__builtin_isnan (DEC64_SNAN))
+ abort ();
+ if (!__builtin_isnan (d64))
+ abort ();
+ (void) _Generic (DEC128_SNAN, _Decimal128 : 0);
+ if (!__builtin_isnan (DEC128_SNAN))
+ abort ();
+ if (!__builtin_isnan (d128))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c
new file mode 100644
index 0000000..4169602
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/dfp/c2x-float-dfp-8.c
@@ -0,0 +1,45 @@
+/* Test DEC*_SNAN macros. Test requiring runtime exceptions
+ support. */
+/* { dg-do run } */
+/* { dg-require-effective-target fenv_exceptions_dfp } */
+/* { dg-options "-std=c2x" } */
+
+#include <fenv.h>
+#include <float.h>
+
+volatile _Decimal32 d32 = DEC32_SNAN;
+volatile _Decimal64 d64 = DEC64_SNAN;
+volatile _Decimal128 d128 = DEC128_SNAN;
+
+extern void abort (void);
+extern void exit (int);
+
+int
+main (void)
+{
+ feclearexcept (FE_ALL_EXCEPT);
+ d32 += d32;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d32 += d32;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d64 += d64;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d64 += d64;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d128 += d128;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ feclearexcept (FE_ALL_EXCEPT);
+ d128 += d128;
+ if (fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/fold-isfinite-1.c b/gcc/testsuite/gcc.dg/fold-isfinite-1.c
new file mode 100644
index 0000000..2ea0192
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isfinite-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_finite((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_finitef((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_finitel((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_finite" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u> " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isfinite-2.c b/gcc/testsuite/gcc.dg/fold-isfinite-2.c
new file mode 100644
index 0000000..ff70d8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isfinite-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_finite((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_finitef((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_finitel((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_finite" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u> " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isinf-1.c b/gcc/testsuite/gcc.dg/fold-isinf-1.c
new file mode 100644
index 0000000..485816e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isinf-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_isinf((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_isinff((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_isinfl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isinf" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u<= " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isinf-2.c b/gcc/testsuite/gcc.dg/fold-isinf-2.c
new file mode 100644
index 0000000..a236ca1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isinf-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_isinf((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_isinff((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_isinfl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isinf" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " u<= " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isnan-1.c b/gcc/testsuite/gcc.dg/fold-isnan-1.c
new file mode 100644
index 0000000..05ee930
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isnan-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(int x)
+{
+ return __builtin_isnan((double)x);
+}
+
+int foof(int x)
+{
+ return __builtin_isnanf((float)x);
+}
+
+int fool(int x)
+{
+ return __builtin_isnanl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isnan" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " unord " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-isnan-2.c b/gcc/testsuite/gcc.dg/fold-isnan-2.c
new file mode 100644
index 0000000..32b8833
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-isnan-2.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target inf } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_isnan((double)x);
+}
+
+int foof(unsigned int x)
+{
+ return __builtin_isnanf((float)x);
+}
+
+int fool(unsigned int x)
+{
+ return __builtin_isnanl((long double)x);
+}
+
+/* { dg-final { scan-tree-dump-times "_isnan" 0 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " unord " 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
index d8c51ea..f46f155 100644
--- a/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
+++ b/gcc/testsuite/gcc.dg/format/ms_c99-printf-3.c
@@ -9,13 +9,33 @@
#include "format.h"
void
-foo (int i, char *s, size_t n, va_list v0, va_list v1, va_list v2, va_list v3,
+foo (int i, char *s, size_t n, long l, llong ll, double d,
+ long double ld, va_list v0, va_list v1, va_list v2, va_list v3,
va_list v4, va_list v5, va_list v6, va_list v7)
{
fprintf (stdout, "%d", i);
fprintf (stdout, "%ld", i); /* { dg-warning "format" "fprintf" } */
printf ("%d", i);
printf ("%ld", i); /* { dg-warning "format" "printf" } */
+ /* These are accepted since MSVCR80, MSVCRT from Vista, UCRT,
+ * and mingw-w64 8.0 with C99/C++11. */
+ printf ("%lld", i); /* { dg-warning "format" "printf" } */
+ printf ("%lld", l); /* { dg-warning "format" "printf" } */
+ printf ("%lld", ll);
+ printf ("%llu", i); /* { dg-warning "format" "printf" } */
+ printf ("%llu", l); /* { dg-warning "format" "printf" } */
+ printf ("%llu", ll);
+ printf ("%llx", i); /* { dg-warning "format" "printf" } */
+ printf ("%llx", l); /* { dg-warning "format" "printf" } */
+ printf ("%llx", ll);
+ /* As MSABI uses an 8-byte `long double`, `%Lg` matches GCC's
+ * `double` instead of `long double` which takes 10 bytes. */
+ printf ("%Lg", d);
+ printf ("%Lg", ld); /* { dg-warning "format" "printf" } */
+ printf ("%Le", d);
+ printf ("%Le", ld); /* { dg-warning "format" "printf" } */
+ printf ("%Lf", d);
+ printf ("%Lf", ld); /* { dg-warning "format" "printf" } */
/* The "unlocked" functions shouldn't warn in c99 mode. */
fprintf_unlocked (stdout, "%ld", i);
printf_unlocked ("%ld", i);
diff --git a/gcc/testsuite/gcc.dg/goacc/tile-1.c b/gcc/testsuite/gcc.dg/goacc/tile-1.c
new file mode 100644
index 0000000..6898397
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/goacc/tile-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+
+/* PR c/97880 */
+
+void f ()
+{
+ #pragma acc parallel loop tile(2, 3)
+ for (int i = 0; i < 8; i++)
+ for (long j = 0; j < 8; j++);
+}
diff --git a/gcc/testsuite/gcc.dg/guality/pr59776.c b/gcc/testsuite/gcc.dg/guality/pr59776.c
index 6c1c816..7c95a9f 100644
--- a/gcc/testsuite/gcc.dg/guality/pr59776.c
+++ b/gcc/testsuite/gcc.dg/guality/pr59776.c
@@ -6,7 +6,7 @@
struct S { float f, g; };
-__attribute__((noinline, noclone)) void
+__attribute__((noipa)) void
foo (struct S *p)
{
struct S s1, s2; /* { dg-final { gdb-test pr59776.c:17 "s1.f" "5.0" } } */
diff --git a/gcc/testsuite/gcc.dg/hwasan/hwasan.exp b/gcc/testsuite/gcc.dg/hwasan/hwasan.exp
new file mode 100644
index 0000000..5c040ae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/hwasan.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2012-2019 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib hwasan-dg.exp
+
+# Initialize `dg'.
+dg-init
+hwasan_init
+
+# Main loop.
+if [check_effective_target_fsanitize_hwaddress] {
+ gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/hwasan/*.c]] "" ""
+}
+
+# All done.
+hwasan_finish
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
new file mode 100644
index 0000000..0afcc10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-0.c
@@ -0,0 +1,53 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test that accessing closed over variables works.
+ */
+
+/* We need a second layer of indirection so that GCC doesn't notice we're
+ returning the address of a local variable and put 0 in it's place. */
+__attribute__((noinline))
+int *Ident(void *x) {
+ return x;
+}
+
+int __attribute__ ((noinline))
+intermediate (void (*f) (int, char),
+ char num)
+{
+ if (num == 1)
+ /* NOTE: We need to overrun by an amount greater than the "extra data" in a
+ nonlocal goto structure. The entire structure is allocated on the stack
+ with a single tag, which means hwasan can't tell if a closed-over buffer
+ was overrun by an amount small enough that the access was still to some
+ data in that nonlocal goto structure. */
+ f (100, 100);
+ else
+ f (3, 100);
+ /* Just return something ... */
+ return num % 3;
+}
+
+int* __attribute__ ((noinline))
+nested_function (char num)
+{
+ int big_array[16];
+ int other_array[16];
+ void store (int index, char value)
+ { big_array[index] = value; }
+ return Ident(&other_array[intermediate (store, num)]);
+}
+
+#ifndef MAIN
+int main ()
+{
+ nested_function (0);
+ return 0;
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
new file mode 100644
index 0000000..0161281
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-1.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test option 1.
+ */
+
+#define MAIN 0
+#include "nested-functions-0.c"
+#undef MAIN
+
+int main ()
+{
+ nested_function (1);
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c b/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
new file mode 100644
index 0000000..b1a033f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hwasan/nested-functions-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-require-effective-target hwaddress_exec } */
+/* { dg-shouldfail "hwasan" } */
+
+/*
+ Tests of nested funtions are:
+ 0) Accessing closed over variables works.
+ 1) Accesses outside of variables is caught.
+ 2) Accessing variable out of scope is caught.
+
+ Here we test option 2.
+ */
+
+#define MAIN 0
+#include "nested-functions-0.c"
+#undef MAIN
+
+int main ()
+{
+ int *retval = nested_function (2);
+ *retval = 100;
+ return 0;
+}
+
+/* { dg-output "HWAddressSanitizer: tag-mismatch on address 0x\[0-9a-f\]*.*" } */
+/* { dg-output "WRITE of size 4 at 0x\[0-9a-f\]* tags: \[\[:xdigit:\]\]\[\[:xdigit:\]\]/00 \\(ptr/mem\\) in thread T0.*" } */
+/* { dg-output "Address 0x\[0-9a-f\]* is located in stack of thread T0.*" } */
+/* { dg-output "SUMMARY: HWAddressSanitizer: tag-mismatch \[^\n\]*.*" } */
diff --git a/gcc/testsuite/gcc.dg/ipa/modref-2.c b/gcc/testsuite/gcc.dg/ipa/modref-2.c
index 5ac2c65..51ac658 100644
--- a/gcc/testsuite/gcc.dg/ipa/modref-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/modref-2.c
@@ -11,5 +11,6 @@ test2 (double x, double *y)
__builtin_modf (x,y);
}
/* 321*8 */
-/* { dg-final { scan-ipa-dump "Parm 0 param offset:0 offset:0 size:-1 max_size:2568" "modref" } } */
-/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:64" "modref" } } */
+/* { dg-final { scan-ipa-dump "Parm 0 param offset:0 offset:0 size:-1 max_size:2568" "modref" } } */
+/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:64" "modref" { target lp64 } } } */
+/* { dg-final { scan-ipa-dump "Parm 1 param offset:0 offset:0 size:-1 max_size:32" "modref" { target ilp32 } } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-3_0.c b/gcc/testsuite/gcc.dg/lto/modref-3_0.c
new file mode 100644
index 0000000..bd8f96f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-3_0.c
@@ -0,0 +1,17 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { {-O2 -flto-partition=max -fdump-ipa-modref -fno-ipa-sra -fno-ipa-cp -flto} } } */
+extern void copy (int *a, int *b);
+extern void barrier ();
+extern int *ptr;
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-wpa-ipa-dump "parm 1 flags: nodirectescape" "modref" } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-3_1.c b/gcc/testsuite/gcc.dg/lto/modref-3_1.c
new file mode 100644
index 0000000..c36f3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-3_1.c
@@ -0,0 +1,13 @@
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
diff --git a/gcc/testsuite/gcc.dg/lto/modref-4_0.c b/gcc/testsuite/gcc.dg/lto/modref-4_0.c
new file mode 100644
index 0000000..db90b4f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-4_0.c
@@ -0,0 +1,17 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options { {-O2 -flto-partition=max -fdump-ipa-modref -fno-ipa-sra -flto} } } */
+extern void copy (int *a, int *b);
+extern void barrier ();
+extern int *ptr;
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-wpa-ipa-dump "parm 1 flags: nodirectescape" "modref" } } */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-4_1.c b/gcc/testsuite/gcc.dg/lto/modref-4_1.c
new file mode 100644
index 0000000..c36f3d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-4_1.c
@@ -0,0 +1,13 @@
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
diff --git a/gcc/testsuite/gcc.dg/lvalue-11.c b/gcc/testsuite/gcc.dg/lvalue-11.c
new file mode 100644
index 0000000..d8b5a60c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lvalue-11.c
@@ -0,0 +1,40 @@
+/* test that lvalue conversions drops qualifiers, Bug 97702 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+
+const int jc;
+extern int j;
+extern typeof(0,jc) j;
+extern typeof(+jc) j;
+extern typeof(-jc) j;
+extern typeof(1?jc:0) j;
+extern typeof((int)jc) j;
+extern typeof((const int)jc) j;
+
+volatile int kv;
+extern int k;
+extern typeof(0,kv) k;
+extern typeof(+kv) k;
+extern typeof(-kv) k;
+extern typeof(1?kv:0) k;
+extern typeof((int)kv) k;
+extern typeof((volatile int)kv) k;
+
+_Atomic int la;
+extern int l;
+extern typeof(0,la) l;
+extern typeof(+la) l;
+extern typeof(-la) l;
+extern typeof(1?la:0) l;
+extern typeof((int)la) l;
+extern typeof((_Atomic int)la) l;
+
+int * restrict mr;
+extern int *m;
+extern typeof(0,mr) m;
+extern typeof(1?mr:0) m;
+extern typeof((int *)mr) m;
+extern typeof((int * restrict)mr) m;
+
+
diff --git a/gcc/testsuite/gcc.dg/memchr-3.c b/gcc/testsuite/gcc.dg/memchr-3.c
new file mode 100644
index 0000000..c38d9cf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memchr-3.c
@@ -0,0 +1,25 @@
+/* PR middle-end/97956 - ICE due to type mismatch in pointer_plus_expr
+ during memchr folding
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT32_TYPE__ int32_t;
+
+extern void* memchr (const void*, int, long);
+
+struct SX
+{
+ int32_t n;
+ int8_t a[];
+};
+
+const struct SX sx = { 0x1221 };
+const char sx_rep[] = { };
+
+void test_find (void)
+{
+ int n = 0, nb = (const char*)&sx.a - (const char*)&sx;
+ const char *p = (const char*)&sx, *q = sx_rep;
+ n += p + 1 == memchr (p, q[1], nb);
+}
diff --git a/gcc/testsuite/gcc.dg/nextafter-1.c b/gcc/testsuite/gcc.dg/nextafter-1.c
index 1916ac2..646a741 100644
--- a/gcc/testsuite/gcc.dg/nextafter-1.c
+++ b/gcc/testsuite/gcc.dg/nextafter-1.c
@@ -6,12 +6,14 @@
/* { dg-final { scan-tree-dump-not "nextafter" "optimized" } } */
/* { dg-final { scan-tree-dump-not "nexttoward" "optimized" } } */
+#ifndef _NEXT_AFTER_2
float nextafterf (float, float);
double nextafter (double, double);
long double nextafterl (long double, long double);
float nexttowardf (float, long double);
double nexttoward (double, long double);
long double nexttowardl (long double, long double);
+#endif
#define CHECK(x) if (!(x)) __builtin_abort ()
diff --git a/gcc/testsuite/gcc.dg/nextafter-2.c b/gcc/testsuite/gcc.dg/nextafter-2.c
index e51ae94..b36bc8b 100644
--- a/gcc/testsuite/gcc.dg/nextafter-2.c
+++ b/gcc/testsuite/gcc.dg/nextafter-2.c
@@ -6,6 +6,18 @@
#include <stdlib.h>
+/* In order to run on systems like the PowerPC that have 3 different long
+ double types, include math.h so it can choose what is the appropriate
+ nextafterl function to use.
+
+ If we didn't use -fno-builtin for this test, the PowerPC compiler would have
+ changed the names of the built-in functions that use long double. The
+ nextafter-1.c function runs with this mapping.
+
+ Since this test uses -fno-builtin, include math.h, so that math.h can make
+ the appropriate choice to use. */
+#include <math.h>
+
#if defined(__GLIBC__) && defined(__GLIBC_PREREQ)
# if !__GLIBC_PREREQ (2, 24)
/* Workaround buggy nextafterl in glibc 2.23 and earlier,
@@ -13,4 +25,7 @@
# define NO_LONG_DOUBLE 1
# endif
#endif
+
+#define _NEXT_AFTER_2
+
#include "nextafter-1.c"
diff --git a/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
new file mode 100644
index 0000000..05133d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/analyzer_gil_plugin.c
@@ -0,0 +1,436 @@
+/* Proof-of-concept of a -fanalyzer plugin.
+ Detect (some) uses of CPython API outside of the Global Interpreter Lock.
+ https://docs.python.org/3/c-api/init.html#thread-state-and-the-global-interpreter-lock
+*/
+/* { dg-options "-g" } */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "diagnostic.h"
+#include "tree.h"
+#include "gimple.h"
+#include "gimple-iterator.h"
+#include "gimple-walk.h"
+#include "diagnostic-event-id.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/analyzer-logging.h"
+#include "json.h"
+#include "analyzer/sm.h"
+#include "analyzer/pending-diagnostic.h"
+
+int plugin_is_GPL_compatible;
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+static bool
+type_based_on_pyobject_p (tree type)
+{
+ /* Ideally we'd also check for "subclasses" here by iterating up the
+ first field of each struct. */
+ if (TREE_CODE (type) != RECORD_TYPE)
+ return false;
+ tree name = TYPE_IDENTIFIER (type);
+ if (!name)
+ return false;
+ return id_equal (name, "PyObject");
+}
+
+/* An experimental state machine, for tracking whether the GIL is held,
+ as global state.. */
+
+class gil_state_machine : public state_machine
+{
+public:
+ gil_state_machine (logger *logger);
+
+ 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;
+
+ void on_condition (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ tree lhs,
+ enum tree_code op,
+ tree rhs) 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,
+ const gimple *stmt,
+ tree op) const;
+
+ private:
+ void check_for_pyobject_in_call (sm_context *sm_ctxt,
+ const supernode *node,
+ const gcall *call,
+ tree callee_fndecl) const;
+
+ public:
+ /* These states are "global", rather than per-expression. */
+
+ /* State for when we've released the GIL. */
+ state_t m_released_gil;
+
+ /* Stop state. */
+ state_t m_stop;
+};
+
+/* Subclass for diagnostics involving the GIL. */
+
+class gil_diagnostic : public pending_diagnostic
+{
+public:
+ location_t fixup_location (location_t loc) const FINAL OVERRIDE
+ {
+ /* Ideally we'd check for specific macros here, and only
+ resolve certain macros. */
+ if (linemap_location_from_macro_expansion_p (line_table, loc))
+ loc = linemap_resolve_location (line_table, loc,
+ LRK_MACRO_EXPANSION_POINT, NULL);
+ return loc;
+ }
+
+ label_text describe_state_change (const evdesc::state_change &change)
+ FINAL OVERRIDE
+ {
+ if (change.is_global_p ()
+ && change.m_new_state == m_sm.m_released_gil)
+ return change.formatted_print ("releasing the GIL here");
+ if (change.is_global_p ()
+ && change.m_new_state == m_sm.get_start_state ())
+ return change.formatted_print ("acquiring the GIL here");
+ return label_text ();
+ }
+
+ protected:
+ gil_diagnostic (const gil_state_machine &sm) : m_sm (sm)
+ {
+ }
+
+ private:
+ const gil_state_machine &m_sm;
+};
+
+class double_save_thread : public gil_diagnostic
+{
+ public:
+ double_save_thread (const gil_state_machine &sm, const gcall *call)
+ : gil_diagnostic (sm), m_call (call)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "double_save_thread";
+ }
+
+ 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
+ {
+ return warning_at (rich_loc, 0,
+ "nested usage of %qs", "Py_BEGIN_ALLOW_THREADS");
+ }
+
+ 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");
+ }
+
+ private:
+ const gcall *m_call;
+};
+
+class fncall_without_gil : public gil_diagnostic
+{
+ public:
+ fncall_without_gil (const gil_state_machine &sm, const gcall *call,
+ tree callee_fndecl, unsigned arg_idx)
+ : gil_diagnostic (sm), m_call (call), m_callee_fndecl (callee_fndecl),
+ m_arg_idx (arg_idx)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "fncall_without_gil";
+ }
+
+ bool subclass_equal_p (const pending_diagnostic &base_other) const OVERRIDE
+ {
+ const fncall_without_gil &sub_other
+ = (const fncall_without_gil &)base_other;
+ return (m_call == sub_other.m_call
+ && m_callee_fndecl == sub_other.m_callee_fndecl
+ && m_arg_idx == sub_other.m_arg_idx);
+ }
+
+ 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,
+ "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,
+ "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
+ {
+ if (m_callee_fndecl)
+ return ev.formatted_print ("use of PyObject as argument %i of %qE here"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ else
+ return ev.formatted_print ("use of PyObject as argument %i of call here"
+ " without the GIL",
+ m_arg_idx + 1, m_callee_fndecl);
+ }
+
+ private:
+ const gcall *m_call;
+ tree m_callee_fndecl;
+ unsigned m_arg_idx;
+};
+
+class pyobject_usage_without_gil : public gil_diagnostic
+{
+ public:
+ pyobject_usage_without_gil (const gil_state_machine &sm, tree expr)
+ : gil_diagnostic (sm), m_expr (expr)
+ {}
+
+ const char *get_kind () const FINAL OVERRIDE
+ {
+ return "pyobject_usage_without_gil";
+ }
+
+ 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
+ {
+ auto_diagnostic_group d;
+ /* There isn't a warning ID for use to use. */
+ return warning_at (rich_loc, 0,
+ "use of PyObject %qE without the GIL", m_expr);
+ }
+
+ 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);
+ }
+
+ private:
+ tree m_expr;
+};
+
+/* gil_state_machine's ctor. */
+
+gil_state_machine::gil_state_machine (logger *logger)
+: state_machine ("gil", logger)
+{
+ m_released_gil = add_state ("released_gil");
+ m_stop = add_state ("stop");
+}
+
+struct cb_data
+{
+ cb_data (const gil_state_machine &sm, sm_context *sm_ctxt,
+ const supernode *snode, const gimple *stmt)
+ : m_sm (sm), m_sm_ctxt (sm_ctxt), m_snode (snode), m_stmt (stmt)
+ {
+ }
+
+ const gil_state_machine &m_sm;
+ sm_context *m_sm_ctxt;
+ const supernode *m_snode;
+ const gimple *m_stmt;
+};
+
+static bool
+check_for_pyobject (gimple *, tree op, tree, void *data)
+{
+ cb_data *d = (cb_data *)data;
+ d->m_sm.check_for_pyobject_usage_without_gil (d->m_sm_ctxt, d->m_snode,
+ d->m_stmt, op);
+ return true;
+}
+
+/* Assuming that the GIL has been released, complain about any
+ PyObject * arguments passed to CALL. */
+
+void
+gil_state_machine::check_for_pyobject_in_call (sm_context *sm_ctxt,
+ const supernode *node,
+ const gcall *call,
+ tree callee_fndecl) const
+{
+ for (unsigned i = 0; i < gimple_call_num_args (call); i++)
+ {
+ tree arg = gimple_call_arg (call, i);
+ if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE)
+ continue;
+ tree type = TREE_TYPE (TREE_TYPE (arg));
+ if (type_based_on_pyobject_p (type))
+ {
+ sm_ctxt->warn (node, call, NULL_TREE,
+ new fncall_without_gil (*this, call,
+ callee_fndecl,
+ i));
+ sm_ctxt->set_global_state (m_stop);
+ }
+ }
+}
+
+/* Implementation of state_machine::on_stmt vfunc for gil_state_machine. */
+
+bool
+gil_state_machine::on_stmt (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt) const
+{
+ const state_t global_state = sm_ctxt->get_global_state ();
+ if (const gcall *call = dyn_cast <const gcall *> (stmt))
+ {
+ if (tree callee_fndecl = sm_ctxt->get_fndecl_for_call (call))
+ {
+ if (is_named_call_p (callee_fndecl, "PyEval_SaveThread", call, 0))
+ {
+ if (0)
+ inform (input_location, "found call to %qs",
+ "PyEval_SaveThread");
+ if (global_state == m_released_gil)
+ {
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ new double_save_thread (*this, call));
+ sm_ctxt->set_global_state (m_stop);
+ }
+ else
+ sm_ctxt->set_global_state (m_released_gil);
+ return true;
+ }
+ else if (is_named_call_p (callee_fndecl, "PyEval_RestoreThread",
+ call, 1))
+ {
+ if (0)
+ inform (input_location, "found call to %qs",
+ "PyEval_SaveThread");
+ if (global_state == m_released_gil)
+ sm_ctxt->set_global_state (m_start);
+ return true;
+ }
+ else if (global_state == m_released_gil)
+ {
+ /* Find PyObject * args of calls to fns with unknown bodies. */
+ if (!fndecl_has_gimple_body_p (callee_fndecl))
+ check_for_pyobject_in_call (sm_ctxt, node, call, callee_fndecl);
+ }
+ }
+ else if (global_state == m_released_gil)
+ check_for_pyobject_in_call (sm_ctxt, node, call, NULL);
+ }
+ else
+ if (global_state == m_released_gil)
+ {
+ /* Walk the stmt, finding uses of PyObject (or "subclasses"). */
+ cb_data d (*this, sm_ctxt, node, stmt);
+ walk_stmt_load_store_addr_ops (const_cast <gimple *> (stmt), &d,
+ check_for_pyobject,
+ check_for_pyobject,
+ check_for_pyobject);
+ }
+ return false;
+}
+
+/* Implementation of state_machine::on_condition vfunc for
+ gil_state_machine. */
+
+void
+gil_state_machine::on_condition (sm_context *sm_ctxt ATTRIBUTE_UNUSED,
+ const supernode *node ATTRIBUTE_UNUSED,
+ const gimple *stmt ATTRIBUTE_UNUSED,
+ tree lhs ATTRIBUTE_UNUSED,
+ enum tree_code op ATTRIBUTE_UNUSED,
+ tree rhs ATTRIBUTE_UNUSED) const
+{
+ // Empty
+}
+
+bool
+gil_state_machine::can_purge_p (state_t s ATTRIBUTE_UNUSED) const
+{
+ return true;
+}
+
+void
+gil_state_machine::check_for_pyobject_usage_without_gil (sm_context *sm_ctxt,
+ const supernode *node,
+ const gimple *stmt,
+ tree op) const
+{
+ tree type = TREE_TYPE (op);
+ if (type_based_on_pyobject_p (type))
+ {
+ sm_ctxt->warn (node, stmt, NULL_TREE,
+ new pyobject_usage_without_gil (*this, op));
+ sm_ctxt->set_global_state (m_stop);
+ }
+}
+
+/* Callback handler for the PLUGIN_ANALYZER_INIT event. */
+
+static void
+gil_analyzer_init_cb (void *gcc_data, void */*user_data*/)
+{
+ ana::plugin_analyzer_init_iface *iface
+ = (ana::plugin_analyzer_init_iface *)gcc_data;
+ LOG_SCOPE (iface->get_logger ());
+ if (0)
+ inform (input_location, "got here: gil_analyzer_init_cb");
+ iface->register_state_machine (new gil_state_machine (iface->get_logger ()));
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+#if ENABLE_ANALYZER
+ const char *plugin_name = plugin_info->base_name;
+ if (0)
+ inform (input_location, "got here; %qs", plugin_name);
+ register_callback (plugin_info->base_name,
+ PLUGIN_ANALYZER_INIT,
+ ana::gil_analyzer_init_cb,
+ NULL); /* void *user_data */
+#else
+ sorry_no_analyzer ();
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/gil-1.c b/gcc/testsuite/gcc.dg/plugin/gil-1.c
new file mode 100644
index 0000000..4e8f535
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/gil-1.c
@@ -0,0 +1,90 @@
+/* { dg-do compile } */
+/* { dg-options "-fanalyzer" } */
+
+#include "gil.h"
+
+void test_1 (void)
+{
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+}
+
+void test_2 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+
+ Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*\\(obj\\)' without the GIL" } */
+ Py_DECREF (obj);
+
+ Py_END_ALLOW_THREADS
+}
+
+void test_3 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+
+ Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
+ Py_END_ALLOW_THREADS
+
+ Py_END_ALLOW_THREADS
+}
+
+void test_4 (PyObject *obj)
+{
+ /* These aren't nested, so should be OK. */
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+
+ Py_BEGIN_ALLOW_THREADS
+ Py_END_ALLOW_THREADS
+}
+
+/* Interprocedural example of erroneously nested usage. */
+
+static void __attribute__((noinline))
+called_by_test_5 (void)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-warning "nested usage of 'Py_BEGIN_ALLOW_THREADS'" } */
+ Py_END_ALLOW_THREADS
+}
+
+void test_5 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_5 ();
+ Py_END_ALLOW_THREADS
+}
+
+/* Interprocedural example of bogusly using a PyObject outside of GIL. */
+
+static void __attribute__((noinline))
+called_by_test_6 (PyObject *obj)
+{
+ Py_INCREF (obj); /* { dg-warning "use of PyObject '\\*\\(obj\\)' without the GIL" } */
+ Py_DECREF (obj);
+}
+
+void test_6 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_6 (obj);
+ Py_END_ALLOW_THREADS
+}
+
+extern void called_by_test_7 (PyObject *obj);
+
+void test_7 (PyObject *obj)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ called_by_test_7 (obj); /* { dg-warning "use of PyObject as argument 1 of 'called_by_test_7' without the GIL" } */
+ Py_END_ALLOW_THREADS
+}
+
+typedef void (*callback_t) (PyObject *);
+
+void test_8 (PyObject *obj, callback_t cb)
+{
+ Py_BEGIN_ALLOW_THREADS /* { dg-message "releasing the GIL here" } */
+ cb (obj); /* { dg-warning "use of PyObject as argument 1 of call without the GIL" } */
+ Py_END_ALLOW_THREADS
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/gil.h b/gcc/testsuite/gcc.dg/plugin/gil.h
new file mode 100644
index 0000000..b0610cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/gil.h
@@ -0,0 +1,32 @@
+/* Adapted from CPython 3.8's ceval.h. */
+typedef struct PyThreadState PyThreadState;
+extern PyThreadState * PyEval_SaveThread(void);
+extern void PyEval_RestoreThread(PyThreadState *);
+
+#define Py_BEGIN_ALLOW_THREADS { \
+ PyThreadState *_save; \
+ _save = PyEval_SaveThread();
+#define Py_BLOCK_THREADS PyEval_RestoreThread(_save);
+#define Py_UNBLOCK_THREADS _save = PyEval_SaveThread();
+#define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \
+ }
+
+/* Adapted/hacked up from CPython 3.8's object.h. */
+
+typedef struct _object {
+ int ob_refcnt;
+} PyObject;
+
+#define _PyObject_CAST(op) ((PyObject*)(op))
+
+extern void _Py_Dealloc(PyObject *);
+
+#define _Py_INCREF(OP) do { (OP)->ob_refcnt++; } while (0);
+#define _Py_DECREF(OP) do { \
+ if (--(OP)->ob_refcnt == 0) { \
+ _Py_Dealloc(OP); \
+ } \
+ } while (0)
+
+#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op))
+#define Py_DECREF(op) _Py_DECREF(_PyObject_CAST(op))
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index 5dd102a..7f0ffd6 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -118,6 +118,8 @@ set plugin_test_list [list \
{ dump_plugin.c \
dump-1.c \
dump-2.c } \
+ { analyzer_gil_plugin.c \
+ gil-1.c } \
]
foreach plugin_test $plugin_test_list {
diff --git a/gcc/testsuite/gcc.dg/pr25376.c b/gcc/testsuite/gcc.dg/pr25376.c
index 3008b09..d66f2e1 100644
--- a/gcc/testsuite/gcc.dg/pr25376.c
+++ b/gcc/testsuite/gcc.dg/pr25376.c
@@ -7,3 +7,4 @@ void simple (void)
}
/* { dg-final { scan-assembler "my_named_section" } } */
+/* { dg-final { scan-assembler-symbol-section {simple$} {^\.?my_named_section|simple\[DS\]|^\"\.opd\"} } } */
diff --git a/gcc/testsuite/gcc.dg/pr46309-2.c b/gcc/testsuite/gcc.dg/pr46309-2.c
index f56df42..2903fff 100644
--- a/gcc/testsuite/gcc.dg/pr46309-2.c
+++ b/gcc/testsuite/gcc.dg/pr46309-2.c
@@ -1,6 +1,6 @@
/* PR tree-optimization/46309 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-ipa-icf -fdump-tree-reassoc-details" } */
+/* { dg-options "-O2 -fno-ipa-icf -fno-jump-tables -fno-bit-tests -fdump-tree-reassoc-details" } */
int foo (void);
diff --git a/gcc/testsuite/gcc.dg/pr60195.c b/gcc/testsuite/gcc.dg/pr60195.c
index 0a50a30..8eccf7f 100644
--- a/gcc/testsuite/gcc.dg/pr60195.c
+++ b/gcc/testsuite/gcc.dg/pr60195.c
@@ -15,7 +15,7 @@ atomic_int
fn2 (void)
{
atomic_int y = 0;
- y;
+ y; /* { dg-warning "statement with no effect" } */
return y;
}
diff --git a/gcc/testsuite/gcc.dg/pr83072.c b/gcc/testsuite/gcc.dg/pr83072.c
new file mode 100644
index 0000000..3bed8d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr83072.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre" } */
+
+void kill (void);
+
+int f(int c){
+ c |= 1;
+ if (c == 0)
+ kill ();
+
+ return c;
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr85811.c b/gcc/testsuite/gcc.dg/pr85811.c
new file mode 100644
index 0000000..868f66c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr85811.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+#include <stdio.h>
+
+int main() {
+ const double negval = -1.0;
+ const double nanval = 0.0 / 0.0;
+ const double val = __builtin_fmax(negval, nanval);
+ const double absval = __builtin_fabs(val);
+ printf("fabs(%.16e) = %.16e\n", val, absval);
+ return absval >= 0 ? 0 : 1;
+}
+
+/* We hope not to see: printf ("fabs(%.16e) = %.16e\n", val_4, val_4); */
+/* { dg-final { scan-tree-dump-not "val_\[0-9\]*, val_\[0-9\]*" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr91029.c b/gcc/testsuite/gcc.dg/pr91029.c
new file mode 100644
index 0000000..4904764
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr91029.c
@@ -0,0 +1,48 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i)
+{
+ if ((i % 7) == 3)
+ {
+ xx = (i < 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i)
+{
+ if ((i % 7) > 0)
+ {
+ xx = (i < 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i)
+{
+ if ((i % 7) == -3)
+ {
+ xx = (i > 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i)
+{
+ if ((i % 7) < 0)
+ {
+ xx = (i > 0);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/pr95853.c b/gcc/testsuite/gcc.dg/pr95853.c
new file mode 100644
index 0000000..fdd3c30
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr95853.c
@@ -0,0 +1,59 @@
+/* PR tree-optimization/95853 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-widening_mul" } */
+
+#if __SIZEOF_INT128__
+typedef __uint128_t W;
+typedef unsigned long long T;
+#else
+typedef unsigned long long W;
+typedef unsigned int T;
+#endif
+
+struct S { int p; T r; };
+
+struct S
+foo (T x, T y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+bar (T x)
+{
+ W z = (W) x + 132;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+baz (T x, unsigned short y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+qux (unsigned short x, T y)
+{
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, (T) z };
+}
+
+struct S
+corge (T x, T y)
+{
+ T w = x + y;
+ W z = (W) x + y;
+ return (struct S) { z > ~(T) 0, w };
+}
+
+struct S
+garple (T x, T y)
+{
+ W z = (W) x + y;
+ T w = x + y;
+ return (struct S) { z > ~(T) 0, w };
+}
+
+/* { dg-final { scan-tree-dump-times "ADD_OVERFLOW" 6 "widening_mul" { target { i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/pr96708-negative.c b/gcc/testsuite/gcc.dg/pr96708-negative.c
new file mode 100644
index 0000000..91964d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96708-negative.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noinline))
+test1 (int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp <= a;
+}
+
+bool __attribute__ ((noinline))
+test2 (int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp > a;
+}
+
+bool __attribute__ ((noinline))
+test3 (int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp >= a;
+}
+
+bool __attribute__ ((noinline))
+test4 (int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp < a;
+}
+
+int main()
+{
+ if (test1 (1, 2) || !test1 (2, 1) ||
+ !test2 (1, 2) || test2 (2, 1) ||
+ !test3 (1, 2) || test3 (2, 1) ||
+ test4 (1, 2) || !test4 (2, 1)) {
+ __builtin_abort();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "MAX_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 0;" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "return 1;" } "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr96708-positive.c b/gcc/testsuite/gcc.dg/pr96708-positive.c
new file mode 100644
index 0000000..65af853
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96708-positive.c
@@ -0,0 +1,48 @@
+/* { dg-do run } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#include <stdbool.h>
+
+bool __attribute__ ((noinline))
+test1(int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp >= a;
+}
+
+bool __attribute__ ((noinline))
+test2(int a, int b)
+{
+ int tmp = (a < b) ? b : a;
+ return tmp < a;
+}
+
+bool __attribute__ ((noinline))
+test3(int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp <= a;
+}
+
+bool __attribute__ ((noinline))
+test4(int a, int b)
+{
+ int tmp = (a > b) ? b : a;
+ return tmp > a;
+}
+
+int main()
+{
+ if (!test1 (1, 2) || !test1 (2, 1) ||
+ test2 (1, 2) || test2 (2, 1) ||
+ !test3 (1, 2) || !test3 (2, 1) ||
+ test4 (1, 2) || test4 (2, 1)) {
+ __builtin_abort();
+ }
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "return 0;" 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return 1;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "MAX_EXPR" } "optimized" } } */
+/* { dg-final { scan-tree-dump-not { "MIN_EXPR" } "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr97459-1.c b/gcc/testsuite/gcc.dg/pr97459-1.c
new file mode 100644
index 0000000..96c7ab6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-1.c
@@ -0,0 +1,54 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x % n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x % (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ if (foo (x, tests[k].x) != tests[k].foo (x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-2.c b/gcc/testsuite/gcc.dg/pr97459-2.c
new file mode 100644
index 0000000..0e2bfbd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-2.c
@@ -0,0 +1,57 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x % n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x % (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ if (foo ((T) x, tests[k].x) != tests[k].foo ((T) x)
+ || foo ((T) -x, tests[k].x) != tests[k].foo ((T) -x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-3.c b/gcc/testsuite/gcc.dg/pr97459-3.c
new file mode 100644
index 0000000..7fbb7ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-3.c
@@ -0,0 +1,54 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ if (foo (x, tests[k].x) != tests[k].foo (x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-4.c b/gcc/testsuite/gcc.dg/pr97459-4.c
new file mode 100644
index 0000000..33e49a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-4.c
@@ -0,0 +1,57 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n) { return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x) { return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ if (foo ((T) x, tests[k].x) != tests[k].foo ((T) x)
+ || foo ((T) -x, tests[k].x) != tests[k].foo ((T) -x))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-5.c b/gcc/testsuite/gcc.dg/pr97459-5.c
new file mode 100644
index 0000000..f658a5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-5.c
@@ -0,0 +1,56 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __uint128_t T;
+#else
+typedef unsigned long long T;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n, T *r) { *r = x % n; return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x, T *r) { *r = x % (n - 10000); return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T, T *); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ T x = ((T) 1 << i) + j;
+ T r1, r2;
+ if (foo (x, tests[k].x, &r1) != tests[k].foo (x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97459-6.c b/gcc/testsuite/gcc.dg/pr97459-6.c
new file mode 100644
index 0000000..d4602be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97459-6.c
@@ -0,0 +1,62 @@
+/* PR rtl-optimization/97459 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-DEXPENSIVE" { target run_expensive_tests } } */
+
+#ifdef __SIZEOF_INT128__
+typedef __int128_t T;
+typedef __uint128_t U;
+#else
+typedef long long T;
+typedef unsigned long long U;
+#endif
+
+T __attribute__((noipa)) foo (T x, T n, T *r) { *r = x % n; return x / n; }
+#define C(n) T __attribute__((noipa)) foo##n (T x, T *r) { *r = x % (n - 10000); return x / (n - 10000); }
+
+#define C1(n) C(n##1) C(n##3) C(n##5) C(n##7) C(n##9)
+#define C2(n) C1(n##0) C1(n##1) C1(n##2) C1(n##3) C1(n##4) \
+ C1(n##5) C1(n##6) C1(n##7) C1(n##8) C1(n##9)
+#ifdef EXPENSIVE
+#define C3(n) C2(n##0) C2(n##1) C2(n##2) C2(n##3) C2(n##4) \
+ C2(n##5) C2(n##6) C2(n##7) C2(n##8) C2(n##9)
+#define C4(n) C3(n##0) C3(n##1) C3(n##2) C3(n##3) C3(n##4) \
+ C3(n##5) C3(n##6) C3(n##7) C3(n##8) C3(n##9)
+#else
+#define C3(n) C2(n##0) C2(n##4) C2(n##9)
+#define C4(n) C3(n##0) C3(n##3) C3(n##7)
+#endif
+#define TESTS C4(1) C1(10010) C1(10012) C1(16144)
+
+TESTS
+
+struct S { T x; T (*foo) (T, T *); };
+
+#undef C
+#define C(n) { n - 10000, foo##n },
+
+struct S tests[] = {
+TESTS
+ { 0, 0 }
+};
+
+int
+main ()
+{
+ int i, j, k;
+ for (k = 0; tests[k].x; k++)
+ for (i = 0; i < sizeof (T) * __CHAR_BIT__; i++)
+ for (j = -5; j <= 5; j++)
+ {
+ U x = ((U) 1 << i) + j;
+ T r1 = 0, r2 = 0;
+ if (foo ((T) x, tests[k].x, &r1) != tests[k].foo ((T) x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ r1 = 0; r2 = 0;
+ if (foo ((T) -x, tests[k].x, &r1) != tests[k].foo ((T) -x, &r2)
+ || r1 != r2)
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97515.c b/gcc/testsuite/gcc.dg/pr97515.c
index 84f145a..b4f2481 100644
--- a/gcc/testsuite/gcc.dg/pr97515.c
+++ b/gcc/testsuite/gcc.dg/pr97515.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-evrp" } */
+/* { dg-options "-O2 -fdump-tree-ccp2" } */
int
e7 (int gg)
@@ -20,6 +20,8 @@ e7 (int gg)
return xe;
}
-/* EVRP should be able to reduce this to a single goto. */
+/* EVRP should be able to reduce this to a single goto when we can
+ * revisit statements to try folding again based on changed inputs.
+ * Until then, make sure its gone by ccp2. */
-/* { dg-final { scan-tree-dump-times "goto" 1 "evrp" } } */
+/* { dg-final { scan-tree-dump-times "goto" 1 "ccp2" } } */
diff --git a/gcc/testsuite/gcc.dg/pr97534.c b/gcc/testsuite/gcc.dg/pr97534.c
new file mode 100644
index 0000000..b363a32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97534.c
@@ -0,0 +1,9 @@
+/* PR target/97534 - ICE in decompose on arm*-*-*. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -O2 -g" } */
+
+int f (int a)
+{
+ int b;
+ __atomic_fetch_sub(&b, (int)(-__INT_MAX__ - 1), (int)0);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97579.c b/gcc/testsuite/gcc.dg/pr97579.c
new file mode 100644
index 0000000..5cd5427
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97579.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 --param=max-unswitch-insns=1024" } */
+/* { dg-additional-options "-mavx512vl" { target x86_64-*-* i?86-*-* } } */
+
+int bad_odd_rows_0_0, rows_bad_row1, rows_bad_group_okay, calc_rows_row2;
+
+int
+rows_bad() {
+ int i, in_zeroes;
+ char block;
+ i = 0;
+ for (; i < 5; i++)
+ if (rows_bad_row1 & i)
+ in_zeroes = 0;
+ else {
+ if (!in_zeroes)
+ in_zeroes = 1;
+ if (block & 1)
+ rows_bad_group_okay = 1;
+ }
+ if (in_zeroes)
+ return rows_bad_group_okay;
+}
+
+void
+calc_rows() {
+ for (; calc_rows_row2; calc_rows_row2++) {
+ rows_bad();
+ bad_odd_rows_0_0 = rows_bad();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97806.c b/gcc/testsuite/gcc.dg/pr97806.c
new file mode 100644
index 0000000..9ec3299
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97806.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int b;
+long c;
+int g();
+void h(long *);
+void i(long *);
+void d() {
+ int e, f = b - e;
+ if (g())
+ h(&c + f);
+ else
+ i(&c + f);
+ __builtin_memset(0, 0, f * 8);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97830.c b/gcc/testsuite/gcc.dg/pr97830.c
new file mode 100644
index 0000000..3729a65
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97830.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef enum { LangC } cLanguage;
+typedef enum { FunctionOneArg, FunctionStandard } cFunctionType;
+void *CCTK_CallFunction_function;
+cLanguage CCTK_CallFunction_fdata_0;
+cFunctionType CCTK_CallFunction_fdata_1;
+void CCTK_CallFunction_data() {
+ void (*standardfunc)();
+ int (*oneargfunc)();
+ switch (CCTK_CallFunction_fdata_1) {
+ case FunctionOneArg:
+ oneargfunc = CCTK_CallFunction_function;
+ oneargfunc(CCTK_CallFunction_data);
+ break;
+ case FunctionStandard:
+ switch (CCTK_CallFunction_fdata_0) {
+ case LangC:
+ standardfunc = CCTK_CallFunction_function;
+ standardfunc(CCTK_CallFunction_data);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97860.c b/gcc/testsuite/gcc.dg/pr97860.c
new file mode 100644
index 0000000..04c0f19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97860.c
@@ -0,0 +1,11 @@
+/* PR c/97860 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void
+foo (int n)
+{
+ typedef int T[0];
+ typedef T V[n];
+ void bar (V);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97897.c b/gcc/testsuite/gcc.dg/pr97897.c
new file mode 100644
index 0000000..084c1cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97897.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+void h ();
+void f () __attribute__ ((returns_twice));
+void g (_Complex int a)
+{
+ f ();
+ if (a != 0)
+ {
+ a = 0;
+ h ();
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr97953.c b/gcc/testsuite/gcc.dg/pr97953.c
new file mode 100644
index 0000000..6219619
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97953.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-fre" } */
+
+int __attribute__((noipa))
+foo (int flag, int *p)
+{
+ int val = *p;
+ if (flag)
+ {
+ if (val != 1)
+ __builtin_unreachable ();
+ return 0;
+ }
+ int val2 = *p;
+ return val2 == 2;
+}
+
+int main()
+{
+ int i = 2;
+ if (foo (0, &i) != 1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97954.c b/gcc/testsuite/gcc.dg/pr97954.c
new file mode 100644
index 0000000..178e1d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97954.c
@@ -0,0 +1,12 @@
+/* PR rtl-optimization/97954 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int
+foo (void)
+{
+ int x;
+ lab:
+ asm goto ("": "=r" (x) : : : lab);
+ return x;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97955.c b/gcc/testsuite/gcc.dg/pr97955.c
new file mode 100644
index 0000000..a5236c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97955.c
@@ -0,0 +1,7 @@
+/* PR 97955 - ICE in build_array_type_1 on invalid redeclaration of function
+ with VLA parameter
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+void f (int n, int a[n]);
+void f (int *b) { } // { dg-error "conflicting types" }
diff --git a/gcc/testsuite/gcc.dg/pr97979.c b/gcc/testsuite/gcc.dg/pr97979.c
new file mode 100644
index 0000000..44aaff2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97979.c
@@ -0,0 +1,13 @@
+/* PR tree-optimization/97979 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-ccp" } */
+
+short a = 0;
+int b = 0;
+
+void
+foo (void)
+{
+ unsigned short d = b;
+ a = d >> -2U; /* { dg-warning "right shift count >= width of type" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr98099.c b/gcc/testsuite/gcc.dg/pr98099.c
new file mode 100644
index 0000000..34909f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr98099.c
@@ -0,0 +1,12 @@
+/* PR middle-end/98099 */
+/* Reported by G. Steinmetz <gscfq@t-online.de> */
+
+/* { dg-do compile } */
+/* { dg-options "-fsso-struct=big-endian" } */
+
+struct S { _Decimal128 a; };
+
+_Decimal128 f (struct S x)
+{
+ return x.a; /* { dg-message "sorry, unimplemented: reverse storage order" "" { target { ! int128 } } } */
+}
diff --git a/gcc/testsuite/gcc.dg/profile-info-section.c b/gcc/testsuite/gcc.dg/profile-info-section.c
new file mode 100644
index 0000000..8f31f3b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/profile-info-section.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-skip-if "profile-info-section" { powerpc-ibm-aix* } } */
+/* { dg-options "-fprofile-arcs -fprofile-info-section -fdump-tree-optimized" } */
+
+int foo()
+{
+ return 0;
+}
+
+int bar()
+{
+ return 1;
+}
+
+int main ()
+{
+ return foo ();
+}
+
+/* { dg-final { scan-tree-dump-not "__gcov_init" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "__gcov_exit" "optimized" } } */
+/* { dg-final { scan-assembler "\.gcov_info" } } */
diff --git a/gcc/testsuite/gcc.dg/strncmp-2.c b/gcc/testsuite/gcc.dg/strncmp-2.c
index 6818b30..0d84f93 100644
--- a/gcc/testsuite/gcc.dg/strncmp-2.c
+++ b/gcc/testsuite/gcc.dg/strncmp-2.c
@@ -40,6 +40,7 @@ static void test_driver_strncmp (void (test_strncmp)(const char *, const char *,
e = lib_memcmp(buf1,p2,sz);
(*test_memcmp)(buf1,p2,e);
}
+ mprotect (buf2+pgsz,pgsz,PROT_READ|PROT_WRITE);
free(buf2);
}
diff --git a/gcc/testsuite/gcc.dg/system-binary-constants-1.c b/gcc/testsuite/gcc.dg/system-binary-constants-1.c
index 921ee20..ca16215 100644
--- a/gcc/testsuite/gcc.dg/system-binary-constants-1.c
+++ b/gcc/testsuite/gcc.dg/system-binary-constants-1.c
@@ -14,5 +14,5 @@ foo (void)
warning. */
return 23;
#endif
- return 0b1101; /* { dg-warning "binary constants are a GCC extension" } */
+ return 0b1101; /* { dg-warning "binary constants are a C2X feature or GCC extension" } */
}
diff --git a/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c
new file mode 100644
index 0000000..69fd45a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float128 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float128 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float128_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 128
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c
new file mode 100644
index 0000000..5be4c07
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float128x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float128x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float128x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float128x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 128
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c
new file mode 100644
index 0000000..cf03b45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float16-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float16 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float16 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float16_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 16
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c
new file mode 100644
index 0000000..2976a40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float32 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float32 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float32_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 32
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c
new file mode 100644
index 0000000..0aab4be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float32x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float32x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float32x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float32x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 32
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c
new file mode 100644
index 0000000..1f5298b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float64 NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float64 } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float64_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 64
+#define EXT 0
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c b/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c
new file mode 100644
index 0000000..fbc8676
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/float64x-nan-floath.c
@@ -0,0 +1,11 @@
+/* Test _Float64x NaNs in <float.h>. */
+/* { dg-do run } */
+/* { dg-options "-std=c2x -fsignaling-nans" } */
+/* { dg-add-options float64x } */
+/* { dg-add-options ieee } */
+/* { dg-require-effective-target float64x_runtime } */
+/* { dg-require-effective-target fenv_exceptions } */
+
+#define WIDTH 64
+#define EXT 1
+#include "floatn-nan-floath.h"
diff --git a/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h b/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h
new file mode 100644
index 0000000..9892fd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/floatn-nan-floath.h
@@ -0,0 +1,36 @@
+/* Tests for _FloatN / _FloatNx types: compile and execution tests for
+ NaNs, SNAN macros in <float.h>. Before including this file, define
+ WIDTH as the value N; define EXT to 1 for _FloatNx and 0 for
+ _FloatN. */
+
+#define CONCATX(X, Y) X ## Y
+#define CONCAT(X, Y) CONCATX (X, Y)
+#define CONCAT3(X, Y, Z) CONCAT (CONCAT (X, Y), Z)
+#define CONCAT4(W, X, Y, Z) CONCAT (CONCAT (CONCAT (W, X), Y), Z)
+
+#if EXT
+# define TYPE CONCAT3 (_Float, WIDTH, x)
+# define SNAN CONCAT3 (FLT, WIDTH, X_SNAN)
+#else
+# define TYPE CONCAT (_Float, WIDTH)
+# define SNAN CONCAT3 (FLT, WIDTH, _SNAN)
+#endif
+
+#define __STDC_WANT_IEC_60559_TYPES_EXT__
+#include <fenv.h>
+#include <float.h>
+
+extern void exit (int);
+extern void abort (void);
+
+volatile TYPE nans_cst = SNAN;
+
+int
+main (void)
+{
+ volatile TYPE r;
+ r = nans_cst + nans_cst;
+ if (!fetestexcept (FE_INVALID))
+ abort ();
+ exit (0);
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97812.c b/gcc/testsuite/gcc.dg/torture/pr97812.c
new file mode 100644
index 0000000..4d468ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97812.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fdisable-tree-evrp" } */
+
+unsigned char c;
+
+int main() {
+volatile short b = 4066;
+ unsigned short bp = b;
+ unsigned d = bp & 2305;
+ signed char e = d;
+ c = e ? : e;
+ if (!d)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97901.c b/gcc/testsuite/gcc.dg/torture/pr97901.c
new file mode 100644
index 0000000..a6a89ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97901.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+int a[1], b, *c, *d;
+
+int main() {
+L:
+ d = c;
+ for (b = 0; b < 2; b++)
+ d = &a[0];
+ if (c)
+ goto L;
+ if (*d)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
index 99a5488..85b6806 100644
--- a/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pta-ptrarith-1.c
@@ -6,11 +6,14 @@ struct Foo {
int *p;
};
+struct Foo *ff;
+
void __attribute__((noinline))
foo (void *p)
{
struct Foo *f = (struct Foo *)p - 1;
*f->p = 0;
+ ff = f;
}
int bar (void)
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
index 180fd72..1915b9a 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-5.c
@@ -11,14 +11,14 @@ foo ()
int * p;
int i;
int x[4];
- long unsigned int _1;
- long unsigned int _2;
+ __SIZETYPE__ _1;
+ __SIZETYPE__ _2;
int _7;
__BB(2):
i_3 = 0;
- _1 = (long unsigned int) i_3;
- _2 = _1 * 4ul;
+ _1 = (__SIZETYPE__) i_3;
+ _2 = _1 * _Literal (__SIZETYPE__) 4;
p_4 = _Literal (int *) &x + _2;
__MEM <v4si> ((v4si *)p_4) = _Literal (v4si) { 1, 2, 3, 4 };
_7 = x[0];
diff --git a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
index 2c4235f..041d921 100644
--- a/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
+++ b/gcc/testsuite/gcc.dg/torture/ssa-fre-6.c
@@ -11,14 +11,14 @@ foo ()
int * p;
int i;
int x[4];
- long unsigned int _1;
- long unsigned int _2;
+ __SIZETYPE__ _1;
+ __SIZETYPE__ _2;
int _7;
__BB(2):
i_3 = 0;
- _1 = (long unsigned int) i_3;
- _2 = _1 * 4ul;
+ _1 = (__SIZETYPE__) i_3;
+ _2 = _1 * _Literal (__SIZETYPE__) 4;
p_4 = _Literal (int *) &x + _2;
__MEM <v4si> ((v4si *)p_4) = _Literal (v4si) {};
_7 = x[0];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
index b7471bf..e8b1644 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/stringop-2.c
@@ -20,6 +20,6 @@ main()
return 0;
}
/* autofdo doesn't support value profiling for now: */
-/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: single value 4 stringop" "profile"} } */
+/* { dg-final-use-not-autofdo { scan-ipa-dump "Transformation done: single value 4 stringop" "profile" { target { ! aarch64*-*-* } } } } */
/* The versioned memset of size 4 should be optimized to an assignment.
- { dg-final-use-not-autofdo { scan-tree-dump "MEM <\[a-z \]+> \\\[\\(void .\\)&a\\\] = 168430090" "optimized" } } */
+ { dg-final-use-not-autofdo { scan-tree-dump "MEM <\[a-z \]+> \\\[\\(void .\\)&a\\\] = 168430090" "optimized" { target { ! aarch64*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
index a94d123..0cc03ff 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-1.c
@@ -112,17 +112,21 @@ void test_sprintf_c_const (void)
T ( 3, "%1$c%2$c", '1', '2');
/* Verify that a warning is issued for exceeding INT_MAX bytes and
- not otherwise. */
+ not otherwise. In ILP32 the maximum object size is INT_MAX - 1
+ bytes so the calls are diagnosed due to the overflow. */
T (-1, "%*c", INT_MAX - 1, '1');
- T (-1, "%*c", INT_MAX, '1');
- T (-1, "X%*c", INT_MAX - 1, '1');
- T (-1, "X%*c", INT_MAX, '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*c", INT_MAX, '1'); /* { dg-warning "writing a terminating nul past the end " "ilp32" { target ilp32 } } */
+ T (-1, "X%*c", INT_MAX - 1, '1'); /* { dg-warning "writing a terminating nul past the end " "ilp32" { target ilp32 } } */
+ T (-1, "X%*c", INT_MAX, '1'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 } */
- T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*c%*c", INT_MAX - 1, '1', INT_MAX - 1, '2'); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483646 bytes into a region of size 1" "ilp32" { target ilp32 } .-1 } */
T (-1, "%*cX", INT_MAX - 2, '1');
- T (-1, "%*cX", INT_MAX - 1, '1');
- T (-1, "%*cX", INT_MAX, '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*cX", INT_MAX - 1, '1'); /* { dg-warning "writing a terminating nul past the end of the destination" "ilp32" { target ilp32 } } */
+ T (-1, "%*cX", INT_MAX, '1'); /* { dg-warning "output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 1 byte into a region of size 0" "ilp32" { target ilp32 } .-1 } */
}
/* Verify that no warning is issued for calls that write into a flexible
@@ -288,8 +292,9 @@ void test_sprintf_chk_s_const (void)
/* Verify that output in excess of INT_MAX bytes is diagnosed even
when the size of the destination object is unknown. */
T (-1, "%*s", INT_MAX - 1, "");
- T (-1, "%*s", INT_MAX, "");
- T (-1, "X%*s", INT_MAX, ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." } */
+ T (-1, "%*s", INT_MAX, ""); /* { dg-warning "writing a terminating nul past the end" "ilp32" { target ilp32 } } */
+ T (-1, "X%*s", INT_MAX, ""); /* { dg-warning "directive output of \[0-9\]+ bytes causes result to exceed .INT_MAX." "lp64" { target lp64 } } */
+ /* { dg-warning "directive writing 2147483647 bytes into a region of size 2147483646" "ilp32" { target ilp32 } .-1 } */
/* Multiple directives. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
index 02072b5..134967d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-11.c
@@ -197,17 +197,21 @@ void test_narrow_string_with_width_and_precision (void)
IR (imax / 9, imax / 8), IR (imax / 7, imax / 6), SR (x, y),
IR (imax / 5, imax / 4), IR (imax / 3, imax / 2), SR (x, y));
- /* The two directives below combined convert to [INT_MAX, INT_MAX + 1].
+ /* The two directives below combined convert to [INT_MAX -1, INT_MAX + 1].
Since the lower end of the range doesn't exceed INT_MAX no warning
is expected. */
T (-1, "%*.*s%*.*s",
- IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
+ IR (imax - 6, imax - 3), IR (1, 2), SR (x, y),
IR ( 5, 6), IR (3, 4), SR (x, y));
/* The three directives below (the two %s plus the space in between)
combined convert to [INT_MAX + 1, INT_MAX + 2]. Since the lower
- end of the range exceeds INT_MAX a warning is expected. */
- T (-1, "%*.*s %*.*s", /* { dg-warning "INT_MAX" } */
+ end of the range exceeds INT_MAX a warning is expected. In ILP32,
+ the output overflows the maximum object size. */
+ T (-1, "%*.*s %*.*s",
+ /* { dg-warning "INT_MAX" "LP64" { target lp64 } .-1 }
+ { dg-warning "directive writing between 5 and 6 bytes into a region of size between 2 and 4" "ILP32" { target ilp32 } .-2 }
+ */
IR (imax - 5, imax - 3), IR (1, 2), SR (x, y),
IR ( 5, 6), IR (3, 4), SR (x, y));
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
index 6a18f17..2c410b1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-18.c
@@ -117,10 +117,10 @@ void test_width_and_precision_out_of_range (char *d)
{
/* The range here happens to be a property of the compiler, not
one of the target. */
- T ("%9223372036854775808i", 0); /* { dg-warning "width out of range" "first" } */
- /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
- T ("%.9223372036854775808i", 0); /* { dg-warning "precision out of range" "first" } */
- /* { dg-warning "exceeds .INT_MAX." "second" { target *-*-* } .-1 } */
+ T ("%9223372036854775808i", 0); /* { dg-warning "width out of range|exceeds 'INT_MAX'" "first" } */
+ /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "" { target ilp32 } .-1 } */
+ T ("%.9223372036854775808i", 0); /* { dg-warning "precision out of range|exceeds 'INT_MAX'" "first" } */
+ /* { dg-warning "directive writing \\d+ bytes into a region of size \\d+" "ilp32" { target ilp32 } .-1 } */
/* The following is diagnosed by -Wformat (disabled here). */
/* T ("%9223372036854775808$i", 0); */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c
new file mode 100644
index 0000000..df46023
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-25.c
@@ -0,0 +1,76 @@
+/* PR middle-end/97373 - missing warning on sprintf into allocated destination
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#include "../range.h"
+
+extern void* alloca (size_t);
+extern void* malloc (size_t);
+
+extern int sprintf (char*, const char*, ...);
+#define sprintf(d, ...) (sprintf (d, __VA_ARGS__), sink (d))
+
+void sink (void*, ...);
+
+void test_alloca_range (void)
+{
+ int n1_2 = UR (1, 2);
+ int n5_9 = UR (5, 9);
+
+ char *d = (char*)alloca (n5_9);
+
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345);
+
+ d += n1_2;
+ sprintf (d, "%i", 12345); // { dg-warning "writing a terminating nul past the end of the destination" }
+
+ d += n1_2;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 4" }
+}
+
+
+void test_malloc_range (void)
+{
+ int n2_3 = UR (2, 3);
+ int n5_9 = UR (5, 9);
+
+ char *d = (char*)malloc (n5_9);
+
+ sprintf (d, "%i", 12345);
+
+ d += n2_3;
+ sprintf (d, "%i", 12345);
+
+ d += n2_3;
+ sprintf (d, "%i", 12345); // { dg-warning "writing a terminating nul past the end of the destination" }
+
+ d += n2_3;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 3" }
+}
+
+
+void test_vla_range (void)
+{
+ int n3_4 = UR (3, 4);
+ int n5_9 = UR (5, 9);
+
+ char vla[n5_9];
+ char *d = vla;
+
+ sprintf (d, "%i", 12345);
+
+ d += n3_4;
+ sprintf (d, "%i", 12345);
+
+ d += n3_4;
+ sprintf (d, "%i", 12345); // { dg-warning "'%i' directive writing 5 bytes into a region of size 3" }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c
new file mode 100644
index 0000000..7d4d55f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp20.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void call (void);
+
+void foo (int base)
+{
+ unsigned i;
+
+ // Ranger should be able to remove the (i > 123) comparison.
+ for (i = base; i < 10; i++)
+ if (i > 123)
+ {
+ call ();
+ return;
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "call" "evrp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c
new file mode 100644
index 0000000..dae788c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp21.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void vrp_keep (void);
+extern void vrp_kill (void);
+
+void
+f2 (int s, int b)
+{
+ if (s > 4)
+ s = 4;
+ if (s < -16)
+ s = -16;
+ /* s in [-16, 4]. */
+ b = (b & 1) + 1;
+ /* b in range [1, 2]. */
+ b = s << b;
+ /* b in range [-64, 16]. */
+ if (b == -2)
+ vrp_keep ();
+ if (b <= -65)
+ vrp_kill ();
+ if (b >= 17)
+ vrp_kill ();
+}
+
+/* { dg-final { scan-tree-dump-times "vrp_keep \\(" 1 "evrp"} } */
+/* { dg-final { scan-tree-dump-times "vrp_kill \\(" 0 "evrp"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c b/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c
new file mode 100644
index 0000000..3dd47e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/evrp22.c
@@ -0,0 +1,43 @@
+/* See backwards thru casts if the range fits the LHS type. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+extern void kill(int i);
+extern void keep(int i);
+
+void
+foo (int i)
+{
+ if (i >= 10)
+ {
+ if (i <= 100)
+ {
+ /* i has a range of [10, 100] */
+ char c = (char) i;
+ if (c < 30)
+ {
+ /* If we wind back thru the cast with the range of c being [10,29]
+ * from the branch, and recognize that the range of i fits within
+ * a cast to c, then there is no missing information in a cast
+ * back to int. We can use the range calculated for 'c' with 'i'
+ * as well and Ranger should be able to kill the call. */
+ if (i > 29)
+ kill (i);
+ }
+ }
+ /* i has a range of [10, MAX] */
+ char d = (char) i;
+ if (d < 30)
+ {
+ /* Here, a cast to a char and back is NOT equivalent, so we cannot use
+ * the value of d to remove the call. */
+ if (i > 29)
+ keep (i);
+ }
+
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "kill \\(" 0 "evrp"} } */
+/* { dg-final { scan-tree-dump-times "keep \\(" 1 "evrp"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c
new file mode 100644
index 0000000..e66fa73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-1.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc == 1)
+ foo ();
+ else if (argc == 2)
+ {
+ global += 1;
+ }
+ else if (argc == 3)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 4)
+ {
+ foo ();
+ }
+ else if (argc == 5)
+ {
+ global = 2;
+ }
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c
new file mode 100644
index 0000000..252bea6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int isMyRandomCharacter(int aChar)
+{
+ return aChar == 0x0001 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000E ||
+ aChar == 0x0020;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c
new file mode 100644
index 0000000..707e630
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int IsMySuperRandomChar(int aChar)
+{
+ return aChar == 0x0009 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000D ||
+ aChar == 0x0020 || aChar == 0x0030;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
new file mode 100644
index 0000000..6a03588
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-4.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc == 1)
+ foo ();
+ else if (argc == 2)
+ {
+ global += 1;
+ }
+ else if (argc == 3)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 4)
+ {
+ foo ();
+ }
+ /* This will be removed with EVRP. */
+ else if (argc == 1)
+ {
+ global = 2;
+ }
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c
new file mode 100644
index 0000000..ceeae90
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-5.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int crud (unsigned char c)
+{
+ return (((((((((((int) c == 46) || (int) c == 44)
+ || (int) c == 58) || (int) c == 59) || (int) c == 60)
+ || (int) c == 62) || (int) c == 34) || (int) c == 92)
+ || (int) c == 39) != 0);
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
new file mode 100644
index 0000000..464b1fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-6.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int foo ();
+
+int main(int argc, char **argv)
+{
+ if (argc >= 1 && argc <= 10)
+ foo ();
+ else if (argc == 12)
+ {
+ global += 1;
+ }
+ else if (argc == 13)
+ {
+ foo ();
+ foo ();
+ }
+ else if (argc == 14)
+ {
+ foo ();
+ }
+ /* This will be removed with EVRP. */
+ else if (argc == 5)
+ {
+ global = 2;
+ }
+ /* This will be removed with EVRP. */
+ else if (argc >= 7 && argc <= 9)
+ {
+ global = 2;
+ }
+
+ else
+ global -= 123;
+
+ global -= 12;
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c
new file mode 100644
index 0000000..4a176f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-7.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+
+int foo(int a)
+{
+ int x = 0;
+ for (unsigned i = 0; i < a; i++)
+ {
+ if (a == 2)
+ {
+ global += 123;
+ x = 1;
+ }
+ else if (a == 3)
+ x = 2;
+ else if (a == 10)
+ x = 3;
+ }
+
+ return x;
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain " "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
new file mode 100644
index 0000000..f43ce7d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-8.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int global;
+int global1;
+int global2;
+int global3;
+
+int foo(int a, int b)
+{
+ int x = 0;
+ for (unsigned i = 0; i < a; i++)
+ {
+ if (b == 1)
+ global += 2;
+ else if (a == 2)
+ global = 123;
+ else if (a == 3)
+ global1 = 1234;
+ else if (a == 10)
+ global2 = 12345;
+ else if (a == 1)
+ global2 = 123456;
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "Condition chain" "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c
new file mode 100644
index 0000000..e67198b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/if-to-switch-9.c
@@ -0,0 +1,11 @@
+/* PR tree-optimization/88702 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-iftoswitch-optimized" } */
+
+int IsHTMLWhitespace(int aChar) {
+ return aChar == 0x0009 || aChar == 0x000A ||
+ aChar == 0x000C || aChar == 0x000D ||
+ aChar == 0x0020;
+}
+
+/* { dg-final { scan-tree-dump "Condition chain with \[^\n\r]\* BBs transformed into a switch statement." "iftoswitch" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
new file mode 100644
index 0000000..d71b757
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loopclosedphi.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fno-tree-ch -w -fdump-tree-loopdone-details" } */
+
+void
+t6 (int qz, int wh)
+{
+ int jl = wh;
+
+ while (1.0 * qz / wh < 1)
+ {
+ qz = wh * (wh + 2);
+
+ while (wh < 1)
+ jl = 0;
+ }
+
+ while (qz < 1)
+ qz = jl * wh;
+}
+
+/* { dg-final { scan-tree-dump-times "Replacing" 2 "loopdone"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c
new file mode 100644
index 0000000..fde3177
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-5.c
@@ -0,0 +1,27 @@
+/* { dg-options "-O2 -fdump-tree-modref1" } */
+/* { dg-do run } */
+__attribute__ ((noinline))
+void
+copy (int *a, int *b)
+{
+ *a=*b;
+}
+int p, *ptr = &p;
+__attribute__ ((noinline))
+void
+barrier ()
+{
+ asm ("":"=r"(ptr):"0"(ptr));
+}
+int
+main()
+{
+ int a = 1, b = 2;
+ copy (&a,&b);
+ barrier ();
+ *ptr = 1;
+ if (!__builtin_constant_p (b == 2))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-tree-dump "parm 1 flags: nodirectescape" "modref1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c b/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
index fb8aebf..a93fcaf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr23401.c
@@ -19,5 +19,5 @@ int ffff(int i)
/* We should not use extra temporaries apart from for i1 + i2. */
-/* { dg-final { scan-tree-dump-times "int" 5 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int" 6 "gimple" } } */
/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c b/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
index 84dfcc9..5c1945b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr27810.c
@@ -13,5 +13,5 @@ int qqq (int a)
/* We should not use an extra temporary for the result of the
function call. */
-/* { dg-final { scan-tree-dump-times "int" 3 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "int" 4 "gimple" } } */
/* { dg-final { scan-tree-dump-times "int D\\\." 1 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c b/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c
new file mode 100644
index 0000000..e9158e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr78655.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fno-tree-fre -fdump-tree-evrp" } */
+
+struct A{int a,b;};
+inline int*f1(struct A*p){return&p->a;} /* offset of 0. */
+inline int*f2(struct A*p){return&p->b;} /* Offset of non-zero. */
+inline int*g(struct A*p){return(int*)p+1;} /* Always non-zero offet. */
+
+/* Should be able to eliminate all calls to bad(). */
+
+void bad(void);
+
+int
+main()
+{
+ struct A* ptr = 0;
+ struct A addr;
+
+ if (f1 (ptr) != 0)
+ bad();
+ if (f1 (&addr) == 0)
+ bad();
+
+ if (f2 (ptr) == 0)
+ bad();
+ if (f2 (&addr) == 0)
+ bad();
+
+ if (g (ptr) == 0)
+ bad();
+ if (g (&addr) == 0)
+ bad();
+
+}
+
+/* { dg-final { scan-tree-dump-not "bad" "evrp"} } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c
new file mode 100644
index 0000000..d52734b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-1.c
@@ -0,0 +1,68 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i, int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (i < 3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i, int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (i <= 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i, int j)
+{
+ if ((i % j) == -3)
+ {
+ xx = (i > -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i, int j)
+{
+ if ((i % j) < 0)
+ {
+ xx = (i >= 0);
+ if (xx)
+ kill ();
+ }
+}
+
+void f5 (int i, int j)
+{
+ if ((i % j) > 42)
+ {
+ xx = (i <= 42);
+ if (xx)
+ kill ();
+ }
+}
+
+void f6 (int i, int j)
+{
+ if ((i % j) < -124)
+ {
+ xx = (i >= -124);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c
new file mode 100644
index 0000000..ad9213a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr91029-2.c
@@ -0,0 +1,98 @@
+/* PR tree-optimization/91029 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+int xx;
+
+void f1 (int i, int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (j <= 3 && j >= -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f2 (int i, int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (j <= 1 && j >= -1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f3 (int i, int j)
+{
+ if ((i % j) == -3)
+ {
+ xx = (j <= 3 && j >= -3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f4 (int i, int j)
+{
+ if ((i % j) < 0)
+ {
+ xx = (j <= 1 && j >= -1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f5 (int i, int j)
+{
+ if ((i % j) > 42)
+ {
+ xx = (j <= 43 && j >= -43);
+ if (xx)
+ kill ();
+ }
+}
+
+void f6 (int i, int j)
+{
+ if ((i % j) < -124)
+ {
+ xx = (j <= 125 && j >= -125);
+ if (xx)
+ kill ();
+ }
+}
+
+void f7 (unsigned int i, unsigned int j)
+{
+ if ((i % j) == 3)
+ {
+ xx = (j <= 3);
+ if (xx)
+ kill ();
+ }
+}
+
+void f8 (unsigned int i, unsigned int j)
+{
+ if ((i % j) > 0)
+ {
+ xx = (j <= 1);
+ if (xx)
+ kill ();
+ }
+}
+
+void f9 (unsigned int i, unsigned int j)
+{
+ if ((i % j) >= 124)
+ {
+ xx = (j <= 124);
+ if (xx)
+ kill ();
+ }
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c
new file mode 100644
index 0000000..5ebd805
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-1.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ int a = arg - 3;
+ unsigned int b = 4;
+ int x = 0x1 << arg;
+
+ if (a < 0)
+ b = x;
+
+ /* In the fullness of time, we will delete this call. */
+ if (b >= 5)
+ kill ();;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c
new file mode 100644
index 0000000..c9b2878
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ unsigned int C000003FE = 4;
+
+ if (arg + 1 < 4) // work for if (arg < 3)
+ C000003FE = 0x1 << arg;
+
+ if (C000003FE >= 5)
+ kill ();
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c
new file mode 100644
index 0000000..e1d2be0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93781-3.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-evrp" } */
+
+void kill (void);
+
+void foo (unsigned int arg)
+{
+ int a = arg - 3;
+ unsigned int b = 4;
+
+ if (a < 0)
+ {
+ int x = 0x1 << arg;
+ b = x;
+ }
+
+ if (b >= 5)
+ kill ();
+}
+
+/* { dg-final { scan-tree-dump-not "kill" "evrp" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
index f2a91ef..fc2103d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
@@ -1,6 +1,6 @@
/* PR tree-optimization/96480 */
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-bit-tests -fno-jump-tables" } */
/* { dg-final { scan-tree-dump " = _\[0-9]* <= 3;" "optimized" } } */
int v[4];
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
index d6139a0..5704952 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96789.c
@@ -1,5 +1,8 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -funroll-loops -ftree-vectorize -fdump-tree-dse-details" } */
+/* Disable loop vectorization to avoid that loop vectorizer
+ optimizes those two loops that operate tmp array so that
+ subsequent dse3 won't eliminate expected tmp stores. */
+/* { dg-options "-O2 -funroll-loops -ftree-slp-vectorize -fno-tree-loop-vectorize -fdump-tree-dse-details" } */
/* Test if scalar cleanup pass takes effects, mainly check
its secondary pass DSE can remove dead stores on array
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c
new file mode 100644
index 0000000..65b6147
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96929.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/96929 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump "baz \\\(\\\);" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "return -1;" 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " >> " "optimized" } } */
+
+int baz (void);
+
+int
+foo (void)
+{
+ return -1 >> baz ();
+}
+
+int
+bar (int y)
+{
+ int z = -1;
+ return z >> y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c
new file mode 100644
index 0000000..57a31e3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97849.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vectorize" } */
+/* { dg-additional-options "-march=armv8.2-a+sve" { target aarch64*-*-* } } */
+
+int a, b, c;
+
+int g() {
+ char i = 0;
+ for (c = 0; c <= 8; c++)
+ --i;
+
+ while (b) {
+ _Bool f = i <= 0;
+ a = (a == 0) ? 0 : f / a;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c
new file mode 100644
index 0000000..0ee0196
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97964.c
@@ -0,0 +1,18 @@
+/* PR tree-optimization/97964 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "link_failure \\\(\\\);" "optimized" } } */
+
+void link_failure (void);
+
+void
+foo (int a)
+{
+ long b = -2;
+ int c = a > 0;
+ int d = b * c;
+ int e = 1 - d;
+ int t = (-1 / e) == 1;
+ if (t != 0)
+ link_failure ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c
new file mode 100644
index 0000000..3c4b468
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-1.c
@@ -0,0 +1,52 @@
+/* PR tree-optimization/97997 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return x_\[0-9]*\\\(D\\\);" 6 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+
+unsigned short
+f1 (unsigned short x)
+{
+ return x * 10 / 10;
+}
+
+unsigned short
+f2 (unsigned short x)
+{
+ int a = x;
+ int b = 10;
+ int c = 10;
+ return a * b / c;
+}
+
+unsigned short
+f3 (unsigned short x)
+{
+ return x * 10U / 10;
+}
+
+unsigned short
+f4 (unsigned short x)
+{
+ unsigned a = x;
+ unsigned b = 10;
+ unsigned c = 10;
+ return a * b / c;
+}
+
+unsigned short
+f5 (unsigned short x, unsigned short y)
+{
+ return (unsigned) x * y / y;
+}
+
+unsigned int
+f6 (unsigned int x, unsigned int y)
+{
+ if (x >= 30000)
+ __builtin_unreachable ();
+ if (y >= ~0U / 30000)
+ __builtin_unreachable ();
+ return x * y / y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c
new file mode 100644
index 0000000..a9d5075
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr97997-2.c
@@ -0,0 +1,41 @@
+/* PR tree-optimization/97997 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized -fwrapv" } */
+/* { dg-final { scan-tree-dump-times "return x_\[0-9]*\\\(D\\\);" 4 "optimized" } } */
+/* { dg-final { scan-tree-dump-not " / " "optimized" } } */
+/* { dg-final { scan-tree-dump-not " \\* " "optimized" } } */
+
+unsigned short
+f1 (unsigned short x)
+{
+ return x * 10 / 10;
+}
+
+unsigned short
+f2 (unsigned short x)
+{
+ int a = x;
+ int b = 10;
+ int c = 10;
+ return a * b / c;
+}
+
+short
+f3 (short x, short y)
+{
+ return x * y / y;
+}
+
+int
+f4 (int x, int y)
+{
+ if (x >= 30000)
+ __builtin_unreachable ();
+ if (x <= -30000)
+ __builtin_unreachable ();
+ if (y >= __INT_MAX__ / 30000)
+ __builtin_unreachable ();
+ if (y <= -__INT_MAX__ / 30000)
+ __builtin_unreachable ();
+ return x * y / y;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c
new file mode 100644
index 0000000..6379624
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98084.c
@@ -0,0 +1,26 @@
+/* PR tree-optimization/98084 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+enum {
+ JSON_VARIANT_STRING,
+ JSON_VARIANT_UNSIGNED,
+ JSON_VARIANT_REAL,
+ JSON_VARIANT_ARRAY,
+ _JSON_VARIANT_TYPE_INVALID,
+ _JSON_VARIANT_MAGIC_ZERO_UNSIGNED,
+ _JSON_VARIANT_MAGIC_ZERO_REAL,
+ _JSON_VARIANT_MAGIC_EMPTY_STRING,
+ _JSON_VARIANT_MAGIC_EMPTY_ARRAY
+} json_variant_type(int *v) {
+ if (!v)
+ return _JSON_VARIANT_TYPE_INVALID;
+ if (v == (int *)_JSON_VARIANT_MAGIC_ZERO_UNSIGNED)
+ return JSON_VARIANT_UNSIGNED;
+ if (v == (int *)_JSON_VARIANT_MAGIC_ZERO_REAL)
+ return JSON_VARIANT_REAL;
+ if (v == (int *)_JSON_VARIANT_MAGIC_EMPTY_STRING)
+ return JSON_VARIANT_STRING;
+ if (v == (int *)_JSON_VARIANT_MAGIC_EMPTY_ARRAY)
+ return JSON_VARIANT_ARRAY;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c b/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c
new file mode 100644
index 0000000..f88534a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr98094.c
@@ -0,0 +1,21 @@
+/* PR tree-optimization/98084 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct
+{
+ unsigned a : 10;
+} b;
+
+int c;
+void e();
+void d ()
+{
+ c = b.a;
+ if (c == 8 || c == 0)
+ ;
+ else if (c > 8 * 8)
+ ;
+ else if (c < 8 * 8)
+ e ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
index 944362a..093e7a5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-32.c
@@ -1,6 +1,6 @@
/* { dg-do run { target { ! "m68k*-*-* mmix*-*-* bfin*-*-* v850*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
-/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details --param logical-op-non-short-circuit=1" } */
+/* { dg-options "-O2 -fno-inline -fdump-tree-reassoc1-details --param logical-op-non-short-circuit=1 -fno-bit-tests" } */
/* { dg-additional-options "-mbranch-cost=2" { target branch_cost } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
index 585b660..479f40f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-8.c
@@ -23,7 +23,7 @@ f (int s, int *c, int *d)
However, this proves to be a useful test for introducing an
initializer with a cast, so we'll keep it as is. */
-/* There are 4 ' * ' instances in the decls (since "int * iftmp.0;" is
- added), 2 parms, 3 in the code. The second one in the code may
- be a widening multiply (for example, on AArch64). */
-/* { dg-final { scan-tree-dump-times " w?\\* " 9 "optimized" } } */
+/* There are 5 ' * ' instances in the decls (since "int * iftmp.0;" is
+ added), 2 parms, 3 in the code, and the return value. The second one
+ in the code may be a widening multiply (for example, on AArch64). */
+/* { dg-final { scan-tree-dump-times " w?\\* " 10 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
index 51ba59c..de3051b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-3.c
@@ -15,4 +15,4 @@ int test (int a, int b, int c, int g)
/* We should hoist and CSE only the multiplication. */
/* { dg-final { scan-tree-dump-times " \\* " 1 "pre" } } */
-/* { dg-final { scan-tree-dump "Insertions: 1" "pre" } } */
+/* { dg-final { scan-tree-dump "HOIST inserted: 1" "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
index ce9cec6..fdb6a3e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-hoist-7.c
@@ -49,6 +49,6 @@ void foo (int a, int b, int c, int d, int e, int x, int y, int z)
/* Now inserting x + y five times is unnecessary but the cascading
cannot be avoided with the simple-minded dataflow. But make sure
- we do the insertions all in the first iteration. */
-/* { dg-final { scan-tree-dump "insert iterations == 2" "pre" } } */
+ we do not iterate PRE insertion. */
+/* { dg-final { scan-tree-dump "insert iterations == 1" "pre" } } */
/* { dg-final { scan-tree-dump "HOIST inserted: 5" "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
index 59af63a..cf93173 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
@@ -24,4 +24,4 @@ bar (int b, int x)
/* We should see the partial redundant loads of f even though they
are using different types (of the same size). */
-/* { dg-final { scan-tree-dump-times "Replaced MEM" 2 "pre" } } */
+/* { dg-final { scan-tree-dump-times "Replaced MEM" 3 "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c b/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
index 149687c..6f70c9d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/switch-1.c
@@ -54,7 +54,7 @@ int foo3 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: JT:0-62" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: BT:0-62" "switchlower1" } } */
int foo4 (int x)
{
@@ -77,7 +77,7 @@ int foo4 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: -100 JT:10-62 600-700" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: -100 BT:10-62 600-700" "switchlower1" } } */
int foo5 (int x)
{
@@ -107,4 +107,4 @@ int foo5 (int x)
}
}
-/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: JT:10-62 600-700 JT:1000-1021 111111" "switchlower1" } } */
+/* { dg-final { scan-tree-dump ";; GIMPLE switch case clusters: BT:10-62 600-700 JT:1000-1021 111111" "switchlower1" } } */
diff --git a/gcc/testsuite/gcc.dg/typeof-2.c b/gcc/testsuite/gcc.dg/typeof-2.c
index 21ef5b0..68f91c6 100644
--- a/gcc/testsuite/gcc.dg/typeof-2.c
+++ b/gcc/testsuite/gcc.dg/typeof-2.c
@@ -1,21 +1,23 @@
-/* Test qualifier discard of typeof for atomic types. */
+/* Test qualifier preservation of typeof and discarded for __auto_type. */
/* { dg-do compile } */
/* { dg-options "-std=c11" } */
-/* Check that the qualifiers are discarded for atomic types. */
+/* Check that the qualifiers are preserved for atomic types. */
extern int i;
extern int * p;
extern int _Atomic const ci;
-extern __typeof (ci) i;
+extern __typeof (ci) ci;
extern int _Atomic volatile vi;
-extern __typeof (vi) i;
+extern __typeof (vi) vi;
extern int * _Atomic restrict ri;
-extern __typeof (ri) p;
+extern __typeof (ri) ri;
+
+/* Check that the qualifiers are discarded for atomic types. */
void f(void)
{
@@ -46,14 +48,16 @@ extern __typeof (nvi) k;
extern int * restrict nri;
extern __typeof (nri) q;
+/* Check that the qualifiers are discarded for non-atomic types. */
+
void g(void)
{
__auto_type aci = nci;
- int const *paci = &aci;
+ int *paci = &aci;
__auto_type avi = nvi;
- int volatile *pavi = &avi;
+ int *pavi = &avi;
__auto_type ari = nri;
- int * restrict *pari = &ari;
+ int **pari = &ari;
}
diff --git a/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
index f8c36a8..24b2fa8 100644
--- a/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
+++ b/gcc/testsuite/gcc.dg/vect/aligned-section-anchors-nest-1.c
@@ -30,4 +30,4 @@ int *foo(void)
return &c[0][0];
}
-/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" { xfail vect_element_align_preferred } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
index a65d951..40bd2e0 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-43.c
@@ -14,4 +14,4 @@ f (int *restrict x, short *restrict y)
}
/* { dg-final { scan-tree-dump-not "mixed mask and nonmask" "slp2" } } */
-/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } xfail vect_variable_length } } } */
+/* { dg-final { scan-tree-dump-not "vector operands from scalars" "slp2" { target { { vect_int && vect_bool_cmp } && { vect_unpack && vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
index 8cd3a6a..e9909cf 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr68892.c
@@ -15,6 +15,6 @@ void foo(void)
/* ??? Due to the gaps we fall back to scalar loads which makes the
vectorization profitable. */
-/* { dg-final { scan-tree-dump "not profitable" "slp2" { xfail *-*-* } } } */
-/* { dg-final { scan-tree-dump-times "BB vectorization with gaps at the end of a load is not supported" 1 "slp2" } } */
-/* { dg-final { scan-tree-dump-times "Basic block will be vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump "not profitable" "slp2" { xfail { ! aarch64*-*-* } } } } */
+/* { dg-final { scan-tree-dump "BB vectorization with gaps at the end of a load is not supported" "slp2" } } */
+/* { dg-final { scan-tree-dump-times "Basic block will be vectorized" 1 "slp2" { xfail aarch64*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
index fe36f90..e27f956 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c
@@ -38,4 +38,7 @@ main (int argc, char **argv)
}
/* { dg-final { scan-tree-dump-times "Basic block will be vectorized using SLP" 1 "slp2" } } */
-/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
+/* Because we disable the cost model, targets with variable-length
+ vectors can end up vectorizing the store to a[0..7] on its own.
+ With the cost model we do something sensible. */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
index 877de4e..495c031 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-vect-call-1.c
@@ -97,4 +97,4 @@ main ()
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 4 "vect" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { { vect_call_copysignf && vect_call_sqrtf } && vect_perm3_int } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
index 3bfe498..6834b9a 100644
--- a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-1.c
@@ -5,8 +5,8 @@ void
vadd (int *dst, int *op1, int *op2, int count)
{
/* { dg-prune-output " version\[^\n\r]* alignment" } */
-/* { dg-optimized "loop vectorized" "" { target *-*-* } .+2 } */
-/* { dg-optimized "loop versioned for vectorization because of possible aliasing" "" { target *-*-* } .+1 } */
+/* { dg-optimized "21: loop vectorized" "" { target *-*-* } .+2 } */
+/* { dg-optimized "21: loop versioned for vectorization because of possible aliasing" "" { target *-*-* } .+1 } */
for (int i = 0; i < count; ++i)
dst[i] = op1[i] + op2[i];
}
diff --git a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
index 94c55a9..23a3b39 100644
--- a/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
+++ b/gcc/testsuite/gcc.dg/vect/nodump-vect-opt-info-2.c
@@ -6,7 +6,7 @@ extern void accumulate (int x, int *a);
int test_missing_function_defn (int *arr, int n) /* { dg-message "vectorized 0 loops in function" } */
{
int sum = 0;
- for (int i = 0; i < n; ++i) /* { dg-missed "couldn't vectorize loop" } */
- accumulate (arr[i], &sum); /* { dg-missed "statement clobbers memory: accumulate \\(.*\\);" } */
+ for (int i = 0; i < n; ++i) /* { dg-missed "21: couldn't vectorize loop" } */
+ accumulate (arr[i], &sum); /* { dg-missed "5: statement clobbers memory: accumulate \\(.*\\);" } */
return sum;
}
diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-8.c b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
index a2a940d..d042679 100644
--- a/gcc/testsuite/gcc.dg/vect/pr65947-8.c
+++ b/gcc/testsuite/gcc.dg/vect/pr65947-8.c
@@ -41,6 +41,6 @@ main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! amdgcn*-*-* } } } } */
-/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target amdgcn*-*-* } } } */
-/* { dg-final { scan-tree-dump "multiple types in double reduction or condition reduction" "vect" { target { ! amdgcn*-*-* } } } } */
+/* { dg-final { scan-tree-dump-not "LOOP VECTORIZED" "vect" { target { ! { amdgcn*-*-* || aarch64_sve } } } } } */
+/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" { target { amdgcn*-*-* || aarch64_sve } } } } */
+/* { dg-final { scan-tree-dump "multiple types in double reduction or condition reduction" "vect" { target { ! { amdgcn*-*-* || aarch64_sve } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr91750.c b/gcc/testsuite/gcc.dg/vect/pr91750.c
index fe914b2..3586f11 100644
--- a/gcc/testsuite/gcc.dg/vect/pr91750.c
+++ b/gcc/testsuite/gcc.dg/vect/pr91750.c
@@ -11,5 +11,5 @@ foo (int n)
}
/* Make sure the induction IV uses an unsigned increment. */
-/* { dg-final { scan-tree-dump "vector\\\(\[0-9\]*\\\) unsigned int" "vect" } } */
+/* { dg-final { scan-tree-dump {vector\([][0-9,]*\) unsigned int} "vect" } } */
/* { dg-final { scan-tree-dump "LOOP VECTORIZED" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97678.c b/gcc/testsuite/gcc.dg/vect/pr97678.c
index ebe4a35..d9ffb7a 100644
--- a/gcc/testsuite/gcc.dg/vect/pr97678.c
+++ b/gcc/testsuite/gcc.dg/vect/pr97678.c
@@ -26,4 +26,5 @@ main ()
}
/* The init loop should be vectorized with SLP. */
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97693.c b/gcc/testsuite/gcc.dg/vect/pr97693.c
new file mode 100644
index 0000000..4da44c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97693.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+extern short a[];
+int b;
+short c, d;
+unsigned e() {
+ if (c)
+ return c;
+ return d;
+}
+void f() {
+ for (unsigned g = b; g; g += 6)
+ for (_Bool h = 0; h < (_Bool)e(); h = 1)
+ a[g] = 1 / b;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97730.c b/gcc/testsuite/gcc.dg/vect/pr97730.c
new file mode 100644
index 0000000..af4bca4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97730.c
@@ -0,0 +1,12 @@
+/* { dg-additional-options "-O1" } */
+unsigned b = 0xce8e5a48, c = 0xb849691a;
+unsigned a[8080];
+int main() {
+ a[0] = b;
+ c = c;
+ unsigned f = 0xb1e8;
+ for (int h = 0; h < 5; h++)
+ a[h] = (b & c) ^ f;
+ if (a[0] != 0x8808f9e0)
+ __builtin_abort();
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97835.c b/gcc/testsuite/gcc.dg/vect/pr97835.c
new file mode 100644
index 0000000..a90c773
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97835.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+struct co {
+ int gx;
+ int ty;
+};
+
+void
+x0 (struct co *yy, long int kc, int wi, int md)
+{
+ while (wi < 1)
+ {
+ yy[wi].gx = md;
+ yy[wi].ty = wi;
+ md += kc;
+ ++wi;
+ }
+}
+
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr97838.c b/gcc/testsuite/gcc.dg/vect/pr97838.c
new file mode 100644
index 0000000..06ec035
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97838.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+
+int a, b, c, d;
+
+void f() {
+ while (c++) {
+ int e = -1;
+ d = a ? e / a : e;
+ b ^= ~d;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr98048.c b/gcc/testsuite/gcc.dg/vect/pr98048.c
new file mode 100644
index 0000000..e61a376
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr98048.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+extern short var_0;
+extern int var_3;
+extern int arr_277[];
+int a(int b, int c) { return b < c ? b : c; }
+int e;
+void test()
+{
+ e = var_0;
+ for (int d = 0; d < 9; d++)
+ if (var_3)
+ arr_277[d] = a(var_0, -var_0);
+}
diff --git a/gcc/testsuite/gcc.dg/vect/slp-21.c b/gcc/testsuite/gcc.dg/vect/slp-21.c
index 1f8c82e..117d65c 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-21.c
@@ -201,6 +201,16 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target { vect_strided4 || vect_extract_even_odd } } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { ! { vect_strided4 || vect_extract_even_odd } } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_strided4 } } } */
+/* Some targets can vectorize the second of the three main loops using
+ hybrid SLP. For 128-bit vectors, the required 4->3 permutations are:
+
+ { 0, 1, 2, 4, 5, 6, 8, 9 }
+ { 2, 4, 5, 6, 8, 9, 10, 12 }
+ { 5, 6, 8, 9, 10, 12, 13, 14 }
+
+ Not all vect_perm targets support that, and it's a bit too specific to have
+ its own effective-target selector, so we just test targets directly. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { aarch64*-*-* arm*-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_strided4 && { ! { aarch64*-*-* arm*-*-* } } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { ! { vect_strided4 } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-46.c b/gcc/testsuite/gcc.dg/vect/slp-46.c
index 58a238a..18476a4 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-46.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-46.c
@@ -94,4 +94,4 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { xfail vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-49.c b/gcc/testsuite/gcc.dg/vect/slp-49.c
index 3f53baf..4141a09 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-49.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-49.c
@@ -34,5 +34,6 @@ main()
return 0;
}
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
/* { dg-final { scan-tree-dump "Loop contains only SLP stmts" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
index 4128cca..ca7803e 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
@@ -80,9 +80,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && {! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
index b137821..b86a3dc 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
@@ -104,9 +104,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
index cc863de..bec1544 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
@@ -103,10 +103,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_load_lanes } } } */
-/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } xfail { vect_perm3_int && vect_load_lanes } } } } */
-/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target { vect_load_lanes } xfail { vect_load_lanes } } } } */
-/* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target { vect_load_lanes } xfail { vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target vect_perm3_int } } } */
+/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes xfail vect_perm3_int } } } */
+/* { dg-final { scan-tree-dump "STORE_LANES" "vect" { target vect_load_lanes xfail vect_perm3_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
index 498999a..346411f 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
@@ -96,9 +96,7 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && {! vect_partial_vectors_usage_1 } } } } } } */
-/* The epilogues are vectorized using partial vectors. */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_perm3_int && { {! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_int && { ! vect_load_lanes } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target vect_load_lanes } } } */
/* { dg-final { scan-tree-dump "Built SLP cancelled: can use load/store-lanes" "vect" { target { vect_perm3_int && vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump "LOAD_LANES" "vect" { target vect_load_lanes } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
index 266b439..cffb011 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
@@ -57,6 +57,8 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_min_max } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_min_max || vect_variable_length } } } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
+/* For variable-length SVE, the number of scalar statements in the
+ reduction exceeds the number of elements in a 128-bit granule. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_min_max || { aarch64_sve && vect_variable_length } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail { aarch64_sve && vect_variable_length } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
index 05cc9ed..7a958f2 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
@@ -55,5 +55,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail vect_no_int_add } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_add || vect_variable_length } } } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
+/* For variable-length SVE, the number of scalar statements in the
+ reduction exceeds the number of elements in a 128-bit granule. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_no_int_add || { aarch64_sve && vect_variable_length } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" { xfail { aarch64_sve && vect_variable_length } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c b/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
index ca57a10..28a99c9 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-35-big-array.c
@@ -20,10 +20,6 @@ int main1 ()
s.b[i] = i;
}
- /* Dependence analysis fails cause s.a and s.b may overlap.
- Try to use runtime aliasing test with versioning, and
- later versioning/vectorization are skipped because the
- overlap is proven at compilation time. */
for (i = 0; i < N; i++)
{
s.a[i] = s.b[i] + 1;
@@ -47,5 +43,4 @@ int main (void)
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
-/* { dg-final { scan-tree-dump "can't determine dependence between" "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-35.c b/gcc/testsuite/gcc.dg/vect/vect-35.c
index 76fe32d..a7ec0f16 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-35.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-35.c
@@ -20,10 +20,6 @@ int main1 ()
s.b[i] = i;
}
- /* Dependence analysis fails cause s.a and s.b may overlap.
- Try to use runtime aliasing test with versioning, and
- later versioning/vectorization are skipped because the
- overlap is proven at compilation time. */
for (i = 0; i < N; i++)
{
s.a[i] = s.b[i] + 1;
@@ -47,5 +43,4 @@ int main (void)
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
-/* { dg-final { scan-tree-dump "can't determine dependence between" "vect" } } */
+/* { dg-final { scan-tree-dump-times "vectorized 2 loops" 1 "vect" { xfail { ia64-*-* sparc*-*-* } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c
new file mode 100644
index 0000000..0737da5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *x, int *y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c
new file mode 100644
index 0000000..fa9bdb6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+void
+f (int *x, int *y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump-not {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c
new file mode 100644
index 0000000..d7c6cfd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-3.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c
new file mode 100644
index 0000000..bb018ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-4.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+int x[1024], y[1024];
+
+void
+f (void)
+{
+ for (unsigned int i = 0; i < 1024; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c
new file mode 100644
index 0000000..536ec0a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-5.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1023; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c b/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c
new file mode 100644
index 0000000..552febb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cost-model-6.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-O2 -ftree-vectorize -fvect-cost-model=very-cheap" } */
+
+void
+f (int *restrict x, int *restrict y)
+{
+ for (unsigned int i = 0; i < 1023; ++i)
+ x[i] += y[i];
+}
+
+/* { dg-final { scan-tree-dump {LOOP VECTORIZED} vect { target { vect_int && vect_partial_vectors_usage_2 } } } } */
+/* { dg-final { scan-tree-dump-not {LOOP VECTORIZED} vect { target { vect_int && { ! vect_partial_vectors_usage_2 } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-epilogues.c b/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
index a146bb6..ab7e8a1 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-epilogues.c
@@ -16,4 +16,4 @@ void pixel_avg( unsigned char *dst, int i_dst_stride,
}
}
-/* { dg-final { scan-tree-dump "LOOP EPILOGUE VECTORIZED" "vect" { target vect_multiple_sizes xfail { arm32 && be } } } } */
+/* { dg-final { scan-tree-dump "LOOP EPILOGUE VECTORIZED" "vect" { target vect_multiple_sizes xfail { { arm32 && be } || vect_partial_vectors_usage_2 } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
index 62b18bd..445157d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-1.c
@@ -27,5 +27,6 @@ void foo (void)
/* We should vectorize this outer loop with SLP. */
/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" } } */
-/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" { xfail vect_variable_length } } } */
/* { dg-final { scan-tree-dump-not "VEC_PERM_EXPR" "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
index 08b4fc5..ec1e103 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-2.c
@@ -48,4 +48,5 @@ int main ()
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
index c67d369..53865d4 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-outer-slp-3.c
@@ -59,4 +59,5 @@ int main ()
}
/* { dg-final { scan-tree-dump-times "OUTER LOOP VECTORIZED" 1 "vect" } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" } } */
+/* We don't yet support SLP inductions for variable length vectors. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail vect_variable_length } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c b/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
index be70bc6..484efb1 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-sdiv-pow2-1.c
@@ -62,7 +62,10 @@ main (void)
{
int p = power2 (fns[i].po2);
for (int j = 0; j < N; j++)
- a[j] = ((p << 4) * j) / (N - 1) - (p << 5);
+ {
+ a[j] = ((p << 4) * j) / (N - 1) - (p << 5);
+ asm volatile ("" ::: "memory");
+ }
fns[i].div (b, a, N);
fns[i].mod (c, a, N);
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 02f6f3d..2afd2b5 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -143,11 +143,11 @@ T (v0 ? b[1] : "", bsz);
T (v0 ? b[2] : "", bsz);
T (v0 ? b[3] : "", bsz);
-T (v0 ? "" : b[0], bsz + 1);
+T (v0 ? "" : b[0], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
T (v0 ? "" : b[1], bsz + 1);
T (v0 ? "" : b[2], bsz + 1);
T (v0 ? "" : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : "", bsz + 1);
+T (v0 ? b[0] : "", bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" } */
T (v0 ? b[1] : "", bsz + 1);
T (v0 ? b[2] : "", bsz + 1);
T (v0 ? b[3] : "", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
@@ -185,8 +185,8 @@ T (v0 ? "1234" : b[i3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfa
T (v0 ? b[3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
T (v0 ? b[i3] : "1234", bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? a : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
-T (v0 ? b[0] : b[2], bsz + 1);
+T (v0 ? a : b[3], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" { xfail *-*-*} } */
+T (v0 ? b[0] : b[2], bsz + 1); /* { dg-warning "bound 6 may exceed source size 5" "pr86937" } */
T (v0 ? b[2] : b[3], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */
T (v0 ? b[3] : b[2], bsz + 1); /* { dg-warning "unterminated" "pr86937" { xfail *-*-* } } */