aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2020-10-12 09:46:38 -0700
committerIan Lance Taylor <iant@golang.org>2020-10-12 09:46:38 -0700
commit9cd320ea6572c577cdf17ce1f9ea5230b166af6d (patch)
treed1c8e7c2e09a91ed75f0e5476c648c2e745aa2de /gcc/testsuite/gcc.dg
parent4854d721be78358e59367982bdd94461b4be3c5a (diff)
parent3175d40fc52fb8eb3c3b18cc343d773da24434fb (diff)
downloadgcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.zip
gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.gz
gcc-9cd320ea6572c577cdf17ce1f9ea5230b166af6d.tar.bz2
Merge from trunk revision 3175d40fc52fb8eb3c3b18cc343d773da24434fb.
Diffstat (limited to 'gcc/testsuite/gcc.dg')
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-30.c3
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-39.c46
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-40.c2
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-46.c3
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-48.c3
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-50.c3
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-58.c26
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-62.c130
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-63.c54
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-64.c60
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-65.c202
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-66.c257
-rw-r--r--gcc/testsuite/gcc.dg/Warray-bounds-67.c36
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-2.c45
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-3.c89
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-4.c119
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-5.c14
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-6.c9
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-7.c25
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter-8.c36
-rw-r--r--gcc/testsuite/gcc.dg/Warray-parameter.c187
-rw-r--r--gcc/testsuite/gcc.dg/Wattributes-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-16.c12
-rw-r--r--gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-9.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wno-frame-address.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wnonnull-4.c173
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstack-usage.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-15.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-22.c54
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-23.c19
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-24.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-25.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-27.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-33.c8
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-34.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-37.c20
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-39.c3
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-40.c120
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-41.c120
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-42.c62
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-43.c179
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-44.c129
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-44.s271
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-45.c255
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-46.c97
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-47.c69
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-49.c146
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-50.c125
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-51.c34
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-52.c62
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-53.c116
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-54.c103
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-55.c97
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow-9.c4
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overflow.c12
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread-2.c117
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread-3.c188
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread-4.c58
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread-5.c76
-rw-r--r--gcc/testsuite/gcc.dg/Wstringop-overread.c716
-rw-r--r--gcc/testsuite/gcc.dg/Wunused-var-4.c33
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-2.c75
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-3.c68
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-4.c99
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-5.c22
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-6.c34
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter-7.c36
-rw-r--r--gcc/testsuite/gcc.dg/Wvla-parameter.c136
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c61
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/abs-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/aliasing-1.c25
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/aliasing-2.c32
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/alloca-leak.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/analyzer.exp2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/bzero-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/bzip2-arg-parse-1.c95
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/casts-1.c49
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/casts-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/compound-assignment-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/compound-assignment-4.c28
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c142
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c33
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-1.c98
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-13.c7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-14.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-18.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-20.c25
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-5.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-5b.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-5c.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-5d.c61
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-6.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/data-model-8.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/describe-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/dot-output.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/explode-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-1.c62
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/feasibility-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/first-field-1.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/first-field-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/getchar-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/init.c136
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/leak-2.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c74
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-2a.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-3.c7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-4.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c35
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c36
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/loop.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-1.c28
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c19
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c84
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c59
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memcpy-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/memset-1.c114
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/paths-3.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/paths-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/paths-6.c4
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/paths-7.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-simplified.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c331
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c79
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-simplified.c45
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93355-localealias.c391
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93382.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93546.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr93938.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94099.c3
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94399.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94447.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94458.c23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94640.c17
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94688.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94689.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94839.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94851-1.c47
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94851-3.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94851-4.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94858-1.c42
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr94858-2.c25
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr95026.c17
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr95152-4.c11
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr95152-5.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr95240.c27
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96598.c26
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96611.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96639.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96642.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96644.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96646.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96648.c36
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c30
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96651-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96651-2.c72
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96653.c1104
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96699.c13
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96705.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96713.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96764.c6
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96777.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96792.c39
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96841.c23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96860-1.c9
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr96860-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr97029.c7
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr97130.c10
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/pr97233.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/refcounting-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/rhbz1878600.c34
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-7a.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-8.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-9.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/setjmp-pr93378.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-4a.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-4b.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-6.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-exit.c1
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c23
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/single-field.c37
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/strcpy-1.c18
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/strdup-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/strndup-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-1.c43
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-2.c32
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-3.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-4.c20
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-5.c29
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/symbolic-6.c24
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/taint-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-3.c18
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/unknown-fns-2.c238
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/unknown-fns-3.c67
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/unknown-fns-4.c15
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/unknown-fns.c8
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/use-after-free.c12
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/vla-1.c14
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c58
-rw-r--r--gcc/testsuite/gcc.dg/analyzer/zlib-4.c10
-rw-r--r--gcc/testsuite/gcc.dg/asan/pr97294.c41
-rw-r--r--gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c1
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-2.c122
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-none.c2
-rw-r--r--gcc/testsuite/gcc.dg/attr-access-read-write-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/attr-alloc_align-5.c23
-rw-r--r--gcc/testsuite/gcc.dg/attr-alloc_size-13.c34
-rw-r--r--gcc/testsuite/gcc.dg/attr-copy-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/attr-copy-6.c1
-rw-r--r--gcc/testsuite/gcc.dg/attr-copy-8.c25
-rw-r--r--gcc/testsuite/gcc.dg/attr-nonstring-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/attr-nonstring-3.c18
-rw-r--r--gcc/testsuite/gcc.dg/attr-nonstring-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/attr-nonstring.c32
-rw-r--r--gcc/testsuite/gcc.dg/attr-section.c13
-rw-r--r--gcc/testsuite/gcc.dg/bad-binary-ops.c8
-rw-r--r--gcc/testsuite/gcc.dg/builtin-apply2.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-21.c3
-rw-r--r--gcc/testsuite/gcc.dg/builtin-object-size-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c30
-rw-r--r--gcc/testsuite/gcc.dg/c11-align-9.c4
-rw-r--r--gcc/testsuite/gcc.dg/cdce3.c3
-rw-r--r--gcc/testsuite/gcc.dg/const-uniq-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/darwin-sections.c42
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/align-as-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c4
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c69
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-attribute.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-keyword.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-7.c16
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-8.c11
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c17
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c17
-rw-r--r--gcc/testsuite/gcc.dg/dfp/composite-type.c3
-rw-r--r--gcc/testsuite/gcc.dg/fold-parity-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/fold-parity-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/fold-parity-3.c20
-rw-r--r--gcc/testsuite/gcc.dg/fold-parity-4.c20
-rw-r--r--gcc/testsuite/gcc.dg/fold-parity-5.c38
-rw-r--r--gcc/testsuite/gcc.dg/fold-popcount-5.c38
-rw-r--r--gcc/testsuite/gcc.dg/format/branch-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/format/pr79210.c2
-rw-r--r--gcc/testsuite/gcc.dg/format/pr96935.c9
-rw-r--r--gcc/testsuite/gcc.dg/gimplefe-44.c2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/block-7.c12
-rw-r--r--gcc/testsuite/gcc.dg/gomp/gomp.exp2
-rw-r--r--gcc/testsuite/gcc.dg/gomp/simd-2.c51
-rw-r--r--gcc/testsuite/gcc.dg/gomp/simd-3.c51
-rw-r--r--gcc/testsuite/gcc.dg/ia64-sync-5.c83
-rw-r--r--gcc/testsuite/gcc.dg/ifcvt-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/independent-cloneids-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-loophint-1.c29
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr96482-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr96482.c44
-rw-r--r--gcc/testsuite/gcc.dg/ipa/remref-2a.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/symver1.c12
-rw-r--r--gcc/testsuite/gcc.dg/loop-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-1_0.c14
-rw-r--r--gcc/testsuite/gcc.dg/lto/modref-1_1.c13
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr96291.h4
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr96291_0.c11
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr96291_1.c3
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr96291_2.c7
-rw-r--r--gcc/testsuite/gcc.dg/memchr-2.c41
-rw-r--r--gcc/testsuite/gcc.dg/memchr.c94
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-2.c183
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-3.c349
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-4.c81
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-5.c72
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-6.c47
-rw-r--r--gcc/testsuite/gcc.dg/memcmp-pr95189.c28
-rw-r--r--gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c142
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-plain.c42
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c16
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp2
-rw-r--r--gcc/testsuite/gcc.dg/pr21137.c20
-rw-r--r--gcc/testsuite/gcc.dg/pr30957-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr44194-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-19.c6
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-22.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-24.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr51628-34.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr51683.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr53037-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr55940.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr78902.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr79214.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr81192.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr84131.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr86314.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr87314-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr87485.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr88928.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr93986.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr94234-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr94234-2.c39
-rw-r--r--gcc/testsuite/gcc.dg/pr94234-3.c42
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-1.c41
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-2.c34
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-3.c40
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-4.c34
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-5.c34
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-6.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-7.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr94600-8.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr95133.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr95857.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr96298.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr96335.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr96370.c8
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-1.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-2.c31
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-3.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-4.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-5.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr96377-6.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr96453.c22
-rw-r--r--gcc/testsuite/gcc.dg/pr96466.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr96514.c27
-rw-r--r--gcc/testsuite/gcc.dg/pr96558.c32
-rw-r--r--gcc/testsuite/gcc.dg/pr96579.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr96818.c14
-rw-r--r--gcc/testsuite/gcc.dg/pr96931.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr97078.c9
-rw-r--r--gcc/testsuite/gcc.dg/pr97192.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr97238.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr97315-2.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr97317.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr97322.c17
-rw-r--r--gcc/testsuite/gcc.dg/pr97357.c39
-rw-r--r--gcc/testsuite/gcc.dg/pr97359.c11
-rw-r--r--gcc/testsuite/gcc.dg/pr97371.c8
-rw-r--r--gcc/testsuite/gcc.dg/pubtypes-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pubtypes-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/pubtypes-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/redecl-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/sinatan-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/sinhovercosh-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-inttypes.c2
-rw-r--r--gcc/testsuite/gcc.dg/store_merging_31.c27
-rw-r--r--gcc/testsuite/gcc.dg/store_merging_32.c129
-rw-r--r--gcc/testsuite/gcc.dg/strcmpopt_10.c2
-rw-r--r--gcc/testsuite/gcc.dg/strcmpopt_12.c17
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-55.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-57.c6
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-83.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-84.c3
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-91.c3
-rw-r--r--gcc/testsuite/gcc.dg/strncmp-3.c57
-rw-r--r--gcc/testsuite/gcc.dg/tanhbysinh.c3
-rw-r--r--gcc/testsuite/gcc.dg/tls/thr-cse-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/torture/20200727-0.c82
-rw-r--r--gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr39074-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr39074.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57147-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57147-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr59330.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr92088-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr92088-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr93124.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr94479.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96130.c26
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96133.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96349.c25
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96491.c29
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96522.c36
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96548.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr96760.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97135.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97330-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr97330-2.c14
-rw-r--r--gcc/testsuite/gcc.dg/torture/pta-callused-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-malloc.c49
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-topn.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/pr96394.c64
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/andnot-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtins-folding-gimple-ub.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/copy-sign-3.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/local-pure-const.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-19.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-1.c45
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-2.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/modref-3.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93121-1.c56
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr94801.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr95433.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr95906.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96480.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96730.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96820.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96967.c36
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c38
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c27
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-40.c16
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-88.c18
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-17.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/uninit-32.c3
-rw-r--r--gcc/testsuite/gcc.dg/uninit-33.c2
-rw-r--r--gcc/testsuite/gcc.dg/uninit-36.c3
-rw-r--r--gcc/testsuite/gcc.dg/uninit-37.c154
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-22.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-24.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-27.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-29.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-31.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-32.c7
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-34.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-35.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-36.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-38.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-45.c36
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-46.c28
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-47.c14
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-48.c55
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-49.c28
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-50.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-51.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8a.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8b.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-div-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-phis-1.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pow-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr58135.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c5
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr78205.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr90006.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pr95866.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr69297.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr37027.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr65947-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr67790.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr92324-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr92558.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr95495.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr96698.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr96783-1.c38
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr96783-2.c29
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr96854.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr96920.c20
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97081-2.c32
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97081.c26
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97085.c13
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97139.c27
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97173.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97236.c43
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr97241.c19
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-3.c8
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-46.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c4
-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.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-7.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-perm-9.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/slp-reduc-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-cond-13.c38
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-live-6.c31
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-reduc-in-order-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-17.c304
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-18.c40
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-19.c40
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-simd-20.c43
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-version-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c8
-rw-r--r--gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c18
605 files changed, 16014 insertions, 941 deletions
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-30.c b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
index b996568..048a95d 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-30.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-30.c
@@ -73,8 +73,7 @@ void test_global_int_array (void)
T (&p[min]); /* { dg-warning "subscript -\[0-9\]+ is \(below|outside\) array bounds of .int\\\[1]." } */
T (&p[-1]); /* { dg-warning "subscript -1 is \(below|outside\) array bounds of .int\\\[1]." } */
- T (&p[0]);
- T (&p[1]);
+ T (&p[0], &p[1]);
T (&p[2]); /* { dg-warning "subscript 2 is \(above|outside\) array bounds of .int\\\[1]." } */
T (&p[max]); /* { dg-warning "subscript \[0-9\]+ is \(above|outside\) array bounds of .int\\\[1]." } */
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-39.c b/gcc/testsuite/gcc.dg/Warray-bounds-39.c
index f10ffac..8317656 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-39.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-39.c
@@ -21,65 +21,65 @@ char d[4];
void* test_memcpy_s0_1 (void *d)
{
- return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s0_2 (void *d)
{
- return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s0_0_1 (void *d)
{
- return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s0_0_2 (void *d)
{
- return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s0_1_1 (void *d)
{
- return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s0_1_2 (void *d)
{
- return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s0_1, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s1_0_1 (void *d)
{
- return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_s1_0_2 (void *d)
{
- return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, s1_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memmove_s0_1 (void *d)
{
- return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memmove (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memmove_s0_2 (void *d)
{
- return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memmove (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memmove_s0_0_1 (void *d)
{
- return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memmove (d, s0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memmove_s0_0_2 (void *d)
{
- return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memmove (d, s0_0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
@@ -92,57 +92,57 @@ const struct Empty e1_0[1][0] = { };
void* test_memcpy_e_1 (void *d)
{
- return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, &e, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_e0_1 (void *d)
{
- return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, e0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_e0_0_1 (void *d)
{
- return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, e0_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_e0_1_1 (void *d)
{
- return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, e0_1, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
void* test_memcpy_e1_0_1 (void *d)
{
- return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return memcpy (d, e1_0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strcpy_s0 (char *d)
{
- return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strcpy (d, s0); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strcpy_s0_0 (char *d)
{
- return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strcpy (d, s0_0[0]); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strncpy_s0_1 (char *d)
{
- return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strncpy (d, s0, 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strncpy_s0_2 (char *d)
{
- return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strncpy (d, s0, 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strncpy_s0_0_1 (char *d)
{
- return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strncpy (d, s0_0[0], 1); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
char* test_strncpy_s0_0_2 (char *d)
{
- return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overflow" } */
+ return strncpy (d, s0_0[0], 2); /* { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" } */
}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-40.c b/gcc/testsuite/gcc.dg/Warray-bounds-40.c
index aabc283..c389d96 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-40.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-40.c
@@ -3,7 +3,7 @@
functions when -Wstringop-overflow is disabled is -Warray-bounds
with the right wording.
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-stringop-overflow" } */
+ { dg-options "-O2 -Wall -Wno-stringop-overflow -Wno-stringop-overread" } */
#define PTRDIFF_MAX __PTRDIFF_MAX__
#define SIZE_MAX __SIZE_MAX__
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-46.c b/gcc/testsuite/gcc.dg/Warray-bounds-46.c
index 3f1c6c7..4effe5c 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-46.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-46.c
@@ -3,7 +3,8 @@
Test to verify that past-the-end accesses by string functions to member
arrays by-reference objects are diagnosed.
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-unused-local-typedefs -Wno-stringop-overflow -ftrack-macro-expansion=0" } */
+ { dg-options "-O2 -Wall -Wno-unused-local-typedefs -Wno-stringop-overflow -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
#define SA(expr) typedef int StaticAssert [2 * !!(expr) - 1]
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-48.c b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
index d6a327e..13373d1 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-48.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-48.c
@@ -1,7 +1,8 @@
/* PR middle-end/91647 - missing -Warray-bounds accessing a zero-length array
of a declared object
{ dg-do "compile" }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
typedef __INT16_TYPE__ int16_t;
typedef __INT32_TYPE__ int32_t;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-50.c b/gcc/testsuite/gcc.dg/Warray-bounds-50.c
index d6edfac..05c89b2 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-50.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-50.c
@@ -1,6 +1,7 @@
/* PR middle-end/92349 - ICE in -Warray-bounds on a VLA member
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-58.c b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
index 7bd6df2..849457e5 100644
--- a/gcc/testsuite/gcc.dg/Warray-bounds-58.c
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-58.c
@@ -1,5 +1,5 @@
/* { dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall -Wno-stringop-overread" } */
typedef __SIZE_TYPE__ size_t;
@@ -15,8 +15,8 @@ void fa0_extern (void)
{
sink (strlen (ea0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ea0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ea0.a)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ea0.a + 1)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (ea0.a)); // valid just-past-the-end offset
+ sink (strlen (ea0.a + 1)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
static struct A0 sa0 = { 0 };
@@ -25,8 +25,8 @@ void fa0_static (void)
{
sink (strlen (sa0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (sa0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (sa0.a)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (sa0.a + 1)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (sa0.a)); // valid just-past-the-end offset
+ sink (strlen (sa0.a + 1)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
@@ -52,23 +52,23 @@ void fax_static (void)
sink (strlen (ax0.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax0.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax0.a));
- sink (strlen (ax0.a + 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ax0.a + 2)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (ax0.a + 1)); // valid just-past-the-end offset
+ sink (strlen (ax0.a + 2)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax1.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax1.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax1.a));
sink (strlen (ax1.a + 1));
- sink (strlen (ax1.a + 2)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ax1.a + 3)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (ax1.a + 2)); // valid just-past-the-end offset
+ sink (strlen (ax1.a + 3)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax2.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax2.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
sink (strlen (ax2.a));
sink (strlen (ax2.a + 1));
sink (strlen (ax2.a + 2));
- sink (strlen (ax2.a + 3)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ax2.a + 4)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (ax2.a + 3)); // valid just-past-the-end offset
+ sink (strlen (ax2.a + 4)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
sink (strlen (ax3.a - 2)); // { dg-warning "\\\[-Warray-bounds" }
sink (strlen (ax3.a - 1)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
@@ -76,6 +76,6 @@ void fax_static (void)
sink (strlen (ax3.a + 1));
sink (strlen (ax3.a + 2));
sink (strlen (ax3.a + 3));
- sink (strlen (ax3.a + 4)); // { dg-warning "\\\[-Warray-bounds" "pr93514" { xfail *-*-* } }
- sink (strlen (ax3.a + 5)); // { dg-warning "\\\[-Warray-bounds" }
+ sink (strlen (ax3.a + 4)); // valid just-past-the-end offset
+ sink (strlen (ax3.a + 5)); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-62.c b/gcc/testsuite/gcc.dg/Warray-bounds-62.c
new file mode 100644
index 0000000..c2421aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-62.c
@@ -0,0 +1,130 @@
+/* PR tree-optimization/84079 - missing -Warray-bounds taking the address
+ of past-the-end element of a multidimensional array
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+void sink (int, ...);
+
+#define T(type, dims, inxs) \
+ do { \
+ type a dims; \
+ sink (__LINE__, &a inxs); \
+ } while (0)
+
+
+void test_char_1_1 (int i0, int i1, int i2)
+{
+#undef DIMS
+#define DIMS [1][1]
+
+ T (char, DIMS, [0]);
+ T (char, DIMS, [1]);
+ T (char, DIMS, [2]); // { dg-warning "subscript 2 is above array bounds of 'char\\\[1]\\\[1]'" }
+
+ T (char, DIMS, [0][0]);
+ T (char, DIMS, [0][1]);
+ T (char, DIMS, [0][2]); // { dg-warning "subscript 2 is above array bounds of 'char\\\[1]'" }
+
+ T (char, DIMS, [1][0]); // { dg-warning "subscript 1 is above array bounds of 'char\\\[1]\\\[1]'" }
+ T (char, DIMS, [1][1]); // { dg-warning "subscript 1 is above array bounds of 'char\\\[1]\\\[1]'" }
+ T (char, DIMS, [1][2]); // { dg-warning "subscript 2 is above array bounds of 'char\\\[1]'" }
+
+ // Exercise ranges.
+ if (i0 < 0) i0 = 0;
+ if (i1 < 1) i1 = 1;
+ if (i2 < 2) i2 = 2;
+
+ T (char, DIMS, [i0]);
+ T (char, DIMS, [i1]);
+ T (char, DIMS, [i2]); // { dg-warning "subscript 2 is above array bounds of 'char\\\[1]\\\[1]" }
+
+ T (char, DIMS, [i0][i0]);
+ T (char, DIMS, [i0][i1]);
+ T (char, DIMS, [i1][i0]); // { dg-warning "subscript 1 is above array bounds of 'char\\\[1]\\\[1]'" }
+ T (char, DIMS, [i1][i1]); // { dg-warning "subscript 1 is above array bounds of 'char\\\[1]\\\[1]'" }
+ T (char, DIMS, [i1][i2]); // { dg-warning "subscript 2 is above array bounds of 'char\\\[1]'" }
+}
+
+
+void test_int_3_5 (int i0, int i1, int i2, int i3, int i4, int i5, int i6)
+{
+#undef DIMS
+#define DIMS [3][5]
+
+ T (int, DIMS, [0]);
+ T (int, DIMS, [3]);
+ T (int, DIMS, [4]); // { dg-warning "subscript 4 is above array bounds of 'int\\\[3]\\\[5]'" }
+
+ T (int, DIMS, [0][0]);
+ T (int, DIMS, [0][5]);
+ T (int, DIMS, [0][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [1][0]);
+ T (int, DIMS, [1][5]);
+ T (int, DIMS, [1][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [3][0]); // { dg-warning "subscript 3 is above array bounds of 'int\\\[3]\\\[5]'" }
+ T (int, DIMS, [3][5]); // { dg-warning "subscript 3 is above array bounds of 'int\\\[3]\\\[5]'" }
+ T (int, DIMS, [3][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ // Exercise ranges.
+ if (i0 < 0) i0 = 0;
+ if (i1 < 1) i1 = 1;
+ if (i2 < 2) i2 = 2;
+ if (i3 < 3) i3 = 3;
+ if (i4 < 4) i4 = 4;
+ if (i5 < 5) i5 = 5;
+ if (i6 < 6) i6 = 6;
+
+ T (int, DIMS, [i0]);
+ T (int, DIMS, [i3]);
+ T (int, DIMS, [i4]); // { dg-warning "subscript 4 is above array bounds of 'int\\\[3]\\\[5]" }
+
+ T (int, DIMS, [i0][i0]);
+ T (int, DIMS, [i0][i5]);
+ T (int, DIMS, [i0][i6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [i1][i0]);
+ T (int, DIMS, [i1][i5]);
+ T (int, DIMS, [i1][i6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [i3][i0]); // { dg-warning "subscript 3 is above array bounds of 'int\\\[3]\\\[5]'" }
+ T (int, DIMS, [i3][i5]); // { dg-warning "subscript 3 is above array bounds of 'int\\\[3]\\\[5]'" }
+ T (int, DIMS, [i3][i6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+}
+
+
+void test_int_2_3_4_5 (void)
+{
+#undef DIMS
+#define DIMS [2][3][4][5]
+
+ T (int, DIMS, [0]);
+ T (int, DIMS, [2]);
+ T (int, DIMS, [3]); // { dg-warning "subscript 3 is above array bounds of 'int\\\[2]\\\[3]\\\[4]\\\[5]'" }
+
+ T (int, DIMS, [0][0]);
+ T (int, DIMS, [0][3]);
+ T (int, DIMS, [0][4]); // { dg-warning "subscript 4 is above array bounds of 'int\\\[3]\\\[4]\\\[5]'" }
+ T (int, DIMS, [0][9]); // { dg-warning "subscript 9 is above array bounds of 'int\\\[3]\\\[4]\\\[5]'" }
+
+ T (int, DIMS, [0][0][0]);
+ T (int, DIMS, [0][0][4]);
+ T (int, DIMS, [0][0][5]); // { dg-warning "subscript 5 is above array bounds of 'int\\\[4]\\\[5]'" }
+
+ T (int, DIMS, [0][0][0][0]);
+ T (int, DIMS, [0][0][0][5]);
+ T (int, DIMS, [0][0][0][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [0][0][1][0]);
+ T (int, DIMS, [0][0][1][5]);
+ T (int, DIMS, [0][0][1][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [0][0][3][0]);
+ T (int, DIMS, [0][0][3][5]);
+ T (int, DIMS, [0][0][3][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+
+ T (int, DIMS, [0][0][1][0]);
+ T (int, DIMS, [0][0][1][5]);
+ T (int, DIMS, [0][0][1][6]); // { dg-warning "subscript 6 is above array bounds of 'int\\\[5]'" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-63.c b/gcc/testsuite/gcc.dg/Warray-bounds-63.c
new file mode 100644
index 0000000..a3fc918
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-63.c
@@ -0,0 +1,54 @@
+/* PR middle-end/94195 - missing warning reading a smaller object via
+ an lvalue of a larger type
+ { dg-do compile }
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* alloca (size_t);
+
+void sink (void*);
+
+
+void byte_store_to_decl (void)
+{
+ struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
+
+ char *p = (char*)&s;
+
+ p[0] = 0; p[1] = 1; p[2] = 2; p[3] = 3; p[4] = 4; p[5] = 5;
+ p[6] = 6; // { dg-warning "array subscript 6 is outside array bounds of 'struct S6\\\[1]" }
+
+ sink (&s);
+}
+
+
+void word_store_to_decl (void)
+{
+ struct S6 { char a[6]; } s; // { dg-message "referencing 's'" }
+
+ char *p = (char*)&s;
+
+ int16_t *q = (int16_t*)(p + 1);
+
+ q[0] = 0; q[1] = 1;
+ q[2] = 2; // { dg-warning "array subscript 'int16_t {aka short int}\\\[2]' is partly outside array bounds of 'struct S6\\\[1]'" }
+
+ sink (&s);
+}
+
+
+void word_store_to_alloc (void)
+{
+ struct S6 { char a[6]; } *p;
+ p = alloca (sizeof *p); // { dg-message "referencing an object of size 6 allocated by 'alloca'" }
+
+ int16_t *q = (int16_t*)((char*)p + 1);
+
+ q[0] = 0; q[1] = 1;
+ q[2] = 2; // { dg-warning "array subscript 'int16_t {aka short int}\\\[2]' is partly outside array bounds of 'unsigned char\\\[6]'" }
+
+ sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-64.c b/gcc/testsuite/gcc.dg/Warray-bounds-64.c
new file mode 100644
index 0000000..88b88de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-64.c
@@ -0,0 +1,60 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+
+ Verify that out-of-bounds accesses to array arguments are diagnosed,
+ both to ordinary array parameters with constant bounds and to array
+ parameters declared static. This is the converse of what PR 50584
+ asks for.
+
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Warray-parameter -Wno-vla-paramater" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+void sink (void*, ...);
+
+#define T(...) sink (0, __VA_ARGS__)
+
+
+NOIPA void fca1 (char a[1])
+{
+ T (a[0]);
+ T (a[1]); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void fcas1 (char a[static 1])
+{
+ T (a[0]);
+ T (a[1]); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void fca2 (char a[2])
+{
+ T (a[0]); T (a[1]);
+ T (a[2]); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void fcas2 (char a[static 2])
+{
+ T (a[0]); T (a[1]);
+ T (a[2]); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void fca3 (char a[3])
+{
+ T (a[0]); T (a[1]); T (a[2]);
+ T (a[3]); // { dg-warning "-Warray-bounds" }
+}
+
+NOIPA void fcas3 (char a[static 3])
+{
+ T (a[0]); T (a[1]); T (a[2]);
+ T (a[3]); // { dg-warning "-Warray-bounds" }
+}
+
+
+NOIPA void fca1_1 (char a[1][1])
+{
+ T (a[0][0]);
+ T (a[0][1]); // { dg-warning "-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-65.c b/gcc/testsuite/gcc.dg/Warray-bounds-65.c
new file mode 100644
index 0000000..6bd50d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-65.c
@@ -0,0 +1,202 @@
+/* PR middle-end/84051 - missing -Warray-bounds on an out-of-bounds access
+ via an array pointer
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+void sink (void*, ...);
+#define T(x) sink (0, x)
+
+void
+test_note (int (*pia3)[3]) // { dg-message "while referencing 'pia3'" }
+{
+ int i = 0;
+ T ((*pia3)[i++]);
+ T ((*pia3)[i++]);
+ T ((*pia3)[i++]);
+ T ((*pia3)[i++]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" }
+ T ((*pia3)[i++]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[3]'" }
+
+ {
+ /* Regrettably, the following isn't diagnosed because it's represented
+ the same as the possibly valid access below:
+ MEM[(int *)a_1(D) + 36B] = 0; */
+ int *p0 = pia3[0];
+ T (p0[3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" "pr?????" { xfail *-*-* } }
+
+ int *p1 = pia3[3];
+ T (p1[0]); // okay
+ }
+}
+
+void test_a1_cst (_Bool (*pba0)[0], char (*pca1)[1],
+ short (*psa2)[2], int (*pia3)[3])
+{
+ T ((*pba0)[-1]); // { dg-warning "array subscript -1 is (above|outside) array bounds of '_Bool\\\[0]'" }
+ T ((*pba0)[0]); // { dg-warning "array subscript 0 is (above|outside) array bounds of '_Bool\\\[0]'" }
+ T ((*pba0)[1]); // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[0]'" }
+ T ((*pba0)[2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[0]'" }
+ T ((*pba0)[12]); // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[0]'" }
+
+ T ((*pca1)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'char\\\[1]'" }
+ T ((*pca1)[0]);
+ T ((*pca1)[1]); // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]'" }
+ T ((*pca1)[2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[1]'" }
+ T ((*pca1)[123]); // { dg-warning "array subscript 123 is (above|outside) array bounds of 'char\\\[1]'" }
+
+ T ((*psa2)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'short int\\\[2]'" }
+ T ((*psa2)[0]);
+ T ((*psa2)[1]);
+ T ((*psa2)[2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]'" }
+ T ((*psa2)[1234]); // { dg-warning "array subscript 1234 is (above|outside) array bounds of 'short int\\\[2]'" }
+
+ T ((*pia3)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'int\\\[3]'" }
+ T ((*pia3)[0]);
+ T ((*pia3)[1]);
+ T ((*pia3)[2]);
+ T ((*pia3)[3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]'" }
+ T ((*pia3)[12345]); // { dg-warning "array subscript 12345 is (above|outside) array bounds of 'int\\\[3]'" }
+}
+
+
+void test_a2_cst (_Bool (*pba0_1)[0][1], char (*pca1_2)[1][2],
+ short (*psa2_3)[2][3], int (*pia3_4)[3][4])
+{
+ T ((*pba0_1)[-1][-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[-1][0]); // { dg-warning "array subscript -1 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
+
+ T ((*pba0_1)[0][-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[0][0]); // { dg-warning "array subscript 0 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
+ T ((*pba0_1)[0][1]); // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[0][2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[0][12]); // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[1]'" }
+
+ T ((*pba0_1)[1][-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[1][0]); // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[0]\\\[1]'" }
+ T ((*pba0_1)[1][1]); // { dg-warning "array subscript 1 is (above|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[1][2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of '_Bool\\\[1]'" }
+ T ((*pba0_1)[1][12]); // { dg-warning "array subscript 12 is (above|outside) array bounds of '_Bool\\\[1]'" }
+
+
+ T ((*pca1_2)[0][0]);
+ T ((*pca1_2)[0][1]);
+ T ((*pca1_2)[0][2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[2]'" }
+
+ T ((*pca1_2)[1][0]); // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]\\\[2]'" }
+ T ((*pca1_2)[1][1]); // { dg-warning "array subscript 1 is (above|outside) array bounds of 'char\\\[1]\\\[2]'" }
+ T ((*pca1_2)[1][2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'char\\\[2]'" }
+
+
+ T ((*psa2_3)[0][0]);
+ T ((*psa2_3)[0][1]);
+ T ((*psa2_3)[0][2]);
+ T ((*psa2_3)[0][3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
+
+ T ((*psa2_3)[1][0]);
+ T ((*psa2_3)[1][1]);
+ T ((*psa2_3)[1][2]);
+ T ((*psa2_3)[1][3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
+
+ T ((*psa2_3)[2][0]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
+ T ((*psa2_3)[2][1]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
+ T ((*psa2_3)[2][2]); // { dg-warning "array subscript 2 is (above|outside) array bounds of 'short int\\\[2]\\\[3]'" }
+ T ((*psa2_3)[2][3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'short int\\\[3]'" }
+
+
+ T ((*pia3_4)[0][0]);
+ T ((*pia3_4)[0][1]);
+ T ((*pia3_4)[0][2]);
+ T ((*pia3_4)[0][3]);
+ T ((*pia3_4)[0][4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
+
+ T ((*pia3_4)[1][0]);
+ T ((*pia3_4)[1][1]);
+ T ((*pia3_4)[1][2]);
+ T ((*pia3_4)[1][3]);
+ T ((*pia3_4)[1][4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
+
+ T ((*pia3_4)[2][0]);
+ T ((*pia3_4)[2][1]);
+ T ((*pia3_4)[2][2]);
+ T ((*pia3_4)[2][3]);
+ T ((*pia3_4)[2][4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
+
+ T ((*pia3_4)[3][0]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
+ T ((*pia3_4)[3][1]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
+ T ((*pia3_4)[3][2]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
+ T ((*pia3_4)[3][3]); // { dg-warning "array subscript 3 is (above|outside) array bounds of 'int\\\[3]\\\[4]'" }
+ T ((*pia3_4)[3][4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'int\\\[4]'" }
+}
+
+
+typedef int IA4[4];
+typedef IA4 IA3_4[3];
+
+void test_a2_var (IA3_4 *pia3_4)
+{
+ {
+ IA4 *pia4 = &(*pia3_4)[0];
+
+ T ((*pia4)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
+ T ((*pia4)[0]);
+ T ((*pia4)[1]);
+ T ((*pia4)[2]);
+ T ((*pia4)[3]);
+ T ((*pia4)[4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
+ }
+
+ {
+ IA4 *pia4 = &(*pia3_4)[1];
+
+ T ((*pia4)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
+ T ((*pia4)[0]);
+ T ((*pia4)[1]);
+ T ((*pia4)[2]);
+ T ((*pia4)[3]);
+ T ((*pia4)[4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
+ }
+
+ {
+ IA4 *pia4 = &(*pia3_4)[2];
+
+ T ((*pia4)[-1]); // { dg-warning "array subscript -1 is (below|outside) array bounds of 'IA4'" }
+ T ((*pia4)[0]);
+ T ((*pia4)[1]);
+ T ((*pia4)[2]);
+ T ((*pia4)[3]);
+ T ((*pia4)[4]); // { dg-warning "array subscript 4 is (above|outside) array bounds of 'IA4'" }
+ }
+
+ {
+ IA4 *pia4 = &(*pia3_4)[3];
+
+ T ((*pia4)[-1]); // { dg-warning "\\\[-Warray-bounds" }
+ /* The following aren't diagnosed unless N itself is out of bounds
+ because thanks to the MEM_REF they're indistinguishable from
+ possibly valid accesses:
+ MEM[(int[4] *)pia3_4_2(D) + 48B][N]; */
+ T ((*pia4)[0]); // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+ T ((*pia4)[1]); // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+ T ((*pia4)[2]); // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+ T ((*pia4)[3]); // { dg-warning "\\\[-Warray-bounds" "pr?????" { xfail *-*-* } }
+ T ((*pia4)[4]); // { dg-warning "\\\[-Warray-bounds" }
+ }
+}
+
+
+struct S { IA3_4 *pia3_4; };
+typedef struct S S5[5];
+typedef S5 S5_7[7];
+
+void test_s5_7 (S5_7 *ps5_7)
+{
+ {
+ S5 *ps5 = &(*ps5_7)[0];
+ T ((*ps5)[0]);
+ T ((*(*ps5)[0].pia3_4)[0][0]);
+ T ((*(*ps5)[0].pia3_4)[2][3]);
+ T ((*(*ps5)[0].pia3_4)[2][4]); // { dg-warning "array subscript 4 is above array bounds of 'IA4'" }
+
+ T ((*(*ps5)[1].pia3_4)[2][3]);
+ T ((*(*ps5)[5].pia3_4)[2][3]); // { dg-warning "array subscript 5 is above array bounds of 'S5'" }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-66.c b/gcc/testsuite/gcc.dg/Warray-bounds-66.c
new file mode 100644
index 0000000..c61891f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-66.c
@@ -0,0 +1,257 @@
+/* PR middle-end/82608 - missing -Warray-bounds on an out-of-bounds VLA index
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-uninitialized -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
+
+#include "range.h"
+
+typedef __INT16_TYPE__ int16_t;
+
+#define alloca(n) __builtin_alloca (n)
+
+void* calloc (size_t, size_t);
+void* malloc (size_t);
+
+void sink (void*, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+#define T(x) (sink (x))
+
+__attribute__ ((alloc_size (1))) void* alloc (size_t);
+
+
+void test_alloca_cst (void)
+{
+ {
+ char *p = alloca (1);
+ sink (p);
+ T (p[0]);
+ T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'char\\\[1\\\]'" }
+ }
+
+ {
+ char *p = alloca (2);
+ sink (p);
+ T (p[0]), T (p[1]);
+ T (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'char\\\[2\\\]'" }
+ }
+
+ {
+ char *p = alloca (3);
+ sink (p);
+ T (p[0]), T (p[1]), T (p[2]);
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" }
+ }
+}
+
+
+void test_alloca_char_range (int i, unsigned n, size_t sz)
+{
+ {
+ // Be sure to exercise signed as well as unsigned arguments.
+ char *p = alloca (i);
+ sink (p);
+ T (p[0]), T (p[1]), T (p[12345]);
+ T (p[-1]); // { dg-warning "subscript -1 is outside array bounds of 'char\\\[" }
+ }
+
+ {
+ char *p = alloca (n);
+ sink (p);
+ T (p[0]), T (p[1]), T (p[12345]);
+ T (p[-1]); // { dg-warning "subscript -1 is outside array bounds of 'char\\\[" }
+ }
+
+ {
+ char *p = alloca (sz);
+ sink (p);
+ T (p[0]), T (p[1]), T (p[23456]);
+ T (p[-1]); // { dg-warning "subscript -1 is outside array bounds of 'char\\\[" }
+ }
+
+ {
+ char *p = alloca (UR (0, 1));
+ sink (p);
+ T (p[0]);
+ T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'char\\\[1\\\]'" }
+ }
+
+ {
+ char *p = alloca (UR (0, 2));
+ sink (p);
+ sink (p[0], p[1]);
+ sink (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'char\\\[2\\\]'" }
+ }
+
+ {
+ char *p = alloca (UR (0, 3));
+ sink (p);
+ T (p[0]), T (p[1]), T (p[2]);
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" }
+ }
+
+ {
+ char *p = alloca (UR (1, 3));
+ sink (p);
+ T (p[0]), T (p[1]), T (p[2]);
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" }
+ }
+
+ {
+ char *p = alloca (UR (2, 3));
+ sink (p);
+ T (p[0]), T (p[1]), T (p[2]);
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" }
+ }
+}
+
+
+void test_alloca_int16_range (unsigned n)
+{
+ int16_t *p;
+ {
+ p = alloca (n); // { dg-message "allocated by " }
+ sink (p);
+ T (p[0]), T (p[1]), T (p[12345]);
+ T (p[-1]); // { dg-warning "subscript -1 is outside array bounds of 'int16_t\\\[" }
+ }
+
+ {
+ p = alloca (UR (0, 1)); // { dg-message "object of size between 0 and 1 allocated by '__builtin_alloca'" }
+ sink (p);
+ T (p[0]); // { dg-warning "subscript 'int16_t {aka short int}\\\[0\\\]' is partly outside array bounds of 'unsigned char\\\[1]'" }
+ T (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[0]'" }
+ }
+
+ {
+ p = alloca (UR (0, 2)); // { dg-message "object of size between 0 and 2 allocated by '__builtin_alloca'" }
+ sink (p);
+ sink (p[0]);
+ sink (p[1]); // { dg-warning "subscript 1 is outside array bounds of 'int16_t\\\[1]'" }
+ sink (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ }
+
+ {
+ p = alloca (UR (0, 3)); // { dg-message "object of size between 0 and 3 allocated by '__builtin_alloca'" }
+ sink (p);
+ T (p[0]);
+ T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
+ T (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ }
+
+ {
+ p = alloca (UR (1, 3)); // { dg-message "object of size between 1 and 3 allocated by '__builtin_alloca'" }
+ sink (p);
+ T (p[0]);
+ T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
+ T (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ }
+
+ {
+ p = alloca (UR (2, 3)); // { dg-message "object of size between 2 and 3 allocated by '__builtin_alloca'" }
+ sink (p);
+ T (p[0]);
+ T (p[1]); // { dg-warning "subscript 'int16_t {aka short int}\\\[1\\\]' is partly outside array bounds of 'unsigned char\\\[3]'" }
+ T (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'int16_t\\\[1\\\]'" }
+ }
+
+ {
+ p = alloca (UR (3, 4)); // { dg-message "object of size between 3 and 4 allocated by '__builtin_alloca'" }
+ sink (p);
+ T (p[0]);
+ T (p[1]);
+ T (p[2]); // { dg-warning "subscript 2 is outside array bounds of 'int16_t\\\[2\\\]'" }
+ T (p[3]); // { dg-warning "subscript 3 is outside array bounds of 'int16_t\\\[2\\\]'" }
+ }
+}
+
+
+void test_vla_cst (void)
+{
+ int n = 1;
+ {
+ char a[n];
+ sink (a);
+ T (a[0]);
+ T (a[1]); // { dg-warning "subscript 1 is (above|outside) array bounds " }
+ }
+
+ {
+ n = 2;
+ char a[n];
+ sink (a);
+ T (a[0]), T (a[1]);
+ T (a[2]); // { dg-warning "subscript 2 is (above|outside) array bounds " }
+ }
+
+ {
+ n = 3;
+ char a[n], *p = a;
+ sink (p);
+ T (p[0]), T (p[1]), T (p[2]);
+ T (p[3]); // { dg-warning "subscript 3 is (above|outside) array bounds " }
+ }
+}
+
+
+void test_vla_char_range (int i, unsigned n, size_t sz)
+{
+ {
+ char a[i];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[12345]);
+ T (a[-1]); // { dg-warning "subscript -1 is (below|outside) array bounds of 'char\\\[" }
+ }
+
+ {
+ char a[n];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[12345]);
+ T (a[-1]); // { dg-warning "subscript -1 is (below|outside) array bounds of 'char\\\[" }
+ }
+
+ {
+ char a[sz];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[23456]);
+ T (a[-1]); // { dg-warning "subscript -1 is (below|outside) array bounds of 'char\\\[" }
+ }
+
+ {
+ char a[UR (0, 1)];
+ sink (a);
+ T (a[0]);
+ T (a[1]); // { dg-warning "subscript 1 is outside array bounds of 'char\\\[1\\\]'" "pr82608" { xfail *-*-* } }
+ }
+
+ {
+ char a[UR (0, 2)];
+ sink (a);
+ sink (a[0], a[1]);
+ sink (a[2]); // { dg-warning "subscript 2 is outside array bounds of 'char\\\[2\\\]'" "pr82608" { xfail *-*-* } }
+ }
+
+ {
+ char a[UR (0, 3)];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[2]);
+ T (a[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" "pr82608" { xfail *-*-* } }
+ }
+
+ {
+ char a[UR (1, 3)];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[2]);
+ T (a[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" "pr82608" { xfail *-*-* } }
+ }
+
+ {
+ char a[UR (2, 3)];
+ sink (a);
+ T (a[0]), T (a[1]), T (a[2]);
+ T (a[3]); // { dg-warning "subscript 3 is outside array bounds of 'char\\\[3\\\]'" "pr82608" { xfail *-*-* } }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-bounds-67.c b/gcc/testsuite/gcc.dg/Warray-bounds-67.c
new file mode 100644
index 0000000..a9b9ff7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-bounds-67.c
@@ -0,0 +1,36 @@
+/* Verify warnings fpr accesses to trailing one-element array members
+ of a struct that's a member of either a struct or a union. Both
+ are obviously undefined but GCC relies on these hacks so the test
+ verifies that -Warray-bounds doesn't trigger for it.
+ { do-do compile }
+ { dg-options "-O2 -Wall" } */
+
+
+typedef union tree_node *tree;
+
+struct tree_exp { int i; tree operands[1]; };
+
+union tree_node
+{
+ struct tree_exp exp;
+};
+
+tree test_nowarn (tree t)
+{
+ return t->exp.operands[3]; // { dg-bogus "\\\[-Warray-bounds" }
+}
+
+
+typedef struct shrub_node *shrub;
+
+struct shrub_exp { int i; shrub operands[1]; };
+
+struct shrub_node
+{
+ struct shrub_exp exp;
+};
+
+shrub test_warn (shrub s)
+{
+ return s->exp.operands[3]; // { dg-warning "\\\[-Warray-bounds" "pr96346" { xfail *-*-* } }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-2.c b/gcc/testsuite/gcc.dg/Warray-parameter-2.c
new file mode 100644
index 0000000..88f20e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-2.c
@@ -0,0 +1,45 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+// Reduced from Glibc.
+
+typedef struct FILE FILE;
+
+int vfprintf (FILE*, const char*, __builtin_va_list);
+int vfprintf (FILE*, const char*, __builtin_va_list); // { dg-bogus "-Warray-parameter" }
+int vfprintf (FILE*, const char*, __builtin_va_list);
+
+int vfscanf (FILE*, const char*, __builtin_va_list);
+int vfscanf (FILE*, const char*, __builtin_va_list); // { dg-bogus "-Warray-parameter" }
+int vfscanf (FILE*, const char*, __builtin_va_list);
+
+
+/* Verify that mismatches in array/to pointer to va_list are still
+ diagnosed. */
+
+int fva (__builtin_va_list);
+int fva (__builtin_va_list);
+
+int fpva_a1 (__builtin_va_list*);
+int fpva_a1 (__builtin_va_list[1]); // { dg-warning "\\\[-Warray-parameter" }
+
+int fpva_a_ (__builtin_va_list*);
+int fpva_a_ (__builtin_va_list[]);
+int fpva_a_ (__builtin_va_list*);
+int fpva_a_ (__builtin_va_list[]);
+
+/* Also verify that a mismatch between a pointer and a one-element
+ array are diagnosed. This is pervasive in Glibc headers but
+ making an exception for it would leave no way to express
+ the requirement that a function take at least one argument
+ by reference. */
+
+struct __jmp_buf_tag;
+int __sigsetjmp (struct __jmp_buf_tag*, int);
+
+struct __jmp_buf_tag { };
+typedef struct __jmp_buf_tag jmp_buf[1];
+
+int __sigsetjmp (struct __jmp_buf_tag[1], int); // { dg-warning "\\\[-Warray-parameter" }
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-3.c b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
new file mode 100644
index 0000000..cbf3e93
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-3.c
@@ -0,0 +1,89 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ { dg-do compile }
+ { dg-options "-Wall -Warray-parameter=1" } */
+
+/* Verify that at level 1 mismatches in the bounds of ordinary array
+ parameters don't trigger -Warray-parameter. */
+void fax (int[]);
+void fax (int[0]);
+void fax (int[1]);
+void fax (int[2]);
+void fax (int[3]);
+
+/* Same as above but starting with an array with a specified bound. */
+void gax (int[3]);
+void gax (int[2]);
+void gax (int[1]);
+void gax (int[0]);
+void gax (int[]);
+
+/* Same for multidimensional arrays. */
+void fax_y (int[][3]);
+void fax_y (int[0][3]);
+void fax_y (int[1][3]);
+void fax_y (int[2][3]);
+void fax_y (int[3][3]);
+
+/* Same as above but starting with an array with a specified bound. */
+void gax_y (int[3][5]);
+void gax_y (int[2][5]);
+void gax_y (int[1][5]);
+void gax_y (int[0][5]);
+void gax_y (int[][5]);
+
+/* Exercise VLAs with a mismatch in the bound for an ordinary array. */
+void fvlax_y (int n, int[][n]);
+void fvlax_y (int n, int[0][n]);
+void fvlax_y (int n, int[1][n]);
+void fvlax_y (int n, int[2][n]);
+void fvlax_y (int n, int[3][n]);
+
+void fvlaxn_y (int n, int[][n]);
+void fvlaxn_y (int n, int[0][n]);
+void fvlaxn_y (int n, int[1][n]);
+void fvlaxn_y (int n, int[2][n]);
+void fvlaxn_y (int n, int[3][n]);
+
+void fvlaxx_y (int[][*]);
+void fvlaxx_y (int[0][*]);
+void fvlaxx_y (int[1][*]);
+void fvlaxx_y (int[2][*]);
+void fvlaxx_y (int[3][*]);
+
+/* Verify that mismatches in the bounds of array parameters declared
+ static do trigger -Warray-parameter. */
+void fas1 (int[static 1]); // { dg-message "previously declared as 'int\\\[static 1]'" }
+void fas1 (int[static 2]); // { dg-warning "\\\[-Warray-parameter=" }
+
+
+/* Also verify that -Warray-bounds doesn't trigger for ordinary array
+ parameters... */
+#pragma GCC optimize "2"
+
+__attribute__ ((noipa)) void
+gca3 (char a[3])
+{
+ a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
+}
+
+__attribute__ ((noipa)) void
+gia3 (int a[3])
+{
+ a[0] = 0; a[1] = 1; a[2] = 2; a[3] = 3;
+}
+
+/* ...but does for static arrays. */
+__attribute__ ((noipa)) void
+gcas3 (char a[static 3])
+{
+ a[0] = 0; a[1] = 1; a[2] = 2;
+ a[3] = 3; // { dg-warning "\\\[-Warray-bounds" }
+}
+
+__attribute__ ((noipa)) void
+gias3 (int a[static 3])
+{
+ a[0] = 0; a[1] = 1; a[2] = 2;
+ a[3] = 3; // { dg-warning "\\\[-Warray-bounds" }
+}
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-4.c b/gcc/testsuite/gcc.dg/Warray-parameter-4.c
new file mode 100644
index 0000000..b702d73
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-4.c
@@ -0,0 +1,119 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify warnings for multidimensional arrays, including mismatches
+ in bounds of arrays of VLAs. (Mismatches in variable bounds are
+ diagnosed by -Wvla-parameter.)
+ { dg-do compile }
+ { dg-options "-Wall -Warray-parameter=2" } */
+
+// Verify that equivalent forms don't tigger a warning.
+
+typedef int IA1[1];
+typedef int IA1x_[][1];
+typedef int IA1x0[0][1];
+
+void fia_x1 (int[][1]);
+void fia_x1 (IA1[0]);
+void fia_x1 (IA1x_);
+void fia_x1 (IA1x0);
+void fia_x1 (int[0][1]);
+void fia_x1 (int[static 0][1]);
+
+// Same as above one more time.
+void fia_x1 (int[][1]);
+void fia_x1 (IA1[0]);
+void fia_x1 (IA1x_);
+void fia_x1 (IA1x0);
+void fia_x1 (int[0][1]);
+void fia_x1 (int[static 0][1]);
+
+
+void fia1x1 (int[1][1]);
+void fia1x1 (int[1][1]);
+void fia1x1 (int[static 1][1]);
+
+void fia2x1 (int[2][1]);
+void fia2x1 (int[2][1]);
+void fia2x1 (int[static 2][1]);
+
+void fia1x2 (int[1][2]);
+void fia1x2 (int[1][2]);
+void fia1x2 (int[static 1][2]);
+
+void fia1x1_2x1 (int[1][1]); // { dg-message "previously declared as 'int\\\[1]\\\[1]'" }
+void fia1x1_2x1 (int[2][1]); // { dg-warning "\\\[-Warray-parameter" }
+void fia1x1_2x1 (int[static 1][1]);
+void fia1x1_2x1 (int[static 2][1]); // { dg-warning "\\\[-Warray-parameter" }
+
+
+void fia2x1_1x1 (int[2][1]); // { dg-message "previously declared as 'int\\\[2]\\\[1]'" }
+void fia2x1_1x1 (int[1][1]); // { dg-warning "\\\[-Warray-parameter" }
+void fia2x1_1x1 (int[2][1]);
+void fia2x1_1x1 (int[static 1][1]); // { dg-warning "\\\[-Warray-parameter" }
+void fia2x1_1x1 (int[static 2][1]);
+
+
+extern int n1, n2;
+
+void fca_xn1 (char[][n1]);
+void fca_xn1 (char[0][n1]);
+void fca_xn1 (char[static 0][n1]);
+
+void fca1xn1_2xn1 (char[1][n1]);
+void fca1xn1_2xn1 (char[2][n1]); // { dg-warning "\\\[-Warray-parameter" }
+void fca1xn1_2xn1 (char[1][n1]);
+void fca1xn1_2xn1 (char[static 1][n1]);
+void fca1xn1_2xn1 (char[static 2][n1]); // { dg-warning "\\\[-Warray-parameter" }
+
+
+/* Exercise VLAs with a mismatch in the bound for an ordinary array. */
+void fvlax_y (int n, int[][n]);
+void fvlax_y (int n, int[0][n]);
+void fvlax_y (int n, int[1][n]); // { dg-warning "argument 2 of type 'int\\\[1]\\\[n]' with mismatched bound" }
+void fvlax_y (int n, int[2][n]); // { dg-warning "argument 2 of type 'int\\\[2]\\\[n]' with mismatched bound" }
+void fvlax_y (int n, int[3][n]); // { dg-warning "argument 2 of type 'int\\\[3]\\\[n]' with mismatched bound" }
+
+void fvlaxn_y (int n, int[][n]);
+void fvlaxn_y (int n, int[0][n]);
+void fvlaxn_y (int n, int[1][n]); // { dg-warning "\\\[-Warray-parameter" }
+void fvlaxn_y (int n, int[2][n]); // { dg-warning "\\\[-Warray-parameter" }
+void fvlaxn_y (int n, int[3][n]); // { dg-warning "\\\[-Warray-parameter" }
+
+void fvlaxx_y (int[][*]);
+void fvlaxx_y (int[0][*]);
+void fvlaxx_y (int[1][*]); // { dg-warning "\\\[-Warray-parameter" }
+void fvlaxx_y (int[2][*]); // { dg-warning "\\\[-Warray-parameter" }
+void fvlaxx_y (int[3][*]); // { dg-warning "\\\[-Warray-parameter" }
+
+
+// Verify an array of pointers to an array of function pointers.
+
+void ffpa7_5 (void (* (* (* [7])[5])(void))(void));
+// { dg-message "previously declared as 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[7]\\\)\\\[5]\\\)\\\(void\\\)\\\)\\\(void\\\)'" "note" { target *-*-* } .-1 }
+void ffpa7_5 (void (* (* (* [6])[5])(void))(void));
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[6]\\\)\\\[5]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "" { target *-*-* } .-1 }
+void ffpa7_5 (void (* (* (* [])[5])(void))(void));
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[]\\\)\\\[5]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "" { target *-*-* } .-1 }
+void ffpa7_5 (void (* (* (* (*))[5])(void))(void));
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\*\\\)\\\[5]\\\)\\\(void\\\)\\\)\\\(void\\\)' declared as a pointer" "" { target *-*-* } .-1 }
+
+// Same as above but with array of pointers to a VLA of function pointers.
+void ffpa7_n1 (void (* (* (* [7])[n1])(void))(void));
+// { dg-message "previously declared as 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[7]\\\)\\\[n1]\\\)\\\(void\\\)\\\)\\\(void\\\)'" "note" { target *-*-* } .-1 }
+void ffpa7_n1 (void (* (* (* [8])[n1])(void))(void));
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[8]\\\)\\\[n1]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "" { target *-*-* } .-1 }
+
+void ffpa9_x (void (* (* (* [9])[*])(void))(void));
+// { dg-message "previously declared as 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[9]\\\)\\\[\\\*]\\\)\\\(void\\\)\\\)\\\(void\\\)'" "pr?????" { xfail *-*-* } .-1 }
+// { dg-message "previously declared as 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[9]\\\)\\\[0]\\\)\\\(void\\\)\\\)\\\(void\\\)'" "" { target *-*-* } .-2 }
+void ffpa9_x (void (* (* (* [8])[*])(void))(void));
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[8]\\\)\\\[\\\*]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "pr?????" { xfail *-*-* } .-1 }
+// { dg-warning "argument 1 of type 'void \\\(\\\* ?\\\(\\\* ?\\\(\\\*\\\[8]\\\)\\\[0]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "" { target *-*-* } .-2 }
+
+/* Verify a three-dimensional array of pointers to two-dimensional arrays
+ of pointers to function pointers. */
+
+void ffpa7_5_3 (void (* (* (* (* [7])[5])[3])(void))(void));
+// { dg-message "previously declared as 'void ?\\\(\\\* ?\\\(\\\* ?\\\(\\\* ?\\\(\\\* ?\\\[7]\\\)\\\[5]\\\)\\\[3]\\\)\\\(void\\\)\\\)\\\(void\\\)'" "note" { target *-*-* } .-1 }
+void ffpa7_5_3 (void (* (* (* (* [1])[5])[3])(void))(void));
+// { dg-warning "argument 1 of type 'void ?\\\(\\\* ?\\\(\\\* ?\\\(\\\* ?\\\(\\\* ?\\\[1]\\\)\\\[5]\\\)\\\[3]\\\)\\\(void\\\)\\\)\\\(void\\\)' with mismatched bound" "" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-5.c b/gcc/testsuite/gcc.dg/Warray-parameter-5.c
new file mode 100644
index 0000000..6e89bf0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-5.c
@@ -0,0 +1,14 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify that -Warray-parameter diagnoses mismatches in bounds of
+ arrays between redeclarations of the same function and with pointer
+ parameters pointing to those arrays.
+ { dg-do compile }
+ { dg-options "-Wall -Warray-parameter" } */
+
+void fa_x (int (*)[]); // { dg-message "previously declared as 'int \\\(\\\*\\\)\\\[]'" }
+void fa_x (int (*)[2]); // { dg-warning "\\\[-Warray-parameter" }
+void fa_x (int (*)[2]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[2]'" }
+
+void fa_2 (int (*)[2]); // { dg-message "previously declared as 'int \\\(\\\*\\\)\\\[2]'" }
+void fa_2 (int (*)[]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[]'" }
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-6.c b/gcc/testsuite/gcc.dg/Warray-parameter-6.c
new file mode 100644
index 0000000..609dac9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-6.c
@@ -0,0 +1,9 @@
+/* PR c/97131 - ICE: Segmentation fault in warn_parm_ptrarray_mismatch
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+struct bm { };
+
+void ms (struct bm (*at)[1]) { }
+
+void ms (int f1) { } // { dg-error "conflicting types for 'ms'" }
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-7.c b/gcc/testsuite/gcc.dg/Warray-parameter-7.c
new file mode 100644
index 0000000..4863045
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-7.c
@@ -0,0 +1,25 @@
+/* PR c/97206 - ICE in composite_type on declarations of a similar array types
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+__attribute__((__access__(__write_only__, 1))) void
+f1 (char* restrict);
+
+void f1 (char*);
+
+char a1[];
+char a1[] = { };
+
+
+void f2 (char[restrict]);
+void f2 (char*);
+
+char a2[];
+char a2[] = { };
+
+
+void f3 (char*);
+void f3 (char[const]);
+
+extern const char a3[];
+extern const char a3[1];
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter-8.c b/gcc/testsuite/gcc.dg/Warray-parameter-8.c
new file mode 100644
index 0000000..b152702
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter-8.c
@@ -0,0 +1,36 @@
+/* Verify that combinations of array type qualifiers render correctly.
+ { dg-do compile }
+ { dg-options "-Warray-parameter" } */
+
+void fatm (int[_Atomic 1]); // { dg-message "previously declared as 'int\\\[_Atomic 1]" }
+void fatm (int[_Atomic 2]); // { dg-warning "argument 1 of type 'int\\\[_Atomic 2]' with mismatched bound" }
+
+
+void fcst (int[const 2]); // { dg-message "previously declared as 'int\\\[const 2]" }
+void fcst (int[const 3]); // { dg-warning "argument 1 of type 'int\\\[const 3]' with mismatched bound" }
+
+
+void frst (int[restrict 3]); // { dg-message "previously declared as 'int\\\[restrict 3]" }
+void frst (int[restrict 4]); // { dg-warning "argument 1 of type 'int\\\[restrict 4]' with mismatched bound" }
+
+void fvol (int[volatile 4]); // { dg-message "previously declared as 'int\\\[volatile 4]" }
+void fvol (int[volatile 5]); // { dg-warning "argument 1 of type 'int\\\[volatile 5]' with mismatched bound" }
+
+
+void fcr (int[const restrict 1]); // { dg-message "previously declared as 'int\\\[\(const restrict|restrict const\) 1]" }
+void fcr (int[restrict volatile 2]); // { dg-warning "argument 1 of type 'int\\\[\(restrict volatile|volatile restrict\) 2]' with mismatched bound" }
+void fcr (int[const restrict volatile 3]); // { dg-warning "argument 1 of type 'int\\\[const volatile restrict 3]' with mismatched bound" }
+
+
+extern int n;
+
+void fcx_n (int [const 1][n]); // { dg-message "previously declared as 'int\\\[const 1]\\\[n]'" "note" }
+void fcx_n (int [restrict 2][n]); // { dg-warning "argument 1 of type 'int\\\[restrict 2]\\\[n]' with mismatched bound" }
+
+
+extern int n1, n2;
+
+/* The mismatch in the array bound should be diagnosed but the mismatch
+ in the VLA should not be without -Wvla-parameter. */
+void fc3_n1 (int [const 3][n1]); // { dg-message "previously declared as 'int\\\[const 3]\\\[n1]'" "note" }
+void fc3_n1 (int [const 5][n2]); // { dg-warning "argument 1 of type 'int\\\[const 5]\\\[n2]' with mismatched bound" }
diff --git a/gcc/testsuite/gcc.dg/Warray-parameter.c b/gcc/testsuite/gcc.dg/Warray-parameter.c
new file mode 100644
index 0000000..42be310
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Warray-parameter.c
@@ -0,0 +1,187 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify that -Warray-parameter diagnoses mismatches in array (and
+ pointer) arrguments between redeclarations of the same function.
+ Also verify that the array/pointer argument form in a mismatched
+ redeclaration doesn't override the form in the initial declaration.
+ { dg-do compile }
+ { dg-options "-Wall -Warray-parameter -Wno-vla-paramater" } */
+
+/* Redclarations with the same or equivalent array form should not
+ be dianosed. T[0] is diagnosed by -Wpedantic for being invalid
+ C so there's little point in also warning for the difference in
+ array form. */
+void f1vpp (void**);
+void f1vpp (void*[]);
+void f1vpp (void*[0]);
+
+void f1ia_ (int[]);
+void f1ia_ (int[]);
+void f1ia_ (int[0]);
+/* Verify the unused attribute still has an effect. */
+void f1ia_ (int a[0] __attribute__ ((unused))) { }
+void f1ia_ (int[]);
+
+void f1ia_p (int[]);
+void f1ia_p (int*);
+void f1ia_p (int *p __attribute__ ((unused))) { }
+void f1ia_p (int[]);
+
+void f1p_ia (const int*);
+void f1p_ia (const int[]);
+void f1p_ia (const int *p __attribute__ ((unused))) { }
+void f1p_ia (const int[]);
+
+void f1ia1 (int[1]);
+void f1ia1 (int[1]);
+void f1ia1 (int[2 - 1]);
+
+void f1ias2 (int[static 2]);
+void f1ias2 (int[static 2]);
+void f1ias2 (int[static 1 + 1]);
+void f1ias2 (int a[static 3 - 1]) { (void)&a; }
+
+void f1ipa_ (int*[]);
+void f1ipa_ (int*[]);
+void f1ipa_ (int*[0]);
+
+void f1ia1_x (int[1]); // { dg-message "previously declared as 'int\\\[1]'" }
+void f1ia1_x (int[]); // { dg-warning "argument 1 of type 'int\\\[]' with mismatched bound" }
+void f1ia1_x (int[]); // { dg-warning "argument 1 of type 'int\\\[]' with mismatched bound" }
+void f1ia1_x (int[1]);
+void f1ia1_x (int[2]); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
+void f1ia1_x (int[1]);
+void f1ia1_x (int[3]); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
+void f1ia1_x (int a[1] __attribute__ ((unused))) { }
+
+
+void f1ias2_s3 (int[static 2]); // { dg-message "previously declared as 'int\\\[static 2]'" }
+void f1ias2_s3 (int[static 3]); // { dg-warning "argument 1 of type 'int\\\[static 3]' with mismatched bound" }
+/* Verify the unused attribute still has an effect and doesn't interfere
+ with the warning. */
+void f1ias2_s3 (int a[static 3] __attribute__ ((unused))) { } // { dg-warning "argument 1 of type 'int\\\[static 3]' with mismatched bound" }
+
+
+/* Ordinary T[N] and T[static N] forms are both effectively treated
+ the same but strictly have different meanings so they are diagnosed.
+ It might be worth splitting the warning into two levels and having
+ only the higher level treat the ordinary form as T[static N]. */
+
+void f1ia3_s4 (int[3]); // { dg-message "previously declared as 'int\\\[3]'" }
+void f1ia3_s4 (int[static 4]); // { dg-warning "argument 1 of type 'int\\\[static 4]' with mismatched bound" }
+void f1ia3_s4 (int[3]);
+
+
+void f1ias4_5 (int[static 4]); // { dg-message "previously declared as 'int\\\[static 4]'" }
+void f1ias4_5 (int[5]); // { dg-warning "argument 1 of type 'int\\\[5]' with mismatched bound" }
+void f1ias4_5 (int[static 4]);
+
+
+void f1ia_1 (int[]); // { dg-message "previously declared as 'int\\\[]'" }
+void f1ia_1 (int[1]); // { dg-warning "argument 1 of type 'int\\\[1]' with mismatched bound" }
+void f1ia_1 (int[]);
+
+
+void f1ca_ (char[]); // { dg-message "previously declared as 'char\\\[]'" }
+void f1ca_ (char[2]); // { dg-warning "argument 1 of type 'char\\\[2]' with mismatched bound" }
+void f1ca_ (char[]);
+
+
+void f1csp (const short*); // { dg-message "previously declared as 'const short int ?\\\*'" }
+void f1csp (const short[3]); // { dg-warning "argument 1 of type 'const short int\\\[3]' with mismatched bound" }
+void f1csp (const short*);
+
+
+void f1ia2 (int[2]); // { dg-message "previously declared as 'int\\\[2]'" }
+void f1ia2 (int[1]); // { dg-warning "argument 1 of type 'int\\\[1]' with mismatched bound" }
+void f1ia2 (int[2]);
+
+
+void f1cvla2 (const volatile long[3]); // { dg-message "previously declared as 'const volatile long int\\\[3]'" }
+void f1cvla2 (const volatile long[2]); // { dg-warning "argument 1 of type 'const volatile long int\\\[2]' with mismatched bound" }
+void f1cvla2 (const volatile long[3]);
+void f1cvla2 (const volatile long[restrict 4]); // { dg-warning "argument 1 of type 'const volatile long int\\\[restrict 4]' with mismatched bound" }
+
+
+void f1afa4 (_Atomic float[3]); // { dg-message "previously declared as an array '_Atomic float ?\\\[3]'" }
+void f1afa4 (_Atomic float*); // { dg-warning "argument 1 of type '_Atomic float ?\\\*' declared as a pointer" }
+void f1afa4 (_Atomic float[3]);
+
+void f1ipa1_a2 (int*[1]); // { dg-message "previously declared as 'int \\\*\\\[1]'" }
+void f1ipa1_a2 (int*[2]); // { dg-warning "argument 1 of type 'int \\\*\\\[2]' with mismatched bound" }
+void f1ipa1_a2 (int*[1]);
+
+
+typedef int IAx[];
+typedef int IA1[1];
+typedef int IA2[2];
+typedef int IA3[3];
+
+// The message should differentiate between the [] form and *.
+void f1IAx_A1 (IAx); // { dg-message "previously declared as 'int\\\[]'" "pr?????" { xfail *-*-* } }
+ // { dg-message "previously declared as 'int *\\\*'" "note" { target *-*-* } .-1 }
+void f1IAx_A1 (IA1); // { dg-message "argument 1 of type 'int\\\[1]' with mismatched bound" }
+
+void f1IA1_A2 (IA1); // { dg-message "previously declared as 'int\\\[1]'" }
+void f1IA1_A2 (IA2); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
+void f1IA1_A2 (IA1);
+void f1IA1_A2 (int[2]); // { dg-warning "argument 1 of type 'int\\\[2]' with mismatched bound" }
+
+
+void f1IA1_A3 (IA1 ia1); // { dg-message "previously declared as 'int\\\[1]'" }
+void f1IA1_A3 (IA3 ia3); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
+void f1IA1_A3 (IA1 ia1);
+
+
+void f1IA2_A3 (IA2 a); // { dg-message "previously declared as 'int\\\[2]'" }
+void f1IA2_A3 (IA3 a); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
+void f1IA2_A3 (IA2 a);
+
+
+// Verify multiple array arguments.
+
+void f2a2_a3_3_3 (int[2], int[3]); // { dg-message "previously declared as 'int\\\[2]'" }
+void f2a2_a3_3_3 (int[2], int[3]);
+void f2a2_a3_3_3 (int[3], int[3]); // { dg-warning "argument 1 of type 'int\\\[3]' with mismatched bound" }
+
+
+void f2a2_a3_2_4 (int[2], int[3]); // { dg-message "previously declared as 'int\\\[3]'" }
+void f2a2_a3_2_4 (int[2], int[4]); // { dg-warning "argument 2 of type 'int\\\[4]' with mismatched bound" }
+
+
+/* Verify that pointers to arrays and arrays of arrays are differentiated
+ the same way as pointers and arrays of other types. */
+typedef IA1 *PA1;
+
+void fpia1 (IA1*); // { dg-message "previously declared as 'int ?\\(\\\*\\)\\\[1]'" }
+void fpia1 (IA1[1]); // { dg-warning "argument 1 of type 'int\\\[1]\\\[1]' with mismatched bound" }
+void fpia1 (PA1);
+void fpia1 (int(*)[1]);
+void fpia1 (int[][1]);
+
+void f1vpa1 (void*[][1]);
+void f1vpa1 (void*[0][1]);
+
+/* Verify arrays of pointers. */
+void vaip1 (int (*[3])); // { dg-message "previously declared as 'int *\\\*\\\[3]'" }
+void vaip1 (int (*[5])); // { dg-warning "argument 1 of type 'int *\\\*\\\[5]' with mismatched bound" }
+void vaip1 (int (*[3]));
+void vaip1 (int (*[])); // { dg-warning "argument 1 of type 'int *\\\*\\\[]' with mismatched bound" }
+void vaip1 (int (*[3]));
+
+/* Verify that attributes with arrays don't cause unwanted warnings and
+ don't suppress intended ones. */
+
+#define ALIGN(N)__attribute__ ((aligned (__alignof__ (char[N]))))
+
+void fatipa2 (int (* ALIGN (3)[2])); // { dg-message "previously declared as 'int \\\*\\\[2]'" }
+void fatipa2 (int (* ALIGN (4)[2]));
+void fatipa2 (int (* ALIGN (5)[2]));
+void fatipa2 (int (* ALIGN (7)[3])); // { dg-warning "argument 1 of type 'int \\\*\\\[3]' with mismatched bound" }
+
+void fatiap (int (* ALIGN (3))[2]);
+void fatiap (int (* ALIGN (5))[2]);
+
+
+void fatipa3 (int (* ALIGN (1) (* ALIGN (2))[3]));
+void fatipa3 (int (* ALIGN (1) (* ALIGN (2))[3]));
diff --git a/gcc/testsuite/gcc.dg/Wattributes-6.c b/gcc/testsuite/gcc.dg/Wattributes-6.c
index d3dd22d..4ba59bf 100644
--- a/gcc/testsuite/gcc.dg/Wattributes-6.c
+++ b/gcc/testsuite/gcc.dg/Wattributes-6.c
@@ -21,7 +21,7 @@ PackedAligned { int i; };
struct ATTR ((aligned (2)))
AlignedMemberPacked
{
- int ATTR ((packed)) i;
+ int ATTR ((packed)) i; // { dg-warning "attribute ignored" "" { target default_packed } }
};
struct ATTR ((packed))
diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-16.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-16.c
new file mode 100644
index 0000000..494fff9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-16.c
@@ -0,0 +1,12 @@
+/* PR c/96596 - ICE on a declaration of a built-in with invalid array
+ argument
+ { dg-do compile } */
+
+void __builtin_abort (int[foo]); /* { dg-error "'foo' undeclared" } */
+void __builtin_trap (int[__SIZE_MAX__]); /* { dg-error "size of unnamed array is too large" } */
+void __builtin_unreachable (int[][]); /* { dg-error "array type has incomplete element type" } */
+
+void __builtin_exit (int, int[+]); /* { dg-error "expected expression before" } */
+
+/* { dg-prune-output "\\\[-Wbuiltin-declaration-mismatch" } */
+
diff --git a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-9.c b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-9.c
index f0c1ce3..56a827a 100644
--- a/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-9.c
+++ b/gcc/testsuite/gcc.dg/Wbuiltin-declaration-mismatch-9.c
@@ -10,3 +10,6 @@ void a (void)
"" /* { dg-warning "passing argument 2 of .sscanf. from incompatible pointer type" } */
);
}
+
+/* The invalid scanf call may also trigger:
+ { dg-prune-output "accessing 4 bytes in a region of size 1" } */
diff --git a/gcc/testsuite/gcc.dg/Wno-frame-address.c b/gcc/testsuite/gcc.dg/Wno-frame-address.c
index 51f20b4..13c42b2 100644
--- a/gcc/testsuite/gcc.dg/Wno-frame-address.c
+++ b/gcc/testsuite/gcc.dg/Wno-frame-address.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-skip-if "Cannot access arbitrary stack frames" { arm*-*-* amdgpu-*-* avr-*-* hppa*-*-* ia64-*-* visium-*-* csky-*-* msp430-*-* } } */
+/* { dg-skip-if "Cannot access arbitrary stack frames" { arm*-*-* amdgpu-*-* avr-*-* hppa*-*-* ia64-*-* visium-*-* csky-*-* msp430-*-* cris-*-* mmix-*-* } } */
/* { dg-options "-Werror" } */
/* { dg-additional-options "-mbackchain" { target { s390*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/Wnonnull-4.c b/gcc/testsuite/gcc.dg/Wnonnull-4.c
new file mode 100644
index 0000000..180a40d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wnonnull-4.c
@@ -0,0 +1,173 @@
+/* PR middle-end/97188 - ICE passing a null VLA to a function expecting
+ at least one element
+ { dg-do compile }
+ { dg-options "-O -Wall -ftrack-macro-expansion=0" } */
+
+#define INT_MAX __INT_MAX__
+#define INT_MIN (-INT_MAX - 1)
+
+/* Exercise passing nul to a one-dimensional VLA argument. */
+
+void test_fca_n (int r_m1)
+{
+ extern void fca_n (int n, char[n]); // { dg-message "in a call to function 'fca_n'" "note" }
+
+#define T(n) fca_n (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'char\\\[n]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'char\\\[n]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'char\\\[n]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'char\\\[n]' is null but the corresponding bound argument 2 value is \\d+" }
+}
+
+
+/* Exercise passing nul to an array with unspecified bound of VLAs. */
+
+void test_fsa_x_n (int r_m1)
+{
+ extern void fsa_x_n (int n, short[][n]); // { dg-message "in a call to function 'fsa_x_n'" "note" }
+
+#undef T
+#define T(n) fsa_x_n (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'short int\\\[]\\\[n]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'short int\\\[]\\\[n]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'short int\\\[]\\\[n]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'short int\\\[]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" }
+}
+
+
+/* Exercise passing nul to an array of a single VLA. */
+
+void test_fia_1_n (int r_m1)
+{
+ extern void fia_1_n (int n, int[1][n]); // { dg-message "in a call to function 'fia_1_n'" "note" }
+
+#undef T
+#define T(n) fia_1_n (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'int\\\[1]\\\[n]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'int\\\[1]\\\[n]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'int\\\[1]\\\[n]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'int\\\[1]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" }
+}
+
+
+/* Exercise passing nul to an array of three VLAs. */
+
+void test_fla_3_n (int r_m1)
+{
+ extern void fla_3_n (int n, long[3][n]); // { dg-message "in a call to function 'fla_3_n'" "note" }
+
+#undef T
+#define T(n) fla_3_n (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'long int\\\[3]\\\[n]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'long int\\\[3]\\\[n]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'long int\\\[3]\\\[n]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'long int\\\[3]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" }
+}
+
+
+/* Exercise passing nul to a VLA of five-element arrays. */
+
+void test_fda_n_5 (int r_m1)
+{
+ extern void fda_n_5 (int n, double[n][5]);// { dg-message "in a call to function 'fda_n_5'" "note" }
+
+#undef T
+#define T(n) fda_n_5 (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'double\\\[n]\\\[5]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'double\\\[n]\\\[5]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'double\\\[n]\\\[5]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'double\\\[n]\\\[5]' is null but the corresponding bound argument 2 value is \\d+" }
+}
+
+
+/* Exercise passing nul to a two-dimensional VLA. */
+
+void test_fca_n_n (int r_m1)
+{
+ extern void fca_n_n (int n, char[n][n]); // { dg-message "in a call to function 'fca_n_n'" "note" }
+
+#undef T
+#define T(n) fca_n_n (n, 0)
+
+ int min = INT_MIN;
+ int max = INT_MAX;
+ if (r_m1 >= 0)
+ r_m1 = -1;
+
+ // Verify negative bounds.
+ T (min); // { dg-warning "bound argument 1 value -\\d+ is negative for a variable length array argument 2 of type 'char\\\[n]\\\[n]'" }
+ T (r_m1); // { dg-warning "bound argument 1 value \\\[-\\d+, -1] is negative for a variable length array argument 2 of type 'char\\\[n]\\\[n]" }
+ T ( -1); // { dg-warning "bound argument 1 value -1 is negative for a variable length array argument 2 of type 'char\\\[n]\\\[n]" }
+
+ T ( 0);
+
+ // Verify positive bounds.
+ T ( 1); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is 1" }
+ T ( 9); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is 9" }
+ T (max); // { dg-warning "argument 1 of variable length array 'char\\\[n]\\\[n]' is null but the corresponding bound argument 2 value is \\d+" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c
index 0e3435c..9273690 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-2.c
@@ -1,6 +1,7 @@
/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
#define ATTR(...) __attribute__ ((__VA_ARGS__))
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c
index 6dad7af..e922888 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-3.c
@@ -1,6 +1,7 @@
/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
#define ATTR(...) __attribute__ ((__VA_ARGS__))
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c
index 0a451ef..4a3b07b 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-4.c
@@ -1,6 +1,7 @@
/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
#define ATTR(...) __attribute__ ((__VA_ARGS__))
diff --git a/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c b/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c
index 70138b3..844660f 100644
--- a/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c
+++ b/gcc/testsuite/gcc.dg/Wreturn-local-addr-6.c
@@ -1,6 +1,7 @@
/* PR c/71924 - missing -Wreturn-local-addr returning alloca result
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
index 4d14de2..5aea89a 100644
--- a/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
+++ b/gcc/testsuite/gcc.dg/Wsizeof-pointer-memaccess1.c
@@ -1,6 +1,6 @@
/* Test -Wsizeof-pointer-memaccess warnings. */
/* { dg-do compile } */
-/* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow" } */
+/* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow -Wno-stringop-overread" } */
/* { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/Wstack-usage.c b/gcc/testsuite/gcc.dg/Wstack-usage.c
index 4738b69..11e3a27 100644
--- a/gcc/testsuite/gcc.dg/Wstack-usage.c
+++ b/gcc/testsuite/gcc.dg/Wstack-usage.c
@@ -1,6 +1,7 @@
/* PR 90983/manual documents `-Wno-stack-usage` flag, but it is unrecognized
{ dg-do compile }
- { dg-options "-Wall -Wstack-usage=123 -Wno-stack-usage" } */
+ { dg-options "-Wall -Wstack-usage=123 -Wno-stack-usage" }
+ { dg-require-effective-target alloca } */
void f (void*);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c
index 12f8f9d..1907bac 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-15.c
@@ -4,7 +4,8 @@
for either kind of VLAs (member and non-member).
Diagnosing the accesses is the subject of pr82608.
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-array-bounds" } */
+ { dg-options "-O2 -Wall -Wno-array-bounds" }
+ { dg-require-effective-target alloca } */
void sink (void*);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-22.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-22.c
index a81ab99..8eaaa71 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-22.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-22.c
@@ -48,11 +48,18 @@ T (rindex, b + 4, '4'); // { dg-warning "missing terminating nul" "rindex" }
T (stpcpy, d, a); // { dg-warning "missing terminating nul" "stpcpy" }
T (stpncpy, d, a, 4);
-T (stpncpy, d, a, 5); // { dg-warning "missing terminating nul" "stpncpy" }
+T (stpncpy, d, a, 5); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "stpncpy" }
T (stpncpy, d, a, n);
-T (stpncpy, d, a + n, 4);
-T (stpncpy, d, a + n, 5); // { dg-warning "missing terminating nul" "stpncpy" }
+/* When the offset into an unterminated array isn't known and the bound
+ is less than the size of the array it suggests the access may be
+ constrained just right. When the bound is exactly equal to the size
+ of the array, then the offset would have to be zero for the access to
+ be safe, so a warning is justified. Otherwise, the bound is too small
+ and the access is definitely unsafe. */
+T (stpncpy, d, a + n, 3);
+T (stpncpy, d, a + n, 4); // { dg-warning "specified bound 4 may exceed the size of at most 4 of unterminated array" "stpncpy" }
+T (stpncpy, d, a + n, 5); // { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" "stpncpy" }
T (stpncpy, d, b, 4);
T (stpncpy, d, b, 5);
@@ -67,7 +74,7 @@ T (stpncpy, d, b + 3, 5);
T (stpncpy, d, b + 3, n);
T (stpncpy, d, b + 4, 1);
-T (stpncpy, d, b + 4, 2); // { dg-warning "missing terminating nul" "stpncpy" }
+T (stpncpy, d, b + 4, 2); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "stpncpy" }
T (stpncpy, d, b + 4, n);
/* The following might be worth warning about since it's only safe with
n < 4. */
@@ -84,7 +91,7 @@ T (strcasecmp, b, b + 4); // { dg-warning "missing terminating nul" "strcasecm
T (strcat, d, a); // { dg-warning "missing terminating nul" "strcat" }
T (strncat, d, a, 4);
-T (strncat, d, a, 5); // { dg-warning "missing terminating nul" "strncat" }
+T (strncat, d, a, 5); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strncat" }
T (strncat, d, a, n);
T (strncat, d, b, n);
@@ -93,7 +100,7 @@ T (strncat, d, b + 2, n);
T (strncat, d, b + 3, n);
T (strncat, d, b + 4, 0);
T (strncat, d, b + 4, 1);
-T (strncat, d, b + 4, 2); // { dg-warning "missing terminating nul" "strncat" }
+T (strncat, d, b + 4, 2); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "strncat" }
/* The following should probably trigger a warning since it's only safe
when n < 2, makes little sense with n == 0, and not much more with
n == 1. */
@@ -122,8 +129,8 @@ T (strncmp, s, a, 4);
/* The warning below is not issued because GCC folds strncmp calls with
the same arguments to zero before it checks for the missing nul. */
T (strncmp, a, a, 5); // { dg-warning "missing terminating nul" "pr92624" { xfail *-*-*} }
-T (strncmp, a, s, 5); // { dg-warning "missing terminating nul" "strcmp" }
-T (strncmp, s, a, 5); // { dg-warning "missing terminating nul" "strcmp" }
+T (strncmp, a, s, 5); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strcmp" }
+T (strncmp, s, a, 5); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strcmp" }
T (strcpy, d, a); // { dg-warning "missing terminating nul" "strcpy" }
@@ -136,10 +143,10 @@ T (strspn, s, a); // { dg-warning "missing terminating nul" "strcspn"
T (strdup, a); // { dg-warning "missing terminating nul" "strdup" }
T (strndup, a, 4);
-T (strndup, a, 5); // { dg-warning "missing terminating nul" "strndup" }
+T (strndup, a, 5); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strndup" }
T (strndup, b + 3, 2);
T (strndup, b + 4, 1);
-T (strndup, b + 4, 2); // { dg-warning "missing terminating nul" "strndup" }
+T (strndup, b + 4, 2); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "strndup" }
T (strlen, a); // { dg-warning "missing terminating nul" "strlen" }
@@ -161,11 +168,12 @@ T (__stpcpy_chk, d, a, -1); // { dg-warning "missing terminating nul"
T (__stpncpy_chk, d, a, 4, -1);
-T (__stpncpy_chk, d, a, 5, -1); // { dg-warning "missing terminating nul" "stpncpy_chk" }
+T (__stpncpy_chk, d, a, 5, -1); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "stpncpy_chk" }
T (__stpncpy_chk, d, a, n, -1);
-T (__stpncpy_chk, d, a + n, 4, -1);
-T (__stpncpy_chk, d, a + n, 5, -1); // { dg-warning "missing terminating nul" "stpncpy_chk" }
+T (__stpncpy_chk, d, a + n, 3, -1);
+T (__stpncpy_chk, d, a + n, 4, -1); // { dg-warning "specified bound 4 may exceed the size of at most 4 of unterminated array" "stpncpy_chk" }
+T (__stpncpy_chk, d, a + n, 5, -1); // { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" "stpncpy_chk" }
T (__stpncpy_chk, d, b, 4, -1);
T (__stpncpy_chk, d, b, 5, -1);
@@ -180,16 +188,17 @@ T (__stpncpy_chk, d, b + 3, 5, -1);
T (__stpncpy_chk, d, b + 3, n, -1);
T (__stpncpy_chk, d, b + 4, 1, -1);
-T (__stpncpy_chk, d, b + 4, 2, -1); // { dg-warning "missing terminating nul" "stpncpy_chk" }
+T (__stpncpy_chk, d, b + 4, 2, -1); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "stpncpy_chk" }
T (__stpncpy_chk, d, b + 4, n, -1);
T (__strncat_chk, d, a, 4, -1);
-T (__strncat_chk, d, a, 5, -1); // { dg-warning "missing terminating nul" "strncat_chk" }
+T (__strncat_chk, d, a, 5, -1); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strncat_chk" }
T (__strncat_chk, d, a, n, -1);
-T (__strncat_chk, d, a + n, 4, -1);
-T (__strncat_chk, d, a + n, 5, -1); // { dg-warning "missing terminating nul" "strncat_chk" }
+T (__strncat_chk, d, a + n, 3, -1);
+T (__strncat_chk, d, a + n, 4, -1); // { dg-warning "specified bound 4 may exceed the size of at most 4 of unterminated array" "strncat_chk" }
+T (__strncat_chk, d, a + n, 5, -1); // { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" "strncat_chk" }
T (__strncat_chk, d, b, 4, -1);
T (__strncat_chk, d, b, 5, -1);
@@ -204,16 +213,17 @@ T (__strncat_chk, d, b + 3, 5, -1);
T (__strncat_chk, d, b + 3, n, -1);
T (__strncat_chk, d, b + 4, 1, -1);
-T (__strncat_chk, d, b + 4, 2, -1); // { dg-warning "missing terminating nul" "strncat_chk" }
+T (__strncat_chk, d, b + 4, 2, -1); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "strncat_chk" }
T (__strncat_chk, d, b + 4, n, -1);
T (__strncpy_chk, d, a, 4, -1);
-T (__strncpy_chk, d, a, 5, -1); // { dg-warning "missing terminating nul" "strncpy_chk" }
+T (__strncpy_chk, d, a, 5, -1); // { dg-warning "specified bound 5 exceeds the size 4 of unterminated array" "strncpy_chk" }
T (__strncpy_chk, d, a, n, -1);
-T (__strncpy_chk, d, a + n, 4, -1);
-T (__strncpy_chk, d, a + n, 5, -1); // { dg-warning "missing terminating nul" "strncpy_chk" }
+T (__strncpy_chk, d, a + n, 3, -1);
+T (__strncpy_chk, d, a + n, 4, -1); // { dg-warning "specified bound 4 may exceed the size of at most 4 of unterminated array" "strncpy_chk" }
+T (__strncpy_chk, d, a + n, 5, -1); // { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" "strncpy_chk" }
T (__strncpy_chk, d, b, 4, -1);
T (__strncpy_chk, d, b, 5, -1);
@@ -228,7 +238,7 @@ T (__strncpy_chk, d, b + 3, 5, -1);
T (__strncpy_chk, d, b + 3, n, -1);
T (__strncpy_chk, d, b + 4, 1, -1);
-T (__strncpy_chk, d, b + 4, 2, -1); // { dg-warning "missing terminating nul" "strncpy" }
+T (__strncpy_chk, d, b + 4, 2, -1); // { dg-warning "specified bound 2 exceeds the size 1 of unterminated array" "strncpy" }
T (__strncpy_chk, d, b + 4, n, -1);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-23.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-23.c
index 6d9fcb9..0da916a 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-23.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-23.c
@@ -4,7 +4,8 @@
warnings are issued for calls to user-defined functions with attribute
access and with non-constant out-of-bounds arguments.
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
#include "range.h"
@@ -20,7 +21,7 @@ typedef __INT32_TYPE__ int32_t;
/* Exercise null pointer detection. */
RDONLY (2, 1) void
-rd2_1 (int, const void*); // { dg-message "in a call to function 'rd2_1' declared with attribute 'read_only \\\(2, 1\\\)" }
+rd2_1 (int, const void*); // { dg-message "in a call to function 'rd2_1' declared with attribute 'access \\\(read_only, 2, 1\\\)" "note" }
void test_rd2_1 (void)
{
@@ -39,12 +40,16 @@ void test_rd2_1 (void)
{
void *null = 0;
- rd2_1 (SR (1, 2), null); // { dg-warning "argument 2 is null but the corresponding size argument 1 range is \\\[1, 2]" }
+ /* Ideally the message would say "range" for a range and "value"
+ for a singular value but using the same reduces the complexity
+ of the code and keeps down the number of messages that need to
+ be translated, withot sacrificing (too much) clarity. */
+ rd2_1 (SR (1, 2), null); // { dg-warning "argument 2 is null but the corresponding size argument 1 range|value is \\\[1, 2]" }
}
}
WRONLY (3, 1) void
-wr3_1 (int, int, void*); // { dg-message "in a call to function 'wr3_1' declared with attribute 'write_only \\\(3, 1\\\)" }
+wr3_1 (int, int, void*); // { dg-message "in a call to function 'wr3_1' declared with attribute 'access \\\(write_only, 3, 1\\\)" }
void test_wr3_1 (void)
{
@@ -58,7 +63,7 @@ void test_wr3_1 (void)
void *null = 0;
- wr3_1 (SR (1, 2), 1, null); // { dg-warning "argument 3 is null but the corresponding size argument 1 range is \\\[1, 2]" }
+ wr3_1 (SR (1, 2), 1, null); // { dg-warning "argument 3 is null but the corresponding size argument 1 range|value is \\\[1, 2]" }
}
@@ -70,7 +75,7 @@ void test_wrd2_1 (int n)
wr2_1 (0, 0);
wr2_1 (SR (-1, 1), 0);
wr2_1 (SR (0, 1), 0);
- wr2_1 (SR (1, 2), 0); // { dg-warning "argument 2 is null but the corresponding size argument 1 range is \\\[1, 2]" }
+ wr2_1 (SR (1, 2), 0); // { dg-warning "argument 2 is null but the corresponding size argument 1 range|value is \\\[1, 2]" }
/* This should probably be diagnosed but to avoid false positives
caused by jump threading and such it would have to be done
@@ -126,7 +131,7 @@ void test_rd1_3_wr2_4 (const void *s, void *d, int n1, int n2)
rd1_3_wr2_4 (s, d, -1, 2); // { dg-warning "argument 3 value -1 is negative" }
const int ir_min_m1 = SR (INT_MIN, -1);
- rd1_3_wr2_4 (s, d, ir_min_m1, 2); // { dg-warning "argument 3 range \\\[-\[0-9\]+, -1] is negative" }
+ rd1_3_wr2_4 (s, d, ir_min_m1, 2); // { dg-warning "argument 3 range|value \\\[-\[0-9\]+, -1] is negative" }
rd1_3_wr2_4 (s, d, SR (-1, 0), 2);
rd1_3_wr2_4 (s, d, SR (INT_MIN, INT_MAX), 2);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-24.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-24.c
index a21a1f1..049d1c6 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-24.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-24.c
@@ -23,7 +23,7 @@ extern char d1[1], d2[2], d3[3];
the attribute without a size operand. */
RDONLY (1) void
-rd1_int (const int32_t*); // { dg-message "in a call to function 'rd1_int' declared with attribute 'read_only \\\(1\\\)'" }
+rd1_int (const int32_t*); // { dg-message "in a call to function 'rd1_int' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
void test_rd1_int (void)
{
@@ -39,7 +39,7 @@ void test_rd1_int (void)
the attribute and with non-zero size. */
RDONLY (2, 1) void
-rd2_1 (int, const void*); // { dg-message "in a call to function 'rd2_1' declared with attribute 'read_only \\\(2, 1\\\)" }
+rd2_1 (int, const void*); // { dg-message "in a call to function 'rd2_1' declared with attribute 'access \\\(read_only, 2, 1\\\)" "note" }
void test_rd2_1 (void)
{
@@ -49,7 +49,7 @@ void test_rd2_1 (void)
}
WRONLY (3, 1) void
-wr3_1 (int, int, void*); // { dg-message "in a call to function 'wr3_1' declared with attribute 'write_only \\\(3, 1\\\)" }
+wr3_1 (int, int, void*); // { dg-message "in a call to function 'wr3_1' declared with attribute 'access \\\(write_only, 3, 1\\\)" "note" }
void test_wr3_1 (void)
{
@@ -157,7 +157,7 @@ void test_rd6_1_wr5_2_rd4_3 (void)
{
rd6_1_wr5_2_rd4_3 (7, 2, 1, d1, d2, s3); // { dg-warning "reading 7 bytes from a region of size 3" }
rd6_1_wr5_2_rd4_3 (3, 8, 1, d1, d2, s3); // { dg-warning "writing 8 bytes into a region of size 2" }
- rd6_1_wr5_2_rd4_3 (3, 2, 9, d1, d2, s3); // { dg-warning "writing 9 bytes into a region of size 1" }
+ rd6_1_wr5_2_rd4_3 (3, 2, 9, d1, d2, s3); // { dg-warning "accessing 9 bytes in a region of size 1" }
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-25.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-25.c
index 109a1dd..bc60958 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-25.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-25.c
@@ -1,6 +1,7 @@
/* PR middle-end/91582 - missing heap overflow detection for strcpy
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
#include "range.h"
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
index 8e2cfe3..37c1ca2 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-27.c
@@ -2,7 +2,8 @@
PR middle-end/85484 - missing -Wstringop-overflow for strcpy with
a string of non-const length
{ dg-do compile }
- { dg-options "-O2 -Wall -Wno-array-bounds" } */
+ { dg-options "-O2 -Wall -Wno-array-bounds" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-33.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-33.c
index cb8aeb9..d4f7956 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-33.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-33.c
@@ -7,7 +7,7 @@ void fcst (char *d)
{
char a[2] = "0";
- __builtin_strcpy (d, a + 3); // { dg-warning "\\\[-W(array-bounds|stringop-overflow)" }
+ __builtin_strcpy (d, a + 3); // { dg-warning "\\\[-W(array-bounds|stringop-overread)" }
}
void frng (char *d, int i)
@@ -17,14 +17,14 @@ void frng (char *d, int i)
if (i < 3)
i = 3;
- __builtin_strcpy (d, a + i); // { dg-warning "\\\[-W(array-bounds|stringop-overflow)" }
+ __builtin_strcpy (d, a + i); // { dg-warning "\\\[-W(array-bounds|stringop-overread)" }
}
void gcst (char *d)
{
char a[2] = "0";
- __builtin_strcpy (d, a + 2); // { dg-warning "\\\[-W(array-bounds|stringop-overflow)" }
+ __builtin_strcpy (d, a + 2); // { dg-warning "\\\[-W(array-bounds|stringop-overread)" }
}
void grng (char *d, int i)
@@ -34,7 +34,7 @@ void grng (char *d, int i)
if (i < 2)
i = 2;
- __builtin_strcpy (d, a + i); // { dg-warning "\\\[-W(array-bounds|stringop-overflow)" }
+ __builtin_strcpy (d, a + i); // { dg-warning "\\\[-W(array-bounds|stringop-overread)" }
}
/* { dg-prune-output "-Wuninitialized" } */
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
index fd43f3a..a1b1039 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-34.c
@@ -112,7 +112,7 @@ void s2_warn_cstoff_cstidx (struct S2 *p)
void s2_warn_varoff_cstdix (struct S2 *p, int i)
{
char *q = p->a + i;
- q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" "pr?????" { xfail *-*-* } }
+ q[2] = __LINE__; // { dg-warning "\\\[-Wstringop-overflow" }
}
void s2_warn_cstoff_varidx (struct S2 *p, int i)
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
index 339f904..46f8fed 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-37.c
@@ -185,6 +185,18 @@ void test_note (const char *s)
}
{
+ char a[1][1][2]; // { dg-message "at offset 2 into " }
+ 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" }
+ 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 " }
strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
sink (a);
@@ -192,7 +204,13 @@ void test_note (const char *s)
{
char a[1][2][2]; // { dg-message "at offset 4 into " }
- strncpy (a[1][0], s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ 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 " }
+ strncpy (a[0][1], s, 3); // { dg-warning "writing 3 bytes into a region of size 0 " }
sink (a);
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-39.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-39.c
index f83646a..295a38d 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-39.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-39.c
@@ -1,7 +1,8 @@
/* PR middle-end/95667 - unintended warning for memset writing across multiple
members
{ dg-do compile }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
extern void sink (void*);
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-40.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-40.c
new file mode 100644
index 0000000..386c92d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-40.c
@@ -0,0 +1,120 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+typedef __INT16_TYPE__ int16_t;
+
+void fa2 (int16_t[2]);
+void fxa2 (int16_t[2]) __attribute__ ((nonnull));
+
+void fas2 (int16_t[static 2]);
+
+void fvla (unsigned n, int16_t[n]);
+
+void test_array_1_dim (void)
+{
+ int16_t a1[1];
+ int16_t a2[2];
+ int16_t i;
+
+ fa2 (0);
+ fa2 (a2);
+ fa2 (a1); // { dg-warning "'fa2' accessing 4 bytes in a region of size 2 " }
+ fa2 (&i); // { dg-warning "'fa2' accessing 4 bytes in a region of size 2 " }
+
+ fxa2 (0); // { dg-warning "\\\[-Wnonnull" }
+ fxa2 (a2);
+ fxa2 (a1); // { dg-warning "'fxa2' accessing 4 bytes in a region of size 2 " }
+ fxa2 (&i); // { dg-warning "'fxa2' accessing 4 bytes in a region of size 2 " }
+
+ fas2 (0); // { dg-warning "\\\[-Wnonnull" }
+ fas2 (a2);
+ fas2 (a1); // { dg-warning "'fas2' accessing 4 bytes in a region of size 2 " }
+ fas2 (&i); // { dg-warning "'fas2' accessing 4 bytes in a region of size 2 " }
+
+ fvla (1, 0); // { dg-warning "\\\[-Wnonnull" }
+ fvla (1, &i);
+ fvla (2, a2);
+ fvla (2, a1); // { dg-warning "'fvla' accessing 4 bytes in a region of size 2 " }
+ fvla (2, &i); // { dg-warning "'fvla' accessing 4 bytes in a region of size 2 " }
+}
+
+
+void fac2 (const int16_t[2]);
+void fxac2 (const int16_t[2]) __attribute__ ((nonnull));
+
+void facs2 (const int16_t[static 2]);
+
+void fvlac (unsigned n, const int16_t[n]);
+
+void test_const_array_1_dim (void)
+{
+ int16_t a1[1];
+ int16_t a2[2];
+ int16_t i;
+
+ fac2 (0);
+ fac2 (a2);
+ fac2 (a1); // { dg-warning "'fac2' reading 4 bytes from a region of size 2 " }
+ fac2 (&i); // { dg-warning "'fac2' reading 4 bytes from a region of size 2 " }
+
+ fxac2 (0); // { dg-warning "\\\[-Wnonnull" }
+ fxac2 (a2);
+ fxac2 (a1); // { dg-warning "'fxac2' reading 4 bytes from a region of size 2 " }
+ fxac2 (&i); // { dg-warning "'fxac2' reading 4 bytes from a region of size 2 " }
+
+ facs2 (0); // { dg-warning "\\\[-Wnonnull" }
+ facs2 (a2);
+ facs2 (a1); // { dg-warning "'facs2' reading 4 bytes from a region of size 2 " }
+ facs2 (&i); // { dg-warning "'facs2' reading 4 bytes from a region of size 2 " }
+
+ fvlac (1, 0); // { dg-warning "\\\[-Wnonnull" }
+ fvlac (1, &i);
+ fvlac (2, a2);
+ fvlac (2, a1); // { dg-warning "'fvlac' reading 4 bytes from a region of size 2 " }
+ fvlac (2, &i); // { dg-warning "'fvlac' reading 4 bytes from a region of size 2 " }
+}
+
+
+void fca3x5 (int16_t[3][5]);
+void fcas5x7 (int16_t[static 5][7]);
+
+struct Snx5 { int16_t a3x5[3][5], a2x5[2][5], a1x5[1][5]; };
+struct Snx7 { int16_t a5x7[5][7], a4x7[4][7], a1x7[1][7]; };
+struct S0x7 { int x; int16_t a0x7[0][7]; };
+
+void test_array_2_dim (struct Snx5 *px5, struct Snx7 *px7, struct S0x7 *p0x7)
+{
+ int16_t a0x5[0][5], a1x5[1][5], a2x5[2][5], a3x5[3][5], a4x5[4][5];
+
+ fca3x5 (a3x5);
+ fca3x5 (a4x5);
+ fca3x5 (a2x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 20" }
+ fca3x5 (a1x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 10" }
+ fca3x5 (a0x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 0" }
+
+ fca3x5 (px5->a3x5);
+ fca3x5 (px5->a2x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 20" }
+ fca3x5 (px5->a1x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 10" "pr96346" { xfail *-*-* } }
+
+ {
+ int16_t (*pa2x5)[5] = &a2x5[0];
+ fca3x5 (pa2x5); // { dg-warning "'fca3x5' accessing 30 bytes in a region of size 10" }
+ ++pa2x5;
+ fca3x5 (pa2x5); // { dg-warning "'fca3x5' accessing 30 bytes " }
+ }
+
+ int16_t a0x7[0][7], a1x7[1][7], a4x7[4][7], a5x7[5][7], a99x7[99][7];
+ fcas5x7 (a99x7);
+ fcas5x7 (a5x7);
+ fcas5x7 (a4x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 56" }
+ fcas5x7 (a1x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 14" }
+ fcas5x7 (a0x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 0" }
+
+ fcas5x7 (px7->a5x7);
+ fcas5x7 (px7->a4x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 56" }
+ fcas5x7 (px7->a1x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 14" "pr96346" { xfail *-*-* } }
+
+ fcas5x7 (p0x7->a0x7); // { dg-warning "'fcas5x7' accessing 70 bytes in a region of size 0" "pr96346" { xfail *-*-* } }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c
new file mode 100644
index 0000000..9b2d2cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-41.c
@@ -0,0 +1,120 @@
+/* Verify that writes at excessive offsets into declared or allocated
+ objects of unknown size are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#define DIFF_MAX __PTRDIFF_MAX__
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void* memcpy (void*, const void*, size_t);
+void* memset (void*, int, size_t);
+
+void sink (void*);
+
+
+void char_array_cst_off_cst_size (void)
+{
+ extern char caxcc[]; // { dg-message "at offset \\d+ into destination object 'caxcc'" }
+
+ char *p = caxcc;
+ size_t idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" "pr?????" { xfail ilp32 } }
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" }
+ sink (p);
+}
+
+
+void char_array_var_off_cst_size (size_t idx)
+{
+ /* The offset is a range with a very large lower bound and an upper
+ bound of DIFF_MAX. There's not point in also mentioning the latter
+ (it wouldn't make the note any more meaningful) so verify it only
+ mentions the lower bound. */
+ extern char caxvc[]; // { dg-message "at offset \\d+ into destination object 'caxvc'" "note" }
+
+ char *p = caxvc;
+
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+ sink (p);
+}
+
+
+void char_array_var_off_var_size (size_t idx, size_t n)
+{
+ extern char caxvv[]; // { dg-message "at offset \\d+ into destination object 'caxvv'" "note" }
+
+ char *p = caxvv;
+
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ if (n < 3 || 7 < n)
+ n = 3;
+
+ memset (p + idx, 0, n);
+ sink (p);
+
+ ++n;
+ memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
+ sink (p);
+}
+
+
+void alloc_array_var_off_cst_size (size_t n, size_t idx)
+{
+ char *p = malloc (n); // { dg-message "at offset \\d+ into destination object" "note" }
+
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+ sink (p);
+}
+
+
+void int_array_cst_off_cst_size (void)
+{
+ extern int iaxc[]; // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'iaxc'" }
+
+ int *p = iaxc;
+ size_t idx = DIFF_MAX / sizeof *iaxc;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+ sink (p);
+}
+
+
+void* nowarn_anti_range_1 (char *p, char *q)
+{
+ size_t n = q - p;
+ if (!n) return 0;
+
+ char *d = __builtin_malloc (n + 1);
+ memcpy (d, p, n + 1); // { dg-bogus "-Wstringop-overflow" }
+ return d;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c
new file mode 100644
index 0000000..4bb22f2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-42.c
@@ -0,0 +1,62 @@
+/* Verify -Wstringop-overflow a with destination pointer pointing either
+ before the beginning or past the end of an object.
+ { dg-do compile }
+ { dg-options "-O -Wall -Wno-array-bounds -Wno-restrict" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+char* strcpy (char *, const char *);
+
+
+extern char a[1];
+
+volatile char *d;
+
+void cpy_si_1_max (int i, const char *s)
+{
+ if (i < 1) i = 1;
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+}
+
+void cpy_ui_1_max (unsigned i, const char *s)
+{
+ if (i < 1) i = 1;
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { xfail ilp32 } }
+}
+
+void cpy_sl_1_max (long i, const char *s)
+{
+ if (i < 1) i = 1;
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+}
+
+void cpy_ul_1_max (unsigned long i, const char *s)
+{
+ if (i < 1) i = 1;
+
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+
+ /* Because of integer wraparound the offset's range is [1, 0] so
+ the overflow isn't diagnosed (yet). */
+ d = strcpy (a + i + 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" "" { xfail *-*-* } }
+}
+
+
+void cpy_si_min_m1 (int i, const char *s)
+{
+ if (i > -1) i = -1;
+ d = strcpy (a + i - 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i + 2, s);
+}
+
+void cpy_sl_min_m1 (long i, const char *s)
+{
+ if (i > -1) i = -1;
+ d = strcpy (a + i - 1, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i, s); // { dg-warning "writing 1 or more bytes into a region of size 0" }
+ d = strcpy (a + i + 2, s);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c
new file mode 100644
index 0000000..14ab925
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-43.c
@@ -0,0 +1,179 @@
+/* PR 96903 - bogus warning on memcpy at negative offset from array end
+ { dg-do compile }
+ { dg-options "-O2 -Wall -Wno-array-bounds -ftrack-macro-expansion=0" } */
+
+#include "range.h"
+
+#define INT_MAX __INT_MAX__
+#define INT_MIN -(INT_MAX - 1)
+#define UINT_MAX (2U * INT_MAX + 1)
+
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void *, int, size_t);
+
+void sink (void*, ...);
+
+extern char a11[11];
+struct S { char a11[11], b; };
+extern struct S sa11;
+
+#define T2(dst, off1, off2, n) do { \
+ char *_p0 = dst; \
+ char *_p1 = _p0 + (off1); \
+ char *_p2 = _p1 + (off2); \
+ memset (_p2, 0, n); \
+ sink (dst, _p0, _p1, _p2); \
+ } while (0);
+
+#define T1(dst, off, n) T2 (dst, off, 0, n)
+
+
+void nowarn_memset_array_cst (void)
+{
+ char *p = &a11[11];
+
+ T1 (p, -11, 11);
+ T1 (p, -10, 10);
+ T1 (p, -9, 9);
+ T1 (p, -8, 8);
+ T1 (p, -3, 3);
+ T1 (p, -2, 2);
+ T1 (p, -1, 1);
+ T1 (p, 0, 0);
+
+ T2 (p, -6, -5, 11);
+ T2 (p, -6, -4, 10);
+ T2 (p, -6, -3, 9);
+ T2 (p, -6, -2, 8);
+ T2 (p, -6, -1, 7);
+ T2 (p, -5, -6, 11);
+ T2 (p, -5, -5, 10);
+}
+
+void nowarn_memset_array_rng_int (void)
+{
+ char *p = &a11[11];
+
+ int i11 = SR (11, INT_MAX);
+ int i10 = SR (10, INT_MAX);
+ int i9 = SR ( 9, INT_MAX);
+ int i3 = SR ( 3, INT_MAX);
+ int i2 = SR ( 2, INT_MAX);
+ int i1 = SR ( 1, INT_MAX);
+ int i0 = SR ( 0, INT_MAX);
+
+ int m11 = SR (INT_MIN, -11);
+ int m10 = SR (INT_MIN, -10);
+ int m9 = SR (INT_MIN, -9);
+ int m3 = SR (INT_MIN, -3);
+ int m2 = SR (INT_MIN, -2);
+ int m1 = SR (INT_MIN, -1);
+ int m0 = SR (INT_MIN, -0);
+
+ T1 (p, m11, i11);
+ T1 (p, m10, i10);
+ T1 (p, m9, i9);
+ T1 (p, m3, i3);
+ T1 (p, m2, i2);
+ T1 (p, m1, i1);
+ T1 (p, m0, i0);
+
+ T1 (p, m11, i11);
+ T1 (p, m10, i10);
+ T1 (p, m9, i9);
+ T1 (p, m3, i3);
+ T1 (p, m2, i2);
+ T1 (p, m1, i1);
+ T1 (p, m0, i0);
+}
+
+
+void nowarn_memset_array_rng (void)
+{
+ char *p = &a11[11];
+
+ T2 (p, SR (-11, -10), SR ( -2, -1), UR (11, 12));
+ T2 (p, SR (-10, -9), SR ( -1, 0), UR (11, 13));
+ T2 (p, SR ( -9, -8), SR ( -2, -1), UR (11, 14));
+ T2 (p, SR ( -8, -7), SR ( -3, -2), UR (11, 15));
+ T2 (p, SR ( -7, -6), SR ( -4, -3), UR (11, 16));
+ T2 (p, SR ( -6, -5), SR ( -5, -4), UR (11, 17));
+ T2 (p, SR ( -5, -4), SR ( -6, -5), UR (11, 18));
+ T2 (p, SR ( -4, -3), SR ( -7, -6), UR (11, 19));
+ T2 (p, SR ( -3, -2), SR ( -8, -7), UR (11, INT_MAX));
+ T2 (p, SR ( -2, -1), SR ( -9, -8), UR (11, UINT_MAX));
+ T2 (p, SR ( -1, 0), SR (-10, -9), UR (11, DIFF_MAX));
+ T2 (p, SR ( 0, 1), SR (-11, -10), UR (11, SIZE_MAX));
+
+ T2 (p, SR (DIFF_MIN, -10), SR (DIFF_MIN, -1), UR (10, 12));
+
+ T2 (p, SR (-11, -10), SR ( -3, -1), UR (10, 12))
+ T2 (p, SR (-11, -10), SR ( -3, -1), UR (10, 12))
+}
+
+
+void warn_memset_array_rng (void)
+{
+ char *p = &a11[11];
+ size_t n11_12 = UR (11, 12);
+ size_t n10_12 = UR (10, 12);
+
+ T2 (p, SR (-11, -10), SR ( -3, -2), n11_12); // { dg-warning "writing between 11 and 12 bytes into a region of size 0" }
+ T2 (p, SR (-11, -10), SR ( -3, -2), n10_12); // { dg-warning "writing between 10 and 12 bytes into a region of size 0" }
+}
+
+
+void nowarn_memset_anti_range (void)
+{
+ size_t n11 = UR (11, SIZE_MAX);
+
+ char *p = &a11[11];
+
+ T1 (p, (int)SAR (INT_MIN, -12), n11);
+ T1 (p, (int)SAR ( -13, -13), n11);
+ T1 (p, (int)SAR ( -13, -12), n11);
+ T1 (p, (int)SAR ( -10, 1), n11);
+ T1 (p, (int)SAR ( -10, 11), n11);
+ T1 (p, (int)SAR ( -10, INT_MAX), n11);
+ T1 (p, (int)SAR ( -1, -1), n11);
+ T1 (p, (int)SAR ( -1, 0), n11);
+ T1 (p, (int)SAR ( -1, 11), n11);
+ T1 (p, (int)SAR ( -1, INT_MAX), n11);
+
+ T1 (p, SAR (DIFF_MIN, -12), n11);
+ T1 (p, SAR ( -13, -13), n11);
+ T1 (p, SAR ( -13, -12), n11);
+ T1 (p, SAR ( -10, 1), n11); // { dg-bogus "-Wstringop-overflow" }
+ T1 (p, SAR ( -10, 11), n11); // { dg-bogus "-Wstringop-overflow" }
+ T1 (p, SAR ( -10, DIFF_MAX), n11);
+ T1 (p, SAR ( -1, -1), n11); // { dg-bogus "-Wstringop-overflow" }
+ T1 (p, SAR ( -1, 0), n11); // { dg-bogus "-Wstringop-overflow" }
+ T1 (p, SAR ( -1, 11), n11); // { dg-bogus "-Wstringop-overflow" }
+ T1 (p, SAR ( -1, DIFF_MAX), n11);
+}
+
+void warn_memset_reversed_range (void)
+{
+ size_t n11 = UR (11, SIZE_MAX);
+
+ char *p = &a11[11];
+
+ /* Since the offset is excessive, either starting before &a11[0]
+ ot just past &a[11], the region size in the warning should
+ probably be zero, but accept other sizes too. */
+ T1 (p, SAR (INT_MIN, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" }
+
+ /* The following are represented as ordinary ranges with reversed bounds
+ and those are handled. */
+ T1 (p, SAR (INT_MIN, 11), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
+ /* In ILP32 the offset in the following has no range info associated
+ with it. */
+ T1 (p, SAR (INT_MIN, 1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" "pr?????" { xfail ilp32 } }
+ T1 (p, SAR (INT_MIN, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
+ /* Also represented as a true anti-range. */
+ T1 (p, SAR ( -12, -11), n11); // { dg-warning "writing 11 or more bytes into a region of size \\d+" }
+ T1 (p, SAR ( -12, -1), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
+ T1 (p, SAR ( -11, 0), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
+ T1 (p, SAR ( -11, 11), n11); // { dg-warning "writing 11 or more bytes into a region of size 0" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-44.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-44.c
new file mode 100644
index 0000000..9e292a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-44.c
@@ -0,0 +1,129 @@
+/* PR middle-end/97175 - ICE on an excessive strncpy bound
+ { dg-do compile }
+ { dg-options "-O -Wall" } */
+
+int n;
+
+char *d;
+
+void sink (void*);
+
+/* Exercise calls with a destination of unknown size. */
+
+void f0 (const void *s)
+{
+ if (n > 0) return;
+ __builtin_memcpy (d, s, n); // eliminated
+}
+
+void f1 (const void *s)
+{
+ if (n > 0) return;
+ __builtin_memmove (d, s, n); // eliminated
+}
+
+void f2 (void)
+{
+ if (n > 0) return;
+ __builtin_memset (d, 0, n); // eliminated
+}
+
+void f3 (const char *s)
+{
+ if (n > 0) return;
+ __builtin_strncpy (d, s, n); // can be eliminated but isn't
+}
+
+void f4 (const char *s)
+{
+ if (n > 0) return;
+ *d = 0;
+ __builtin_strncat (d, s, n); // can be eliminated but isn't
+}
+
+
+/* Exercise the same calls but with a declared destination object. */
+
+void g0 (const void *s)
+{
+ if (n > 0) return;
+ char a[1];
+ __builtin_memcpy (a, s, n); // eliminated
+ sink (a);
+}
+
+void g1 (const void *s)
+{
+ if (n > 0) return;
+ char a[1];
+ __builtin_memmove (a, s, n); // eliminated
+ sink (a);
+}
+
+void g2 (void)
+{
+ if (n > 0) return;
+ char a[1];
+ __builtin_memset (a, 0, n); // eliminated
+ sink (a);
+}
+
+void g3 (const char *s)
+{
+ if (n > 0) return;
+ char a[1];
+ __builtin_strncpy (a, s, n); // can be eliminated but isn't
+ sink (a);
+}
+
+void g4 (const char *s)
+{
+ if (n > 0) return;
+ char a[1];
+ *a = 0;
+ __builtin_strncat (a, s, n); // can be eliminated but isn't
+ sink (a);
+}
+
+
+void h0 (const void *s)
+{
+ if (n > 0) return;
+ d = __builtin_malloc (1);
+ __builtin_memcpy (d, s, n); // eliminated
+}
+
+void h1 (const void *s)
+{
+ if (n > 0) return;
+ d = __builtin_malloc (1);
+ __builtin_memmove (d, s, n); // eliminated
+}
+
+void h2 (void)
+{
+ if (n > 0) return;
+ d = __builtin_malloc (1);
+ __builtin_memset (d, 0, n); // eliminated
+}
+
+void h3 (const char *s)
+{
+ if (n > 0) return;
+ d = __builtin_malloc (1);
+ __builtin_strncpy (d, s, n); // can be eliminated but isn't
+}
+
+void h4 (const char *s)
+{
+ if (n > 0) return;
+ d = __builtin_malloc (1);
+ *d = 0;
+ __builtin_strncat (d, s, n); // can be eliminated but isn't
+}
+
+/* The calls above that aren't eliminated trigger
+ warning: specified size between INT_MAX and SIZE_MAX exceed maximum
+ object size PTRDIFF_MAX
+ { dg-prune-output "-Wstringop-overflow" }
+ { dg-prune-output "-Wstringop-overread" } */
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-44.s b/gcc/testsuite/gcc.dg/Wstringop-overflow-44.s
new file mode 100644
index 0000000..0fc73a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-44.s
@@ -0,0 +1,271 @@
+ .file "Wstringop-overflow-44.c"
+ .text
+ .p2align 4
+ .globl f0
+ .type f0, @function
+f0:
+.LFB0:
+ .cfi_startproc
+ ret
+ .cfi_endproc
+.LFE0:
+ .size f0, .-f0
+ .p2align 4
+ .globl f1
+ .type f1, @function
+f1:
+.LFB1:
+ .cfi_startproc
+ ret
+ .cfi_endproc
+.LFE1:
+ .size f1, .-f1
+ .p2align 4
+ .globl f2
+ .type f2, @function
+f2:
+.LFB2:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L12
+.L4:
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L12:
+ movslq %eax, %rdx
+ movq d(%rip), %rcx
+ testq %rdx, %rdx
+ je .L4
+ xorl %eax, %eax
+.L6:
+ movb $0, (%rcx,%rax)
+ addq $1, %rax
+ cmpq %rdx, %rax
+ jb .L6
+ ret
+ .cfi_endproc
+.LFE2:
+ .size f2, .-f2
+ .p2align 4
+ .globl f3
+ .type f3, @function
+f3:
+.LFB3:
+ .cfi_startproc
+ movslq n(%rip), %rdx
+ testl %edx, %edx
+ jle .L15
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L15:
+ movq %rdi, %rsi
+ movq d(%rip), %rdi
+ jmp strncpy
+ .cfi_endproc
+.LFE3:
+ .size f3, .-f3
+ .p2align 4
+ .globl f4
+ .type f4, @function
+f4:
+.LFB4:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L18
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L18:
+ movq d(%rip), %rax
+ movq %rdi, %rsi
+ movb $0, (%rax)
+ movslq n(%rip), %rdx
+ movq d(%rip), %rdi
+ jmp strncat
+ .cfi_endproc
+.LFE4:
+ .size f4, .-f4
+ .p2align 4
+ .globl g0
+ .type g0, @function
+g0:
+.LFB5:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L25
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L25:
+ subq $24, %rsp
+ .cfi_def_cfa_offset 32
+ leaq 15(%rsp), %rdi
+ call sink
+ addq $24, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE5:
+ .size g0, .-g0
+ .p2align 4
+ .globl g1
+ .type g1, @function
+g1:
+.LFB6:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L32
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L32:
+ subq $24, %rsp
+ .cfi_def_cfa_offset 32
+ leaq 15(%rsp), %rdi
+ call sink
+ addq $24, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE6:
+ .size g1, .-g1
+ .p2align 4
+ .globl g2
+ .type g2, @function
+g2:
+.LFB7:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L45
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L45:
+ movslq %eax, %rdx
+ subq $24, %rsp
+ .cfi_def_cfa_offset 32
+ testq %rdx, %rdx
+ je .L36
+ xorl %eax, %eax
+.L35:
+ movb $0, 15(%rsp,%rax)
+ addq $1, %rax
+ cmpq %rdx, %rax
+ jb .L35
+.L36:
+ leaq 15(%rsp), %rdi
+ call sink
+ addq $24, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE7:
+ .size g2, .-g2
+ .p2align 4
+ .globl g3
+ .type g3, @function
+g3:
+.LFB8:
+ .cfi_startproc
+ movslq n(%rip), %rdx
+ testl %edx, %edx
+ jle .L52
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L52:
+ subq $24, %rsp
+ .cfi_def_cfa_offset 32
+ movq %rdi, %rsi
+ leaq 15(%rsp), %rdi
+ call strncpy
+ leaq 15(%rsp), %rdi
+ call sink
+ addq $24, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE8:
+ .size g3, .-g3
+ .p2align 4
+ .globl g4
+ .type g4, @function
+g4:
+.LFB9:
+ .cfi_startproc
+ movslq n(%rip), %rdx
+ testl %edx, %edx
+ jle .L59
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L59:
+ subq $24, %rsp
+ .cfi_def_cfa_offset 32
+ movq %rdi, %rsi
+ leaq 15(%rsp), %rdi
+ movb $0, 15(%rsp)
+ call strncat
+ leaq 15(%rsp), %rdi
+ call sink
+ addq $24, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE9:
+ .size g4, .-g4
+ .p2align 4
+ .globl h0
+ .type h0, @function
+h0:
+.LFB10:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L66
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L66:
+ subq $8, %rsp
+ .cfi_def_cfa_offset 16
+ movl $1, %edi
+ call malloc
+ movq %rax, d(%rip)
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE10:
+ .size h0, .-h0
+ .p2align 4
+ .globl h1
+ .type h1, @function
+h1:
+.LFB16:
+ .cfi_startproc
+ movl n(%rip), %eax
+ testl %eax, %eax
+ jle .L73
+ ret
+ .p2align 4,,10
+ .p2align 3
+.L73:
+ subq $8, %rsp
+ .cfi_def_cfa_offset 16
+ movl $1, %edi
+ call malloc
+ movq %rax, d(%rip)
+ addq $8, %rsp
+ .cfi_def_cfa_offset 8
+ ret
+ .cfi_endproc
+.LFE16:
+ .size h1, .-h1
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-45.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-45.c
new file mode 100644
index 0000000..112d79a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-45.c
@@ -0,0 +1,255 @@
+/* PR middle-end/97023 - missing warning on buffer overflow in chained mempcpy
+ Verify that out of bounds writes by built-ins to objects through pointers
+ returned by other built-ins are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#include "range.h"
+
+void* malloc (size_t);
+void* memcpy (void*, const void*, size_t);
+void* memmove (void*, const void*, size_t);
+void* mempcpy (void*, const void*, size_t);
+
+void sink (void*, ...);
+
+
+void nowarn_memcpy (const void *s)
+{
+ extern char cpy_a4[4];
+ unsigned n = sizeof cpy_a4;
+
+ void *p = cpy_a4;
+ p = memcpy (p, s, n);
+ sink (p);
+ memcpy (p, s, n);
+ sink (p);
+
+ p = cpy_a4 + 1;
+ p = memcpy (p, s, n - 1);
+ sink (p);
+ memcpy (p, s, n - 1);
+ sink (p);
+
+ p = cpy_a4 + 2;
+ p = memcpy (p, s, n - 2);
+ sink (p);
+ memcpy (p, s, n - 2);
+ sink (p);
+
+ p = cpy_a4 + 3;
+ p = memcpy (p, s, n - 3);
+ sink (p);
+ memcpy (p, s, n - 3);
+ sink (p);
+
+ p = cpy_a4 + 4;
+ p = memcpy (p, s, n - 4);
+ sink (p);
+ memcpy (p, s, n - 4);
+ sink (p);
+}
+
+
+void nowarn_memcpy_chain (const void *s)
+{
+ extern char cpy_a8[8];
+
+ char *p = cpy_a8;
+
+ p = memcpy (p + 1, s, 7);
+ sink (p);
+
+ p = memcpy (p + 2 , s, 5);
+ sink (p);
+
+ p = memcpy (p + 3 , s, 2);
+ sink (p);
+
+ p = memcpy (p + 1 , s, 1);
+ sink (p);
+
+ p = memcpy (p - 7 , s, 8);
+ sink (p);
+
+ memcpy (p + 1, s, 7);
+}
+
+
+void warn_memcpy (const void *s)
+{
+ extern char cpy_a5[5]; // { dg-message "destination object 'cpy_a5'" "note" }
+
+ unsigned n = sizeof cpy_a5;
+ void *p = cpy_a5;
+
+ p = memcpy (p, s, n);
+ sink (p);
+ memcpy (p, s, n + 1); // { dg-warning "writing 6 bytes into a region of size 5" }
+ sink (p);
+
+ p = cpy_a5;
+ p = memcpy (p, s, n);
+ sink (p);
+ memcpy (p, s, n + 1); // { dg-warning "writing 6 bytes into a region of size 5" }
+ sink (p);
+
+ p = cpy_a5 + 1;
+ p = memcpy (p, s, n - 1);
+ sink (p);
+ memcpy (p, s, n); // { dg-warning "writing 5 bytes into a region of size 4" }
+ sink (p);
+}
+
+
+void warn_memcpy_chain (const void *s)
+{
+ extern char cpy_a8[8]; // { dg-message "destination object 'cpy_a8'" "note" }
+
+ char *p = cpy_a8;
+
+ p = memcpy (p, s, 9); // { dg-warning "writing 9 bytes into a region of size 8" }
+ sink (p);
+
+ p = memcpy (p + 2, s, 7); // { dg-warning "writing 7 bytes into a region of size 6" }
+ sink (p);
+
+ p = memcpy (p + 3, s, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+ sink (p);
+
+ p = memcpy (p + 3, s, 3); // { dg-warning "writing 3 bytes into a region of size 0" }
+ sink (p);
+}
+
+
+void nowarn_mempcpy (const void *s)
+{
+ extern char a4[4];
+ unsigned n = sizeof a4;
+
+ char *p = mempcpy (a4, s, n);
+ sink (p);
+ mempcpy (p - 4, s, n);
+ sink (p);
+
+ p = mempcpy (a4 + 1, s, n - 1);
+ sink (p);
+ mempcpy (p - 4, s, n);
+ sink (p);
+
+ p = mempcpy (a4 + 2, s, n - 2);
+ sink (p);
+ mempcpy (p - 4, s, n);
+ sink (p);
+
+ p = mempcpy (a4 + 3, s, n - 3);
+ sink (p);
+ mempcpy (p - 4, s, n);
+ sink (p);
+
+ p = mempcpy (a4 + 4, s, n - 4);
+ sink (p);
+ mempcpy (p - 4, s, n);
+ sink (p);
+}
+
+
+void nowarn_mempcpy_chain (const void *s)
+{
+ extern char pcpy_a8[8];
+
+ char *p = pcpy_a8;
+
+ p = mempcpy (p + 1, s, 7);
+ sink (p);
+
+ p = mempcpy (p - 7 , s, 7);
+ sink (p);
+
+ p = mempcpy (p - 5 , s, 5);
+ sink (p);
+
+ p = mempcpy (p - 3 , s, 3);
+ sink (p);
+
+ p = mempcpy (p - 2 , s, 2);
+ sink (p);
+
+ mempcpy (p - 1, s, 1);
+ sink (p);
+
+ mempcpy (p - 8, s, 8);
+}
+
+
+void warn_mempcpy (const void *s)
+{
+ extern char pcpy_a5[5]; // { dg-message "destination object 'pcpy_a5'" "note" }
+
+ char *p = pcpy_a5;
+
+ p = mempcpy (p, s, 5);
+ sink (p);
+ mempcpy (p - 5, s, 6); // { dg-warning "writing 6 bytes into a region of size 5 " }
+ sink (p);
+
+ p = pcpy_a5;
+ p = mempcpy (p, s, 3);
+ sink (p);
+ mempcpy (p, s, 3); // { dg-warning "writing 3 bytes into a region of size 2 " }
+ sink (p);
+
+ p = pcpy_a5 + 1;
+ p = mempcpy (p, s, 3);
+ sink (p);
+ mempcpy (p - 1, s, 5); // { dg-warning "writing 5 bytes into a region of size 2 " }
+ sink (p);
+}
+
+
+void warn_mempcpy_chain_3 (const void *s)
+{
+ char *p = malloc (5); // { dg-message "at offset \\\[3, 5] into destination object of size 5" "note" }
+ p = mempcpy (p, s, UR (1, 2));
+ p = mempcpy (p, s, UR (2, 3));
+ p = mempcpy (p, s, UR (3, 4)); // { dg-warning "writing between 3 and 4 bytes into a region of size 2 " }
+
+ sink (p);
+}
+
+void warn_mempcpy_offrng_chain_3 (const void *s)
+{
+ char *p = malloc (11); // { dg-message "at offset \\\[9, 11] into destination object of size 11 " "note" }
+ size_t r1_2 = UR (1, 2);
+ size_t r2_3 = r1_2 + 1;
+ size_t r3_4 = r2_3 + 1;
+
+ p = mempcpy (p + r1_2, s, r1_2);
+ p = mempcpy (p + r2_3, s, r2_3);
+ p = mempcpy (p + r3_4, s, r3_4); // { dg-warning "writing between 3 and 4 bytes into a region of size 2 " }
+
+ sink (p);
+}
+
+void warn_mempcpy_chain_4 (const void *s)
+{
+ char *p = malloc (9); // { dg-message "at offset \\\[6, 9] into destination object of size 9 " "note" }
+ p = mempcpy (p, s, UR (1, 2));
+ p = mempcpy (p, s, UR (2, 3));
+ p = mempcpy (p, s, UR (3, 4));
+ p = mempcpy (p, s, UR (4, 5)); // { dg-warning "writing between 4 and 5 bytes into a region of size 3 " }
+
+ sink (p);
+}
+
+void warn_mempcpy_chain_5 (const void *s)
+{
+ char *p = malloc (14); // { dg-message "at offset \\\[10, 14] into destination object of size 14 " "note" }
+ p = mempcpy (p, s, UR (1, 2));
+ p = mempcpy (p, s, UR (2, 3));
+ p = mempcpy (p, s, UR (3, 4));
+ p = mempcpy (p, s, UR (4, 5));
+ p = mempcpy (p, s, UR (5, 6)); // { dg-warning "writing between 5 and 6 bytes into a region of size 4 " }
+
+ sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
new file mode 100644
index 0000000..a4d78b2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-46.c
@@ -0,0 +1,97 @@
+/* PR middle-end/97023 - missing warning on buffer overflow in chained mempcpy
+ Verify that out of bounds writes by built-ins to objects through pointers
+ returned by memchr() are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#include "range.h"
+
+void* malloc (size_t);
+void* memchr (void*, int, size_t);
+void* memset (void*, int, size_t);
+
+void sink (void*, ...);
+
+void nowarn_memchr_cst_memset_cst (const void *s)
+{
+ char *p = malloc (4);
+ sink (p);
+
+ p = memchr (p, '1', 4);
+ memset (p, 0, 4);
+}
+
+void nowarn_memchr_uint_memset_cst (const void *s, unsigned n)
+{
+ char *p = malloc (4);
+ sink (p);
+
+ p = memchr (p, '1', n);
+ memset (p, 0, 4);
+}
+
+void nowarn_memchr_sz_memset_cst (const void *s, size_t n)
+{
+ char *p = malloc (4);
+ sink (p);
+
+ p = memchr (p, '1', n);
+ memset (p, 0, 4);
+}
+
+void nowarn_memchr_anti_range_memset_cst (const void *s, size_t n)
+{
+ char *p = malloc (4);
+ sink (p);
+
+ if (n == 0)
+ n = 1;
+
+ p = memchr (p, '1', n);
+ memset (p, 0, 4);
+}
+
+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" }
+ sink (p);
+
+ p = memchr (p, '1', 4);
+ memset (p, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+}
+
+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" }
+ sink (p);
+
+ p = memchr (p, '1', n);
+ memset (p, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4 " }
+}
+
+void warn_memchr_var_memset_range (const void *s, unsigned n)
+{
+ /* The offsets in the first two notes are bounded by the size of
+ the allocated object. The real upper bound of the offset in
+ the last note includes the upper bound f the offset of the pointer
+ returned from the previous memchr() call, but it ends up getting
+ constrained to the bounds of the allocated object so it's the same
+ 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 }
+
+ sink (p0);
+ char *p1 = memchr (p0, '1', n);
+ memset (p1, 0, UR (8, 9)); // { dg-warning "writing between 8 and 9 bytes into a region of size 7 " }
+
+ sink (p0);
+ p1 = memchr (p0 + 1, '2', n);
+ memset (p1, 0, UR (7, 9)); // { dg-warning "writing between 7 and 9 bytes into a region of size 6 " }
+
+ sink (p0);
+ char *p2 = memchr (p1 + 1, '3', n);
+ memset (p2, 0, UR (6, 9)); // { dg-warning "writing between 6 and 9 bytes into a region of size 5 " }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
new file mode 100644
index 0000000..02b14ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-47.c
@@ -0,0 +1,69 @@
+/* Verify that storing a bigger vector into smaller space is diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+typedef __INT16_TYPE__ int16_t;
+typedef __attribute__ ((__vector_size__ (32))) char C32;
+
+typedef __attribute__ ((__vector_size__ (64))) int16_t I16_64;
+
+void sink (void*);
+
+
+void nowarn_c32 (char c)
+{
+ extern char nowarn_a32[32];
+
+ void *p = nowarn_a32;
+ *(C32*)p = (C32){ c };
+ sink (p);
+
+ char a32[32];
+ p = a32;
+ *(C32*)p = (C32){ c };
+ sink (p);
+}
+
+void warn_c32 (char c)
+{
+ extern char warn_a32[32]; // { dg-message "at offset 32 to object 'warn_a32' with size 32" }
+
+ void *p = warn_a32 + 1;
+ *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" }
+
+ /* Verify a local variable too. */
+ char a32[32];
+ p = a32 + 1;
+ *(C32*)p = (C32){ c }; // { dg-warning "writing 1 byte into a region of size 0" }
+ sink (p);
+}
+
+
+void nowarn_i16_64 (int16_t i)
+{
+ extern char nowarn_a64[64];
+
+ void *p = nowarn_a64;
+ I16_64 *q = (I16_64*)p;
+ *q = (I16_64){ i };
+
+ char a64[64];
+ q = (I16_64*)a64;
+ *q = (I16_64){ i };
+ sink (q);
+}
+
+void warn_i16_64 (int16_t i)
+{
+ extern char warn_a64[64]; // { dg-message "at offset 128 to object 'warn_a64' with size 64" "pr97027" { xfail *-*-* } }
+
+ void *p = warn_a64 + 1;
+ I16_64 *q = (I16_64*)p;
+ *q = (I16_64){ i }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
+
+ char a64[64];
+ p = a64 + 1;
+ q = (I16_64*)p;
+ *q = (I16_64){ i }; // { dg-warning "writing 1 byte into a region of size 0" "pr97027" { xfail *-*-* } }
+ sink (p);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-49.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-49.c
new file mode 100644
index 0000000..84b6c94
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-49.c
@@ -0,0 +1,146 @@
+/* Verify the handling of anti-ranges/multi-ranges by allocation functions
+ and subsequent accesses.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+void* malloc (size_t);
+void bzero (void*, size_t);
+void* memset (void*, int, size_t);
+
+
+/* Exercise size_t (via malloc and memset) and unsigned/signed int. */
+
+__attribute__ ((alloc_size (1))) void*
+alloc_int (int);
+
+__attribute__ ((access (write_only, 1, 2))) void
+access_int (void*, int);
+
+__attribute__ ((alloc_size (1))) void*
+alloc_uint (unsigned);
+
+__attribute__ ((access (write_only, 1, 2))) void
+access_uint (void*, unsigned);
+
+
+void* nowarn_malloc_memset_same_anti_range (size_t n)
+{
+ /* Set N to the anti-range ~[3, 3]. */
+ if (n == 3)
+ n = 4;
+ void *p = malloc (n);
+
+ /* Verify there is no warning for an access to N bytes at P.
+ This means the warning has to assume the value of N in the call
+ to alloc() is in the larger subrange [4, UINT_MAX], while in
+ the call to access() in [0, 3]. */
+ return memset (p, 0, n);
+}
+
+/* Same as above but with two valid ranges. */
+
+void* nowarn_malloc_memset_anti_range (size_t n1, size_t n2)
+{
+ /* Set N1 to the anti-range ~[3, 3]. */
+ if (n1 == 3)
+ n1 = 4;
+ void *p = malloc (n1);
+
+ /* Set N2 to the anti-range ~[7, 7]. */
+ if (n2 == 7)
+ n2 = 8;
+
+ return memset (p, 0, n2);
+}
+
+
+void nowarn_alloc_access_same_anti_range_int (int n)
+{
+ /* Set N to the anti-range ~[3, 3]. */
+ if (n == 3)
+ n = 4;
+ void *p = alloc_int (n);
+
+ /* Verify there is no warning for an access to N bytes at P.
+ This means the warning has to assume the value of N in the call
+ to alloc() is in the larger subrange [4, UINT_MAX], while in
+ the call to access() in [0, 3]. */
+ access_int (p, n);
+}
+
+/* Same as above but with two valid ranges. */
+
+void nowarn_alloc_access_anti_range_int (int n1, int n2)
+{
+ /* Set N1 to the anti-range ~[3, 3]. */
+ if (n1 == 3)
+ n1 = 4;
+ void *p = alloc_int (n1);
+
+ /* Set N2 to the anti-range ~[7, 7]. */
+ if (n2 == 7)
+ n2 = 8;
+
+ access_int (p, n2);
+}
+
+
+void nowarn_alloc_access_same_anti_range_uint (unsigned n)
+{
+ /* Set N to the anti-range ~[3, 3]. */
+ if (n == 3)
+ n = 4;
+ void *p = alloc_uint (n);
+
+ /* Verify there is no warning for an access to N bytes at P.
+ This means the warning has to assume the value of N in the call
+ to alloc() is in the larger subrange [4, UINT_MAX], while in
+ the call to access() in [0, 3]. */
+ access_uint (p, n);
+}
+
+/* Same as above but with two valid ranges. */
+
+void nowarn_alloc_access_anti_range_uint (unsigned n1, unsigned n2)
+{
+ /* Set N1 to the anti-range ~[3, 3]. */
+ if (n1 == 3)
+ n1 = 4;
+ void *p = alloc_uint (n1);
+
+ /* Set N2 to the anti-range ~[7, 7]. */
+ if (n2 == 7)
+ n2 = 8;
+
+ access_uint (p, n2);
+}
+
+
+void* nowarn_malloc_anti_range_memset_range (size_t n1, size_t n2)
+{
+ /* Set N1 to the anti-range ~[3, 3]. */
+ if (n1 == 3)
+ n1 = 4;
+ void *p = malloc (n1);
+
+ /* Set N2 to the range [5, MAX]. */
+ if (n2 < 5)
+ n2 = 5;
+ return memset (p, 0, n2);
+}
+
+void* nowarn_malloc_range_bzero_anti_range (size_t n1, size_t n2)
+{
+ /* Set N1 to the anti-range ~[3, 3]. */
+ if (n1 > 4)
+ n1 = 4;
+ void *p = malloc (n1);
+
+ /* Set N2 to the range [5, MAX]. */
+ if (n2 <= 3 || 5 <= n2)
+ n2 = 4;
+ bzero (p, n2);
+ return p;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-50.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-50.c
new file mode 100644
index 0000000..7df58e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-50.c
@@ -0,0 +1,125 @@
+/* Verify that writes at excessive offsets into objects of unknown size
+ pointed to by function arguments are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#define DIFF_MAX __PTRDIFF_MAX__
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void*, int, size_t);
+
+void sink (void*);
+
+char* fcall (void);
+
+void char_ptr_cst_off_cst_size (char *p)
+ // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
+{
+ size_t idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" }
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" }
+}
+
+
+void char_ptr_var_difoff_cst_size (ptrdiff_t idx)
+{
+ char *p = fcall ();
+ /* The offset is a range with a very large lower bound and an upper
+ bound of DIFF_MAX. There's not point in also mentioning the latter
+ (it wouldn't make the note any more meaningful) so verify it only
+ mentions the lower bound.
+ { dg-message "at offset \\d+ into destination object of size \\\[0, \\d+] (allocated|returned) by 'fcall'" "note" { target *-*-* } .-5 } */
+
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+}
+
+
+void char_ptr_var_szoff_cst_size (size_t idx)
+{
+ extern char* gptr;
+ // { dg-message "at offset \\d+ into destination object 'gptr'" "note" { target *-*-* } .-1 }
+
+ char *p = gptr;
+
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" "" { xfail *-*-* } }
+
+ if (idx > DIFF_MAX)
+ idx = DIFF_MAX;
+
+ memset (p + idx, 0, 7); // { dg-warning "writing 7 bytes into a region of size 3" }
+}
+
+
+void char_ptr_var_difoff_var_size (char *p, ptrdiff_t idx, size_t n)
+ // { dg-message "at offset \\d+ into destination object 'p'" "note" { target *-*-* } .-1 }
+{
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ if (n < 3 || 7 < n)
+ n = 3;
+
+ memset (p + idx, 0, n);
+ sink (p);
+
+ ++n;
+ memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
+}
+
+
+void char_ptr_var_szoff_var_size (char *p, size_t idx, size_t n)
+ // { dg-message "at offset \\\[\[1-9\]\[0-9\]+, \[1-9\]\[0-9\]+] into destination object 'p'" "note" { xfail *-*-* } .-1 }
+{
+ if (idx < DIFF_MAX - 3)
+ idx = DIFF_MAX - 3;
+
+ if (n < 3 || 7 < n)
+ n = 3;
+
+ memset (p + idx, 0, n);
+ sink (p);
+
+ ++n;
+ /* With an unsigned offset large values are interpreted as negative
+ so the addition (p + idx) is effectively treated as subtraction,
+ making an overflow indistinguishable from a valid (if unlikely)
+ store. */
+ memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" "pr?????" { xfail *-*-* } }
+}
+
+
+void int_ptr_cst_off_cst_size (int *p)
+ // { dg-message "at offset \[1-9\]\[0-9\]+ into destination object 'p'" "note" { target *-*-* } .-1 }
+{
+ size_t idx = DIFF_MAX / sizeof *p;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-51.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-51.c
new file mode 100644
index 0000000..6f36643
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-51.c
@@ -0,0 +1,34 @@
+/* Test case derived from Binutils/GDB's readline/readline/histexpand.c.
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+char *
+get_subst_pattern (char *str, int *iptr, int delimiter, int is_rhs, int *lenptr)
+{
+ int si, i, j, k;
+ char *s;
+
+ s = 0;
+ i = *iptr;
+
+ for (si = i; str[si] && str[si] != delimiter; si++)
+ if (str[si] == '\\' && str[si + 1] == delimiter)
+ si++;
+
+ if (si > i || is_rhs)
+ {
+ s = (char *)__builtin_malloc (si - i + 1);
+ for (j = 0, k = i; k < si; j++, k++)
+ {
+ /* Remove a backslash quoting the search string delimiter. */
+ if (str[k] == '\\' && str[k + 1] == delimiter)
+ k++;
+ s[j] = str[k]; // { dg-bogus "-Wstringop-overflow" }
+ }
+ s[j] = '\0';
+ if (lenptr)
+ *lenptr = j;
+ }
+
+ return s;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-52.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-52.c
new file mode 100644
index 0000000..a289655
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-52.c
@@ -0,0 +1,62 @@
+
+/* PR middle-end/97023 - missing warning on buffer overflow in chained mempcpy
+ Verify that writes by built-in functions to objects through pointers
+ returned by ordinary (non-built-int) function are assumed to point to
+ the beginning of objects.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#include "range.h"
+
+void* memcpy (void*, const void*, size_t);
+void* memset (void*, int, size_t);
+
+void sink (void*, ...);
+
+extern char* arrptr[];
+extern char* ptr;
+extern char* retptr (void);
+struct S { char *p; };
+extern struct S retstruct (void);
+
+void nowarn_ptr (void)
+{
+ {
+ void *p = arrptr;
+ memset (p - 1, 0, 12345); // { dg-warning "\\\[-Wstringop-overflow" }
+ memset (p,0, 12345);
+ memset (p,0, DIFF_MAX - 1);
+ }
+
+ {
+ char *p = arrptr[0];
+ memset (p - 1, 0, 12345);
+ memset (p - 12345, 0, 12345);
+ memset (p - 1234, 0, DIFF_MAX - 1);
+ memset (p - DIFF_MAX + 1, 0, 12345);
+ }
+
+ {
+ char *p = ptr;
+ memset (p - 1, 0, 12345);
+ memset (p - 12345, 0, 12345);
+ memset (p - 1234, 0, DIFF_MAX - 1);
+ memset (p - DIFF_MAX + 1, 0, 12345);
+ }
+
+ {
+ char *p = retptr ();
+ memset (p - 1, 0, 12345);
+ memset (p - 12345, 0, 12345);
+ memset (p - 1234, 0, DIFF_MAX - 1);
+ memset (p - DIFF_MAX + 1, 0, 12345);
+ }
+
+ {
+ char *p = retstruct ().p;
+ memset (p - 1, 0, 12345);
+ memset (p - 12345, 0, 12345);
+ memset (p - 1234, 0, DIFF_MAX - 1);
+ memset (p - DIFF_MAX + 1, 0, 12345);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-53.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-53.c
new file mode 100644
index 0000000..cd8fa32
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-53.c
@@ -0,0 +1,116 @@
+/* PR middle-end/96384 - bogus -Wstringop-overflow= storing into
+ multidimensional array with index in range
+ { dg-do compile }
+ { dg-options "-O2 -Wall" } */
+
+#define SHRT_MAX __SHRT_MAX__
+#define SHRT_MIN (-SHRT_MAX - 1)
+#define INT_MAX __INT_MAX__
+#define INT_MIN (-INT_MAX - 1)
+#define LONG_MAX __LONG_MAX__
+#define LONG_MIN (-LONG_MAX - 1)
+
+#define USHRT_MAX (SHRT_MAX * 2 + 1)
+#define UINT_MAX ~0U
+#define ULONG_MAX ~0LU
+
+char ca3_5_7[3][5][7];
+
+void nowarn_ca_3_5_ssi (short i)
+{
+ if (i > SHRT_MAX - 1)
+ i = SHRT_MAX - 1;
+
+ ca3_5_7[i][0][0] = __LINE__;
+ ca3_5_7[i][0][1] = __LINE__;
+ ca3_5_7[i][0][2] = __LINE__;
+ ca3_5_7[i][0][3] = __LINE__;
+ ca3_5_7[i][0][4] = __LINE__;
+ ca3_5_7[i][0][5] = __LINE__;
+ ca3_5_7[i][0][6] = __LINE__;
+
+ ca3_5_7[i][1][0] = __LINE__;
+ ca3_5_7[i][1][1] = __LINE__;
+ ca3_5_7[i][1][2] = __LINE__;
+ ca3_5_7[i][1][3] = __LINE__;
+ ca3_5_7[i][1][4] = __LINE__;
+ ca3_5_7[i][1][5] = __LINE__;
+ ca3_5_7[i][1][6] = __LINE__;
+
+ ca3_5_7[i][2][0] = __LINE__;
+ ca3_5_7[i][2][1] = __LINE__;
+ ca3_5_7[i][2][2] = __LINE__;
+ ca3_5_7[i][2][3] = __LINE__;
+ ca3_5_7[i][2][4] = __LINE__;
+ ca3_5_7[i][2][5] = __LINE__;
+ ca3_5_7[i][2][6] = __LINE__;
+
+ ca3_5_7[i][3][0] = __LINE__;
+ ca3_5_7[i][3][1] = __LINE__;
+ ca3_5_7[i][3][2] = __LINE__;
+ ca3_5_7[i][3][3] = __LINE__;
+ ca3_5_7[i][3][4] = __LINE__;
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[i][3][6] = __LINE__;
+
+ ca3_5_7[i][4][0] = __LINE__;
+ ca3_5_7[i][4][1] = __LINE__;
+ ca3_5_7[i][4][2] = __LINE__;
+ ca3_5_7[i][4][3] = __LINE__;
+ ca3_5_7[i][4][4] = __LINE__;
+ ca3_5_7[i][4][5] = __LINE__;
+ ca3_5_7[i][4][6] = __LINE__;
+
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
+
+void nowarn_ca_3_5_usi (unsigned short i)
+{
+ if (i > USHRT_MAX - 1)
+ i = USHRT_MAX - 1;
+
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
+
+void nowarn_ca_3_5_si (int i)
+{
+ if (i > INT_MAX - 1)
+ i = INT_MAX - 1;
+
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
+
+void nowarn_ca_3_5_ui (unsigned i)
+{
+ if (i > UINT_MAX - 1)
+ i = UINT_MAX - 1;
+
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
+
+void nowarn_ca_3_5_li (long i)
+{
+ if (i > LONG_MAX - 1)
+ i = LONG_MAX - 1;
+
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
+
+void nowarn_ca_3_5_uli (unsigned long i)
+{
+ if (i > ULONG_MAX - 1)
+ i = ULONG_MAX - 1;
+
+ ca3_5_7[i][3][5] = __LINE__;
+ ca3_5_7[1][i][5] = __LINE__;
+ ca3_5_7[2][3][i] = __LINE__;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
new file mode 100644
index 0000000..26568f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-54.c
@@ -0,0 +1,103 @@
+/* Verify that writes at excessive offsets into flexible array members
+ of extern or allocated objects of unknow size are diagnosed.
+ { dg-do compile }
+ { dg-options "-O2" } */
+
+#define DIFF_MAX __PTRDIFF_MAX__
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void*, int, size_t);
+
+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'" }
+
+ char *p = caxcc.a;
+ size_t idx = DIFF_MAX - 4;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 2" }
+ sink (p);
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 1" }
+
+ ++idx;
+ memset (p + idx, 0, 3); // { dg-warning "writing 3 bytes into a region of size 0" }
+}
+
+
+void char_flexarray_var_off_cst_size (ptrdiff_t idx)
+{
+ extern struct { char n, a[]; }
+ caxvc; // { dg-message "destination object 'caxvc'" }
+
+ char *p = caxvc.a;
+
+ if (idx < DIFF_MAX - 4)
+ idx = DIFF_MAX - 4;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+}
+
+
+void char_flexarray_var_off_var_size (size_t n, ptrdiff_t idx)
+{
+ extern struct { char n, a[]; }
+ caxvv; // { dg-message "destination object 'caxvv'" }
+
+ char *p = caxvv.a;
+
+ if (idx < DIFF_MAX - 4)
+ idx = DIFF_MAX - 4;
+
+ if (n < 3 || 7 < n)
+ n = 3;
+
+ memset (p + idx, 0, n);
+ sink (p);
+
+ ++n;
+ memset (p + idx, 0, n); // { dg-warning "writing between 4 and 8 bytes into a region of size 3" }
+}
+
+
+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" }
+
+ if (idx < DIFF_MAX - 4)
+ idx = DIFF_MAX - 4;
+
+ memset (p->a + idx, 0, 3);
+ sink (p);
+
+ memset (p->a + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+}
+
+
+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'" }
+
+ int *p = iaxc.a;
+ size_t idx = DIFF_MAX / sizeof *p - 1;
+
+ memset (p + idx, 0, 3);
+ sink (p);
+
+ memset (p + idx, 0, 5); // { dg-warning "writing 5 bytes into a region of size 3" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c
new file mode 100644
index 0000000..25f5b82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-55.c
@@ -0,0 +1,97 @@
+/* Verify that offsets in "anti-ranges" are handled correctly.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+typedef __SIZE_TYPE__ size_t;
+
+void* memset (void*, int, size_t);
+
+void sink (void*, ...);
+#define T(x) sink (x)
+
+
+void int_range_add_sub_ (int i, int j)
+{
+ if (i < 1) i = 1;
+ if (j > -1) j = -1;
+
+ char ca5[5]; // { dg-message "at offset \\\[1, 5]" "note" }
+ char *p0 = ca5; // offset
+ char *p1 = p0 + i; // 1-5
+ char *p2 = p1 + i; // 2-5
+ char *p3 = p2 + j; // 0-4
+ char *p4 = p3 + j; // 0-3
+ char *p5 = p4 + j; // 0-2
+ char *p6 = p5 + j; // 0-1
+ char *p7 = p6 + i; // 1-2
+
+ memset (p7, 0, 5); // { dg-warning "writing 5 bytes into a region of size 4" }
+
+ sink (p0, p1, p2, p3, p4, p5, p6, p7);
+}
+
+
+void ruint_arint_add (unsigned i, int j)
+{
+ i |= 1; // [1, UINT_MAX]
+ j |= 1; // [INT_MIN + 1, -1] U [1, INT_MAX]
+
+ char a[5]; // { dg-message "at offset \\\[1, 5]" "note" }
+ char *p0 = a; // offset
+ char *p1 = p0 + i; // 1-5
+ T (memset (p1, 0, 4));
+
+ char *p2 = p1 + j; // 0-5
+ T (memset (p2, 0, 5));
+
+ char *p3 = p2 + i; // 1-5
+ T (memset (p3, 0, 4));
+
+ char *p4 = p3 + j; // 0-5
+ T (memset (p4, 0, 5));
+
+ char *p5 = p4 + i; // 1-5
+ T (memset (p5, 0, 4));
+
+ char *p6 = p5 + j; // 0-5
+ T (memset (p6, 0, 5));
+
+ char *p7 = p6 + i; // 1-5
+ T (memset (p7, 0, 5)); // { dg-warning "writing 5 bytes into a region of size 4" "" }
+}
+
+
+void warn_ptrdiff_anti_range_add (ptrdiff_t i)
+{
+ i |= 1;
+
+ char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } }
+ char *p0 = ca5; // offset
+ char *p1 = p0 + i; // 1-5
+ char *p2 = p1 + i; // 2-5
+ char *p3 = p2 + i; // 3-5
+ char *p4 = p3 + i; // 4-5
+ char *p5 = p4 + i; // 5
+
+ memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } }
+
+ sink (p0, p1, p2, p3, p4, p5);
+}
+
+void warn_int_anti_range (int i)
+{
+ i |= 1;
+
+ char ca5[5]; // { dg-message "at offset \\\[1, 5]" "pr?????" { xfail *-*-* } }
+ char *p0 = ca5; // offset
+ char *p1 = p0 + i; // 1-5
+ char *p2 = p1 + i; // 2-5
+ char *p3 = p2 + i; // 3-5
+ char *p4 = p3 + i; // 4-5
+ char *p5 = p4 + i; // 5
+
+ memset (p5, 0, 5); // { dg-warning "writing 5 bytes into a region of size 0" "pr?????" { xfail *-*-* } }
+
+ sink (p0, p1, p2, p3, p4, p5);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-9.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-9.c
index 11db965..2df84b2 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow-9.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-9.c
@@ -63,10 +63,10 @@ void test_strncpy (void)
char* test_strndup (void)
{
- return strndup (s, SIZE_MAX - 5); /* { dg-warning ".strndup. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */
+ return strndup (s, SIZE_MAX - 5); /* { dg-warning ".strndup. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overread" } */
}
size_t test_strnlen (void)
{
- return strnlen (s, SIZE_MAX - 6); /* { dg-warning ".strnlen. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overflow=\\\]" } */
+ return strnlen (s, SIZE_MAX - 6); /* { dg-warning ".strnlen. specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+ \\\[-Wstringop-overread" } */
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow.c b/gcc/testsuite/gcc.dg/Wstringop-overflow.c
index 2c5f4f0..c615dae 100644
--- a/gcc/testsuite/gcc.dg/Wstringop-overflow.c
+++ b/gcc/testsuite/gcc.dg/Wstringop-overflow.c
@@ -51,8 +51,8 @@ void test_memcpy_array (const void *s)
T (a7 + UR (8, 9), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
T (a7 + UR (9, 10), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
- T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
- T (a7 + UR (DIFF_MAX, SIZE_MAX), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-*} } */
+ T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
+ T (a7 + UR (DIFF_MAX, SIZE_MAX), s, 7); /* { dg-warning "writing 7 bytes into a region of size 0" } */
/* This is valid. */
char *d = a7 + 7;
@@ -102,8 +102,8 @@ void test_strcpy_array (void)
T (a7 + UR (8, 9), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
T (a7 + UR (9, 10), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
- T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
- T (a7 + UR (DIFF_MAX, SIZE_MAX), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
+ T (a7 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
+ T (a7 + UR (DIFF_MAX, SIZE_MAX), "012345"); /* { dg-warning "writing 7 bytes into a region of size 0" } */
char *d = a7 + 7;
@@ -127,6 +127,6 @@ void test_strncpy_memarray (struct MemArray *p, const void *s)
T (p->a9 + UR (9, 10), s, 9); /* { dg-warning "writing 9 bytes into a region of size 0" } */
T (p->a9 + UR (10, 11), s, 9); /* { dg-warning "writing 9 bytes into a region of size 0" } */
- T (p->a9 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 1); /* { dg-warning "writing 1 byte into a region of size 0" "pr85350" { xfail *-*-* } } */
- T (p->a9 + UR (DIFF_MAX, SIZE_MAX), s, 3); /* { dg-warning "writing 3 bytes into a region of size 0" "pr85350" { xfail *-*-* } } */
+ T (p->a9 + UR (DIFF_MAX, DIFF_MAX + (size_t)1), s, 1); /* { dg-warning "writing 1 byte into a region of size 0" } */
+ T (p->a9 + UR (DIFF_MAX, SIZE_MAX), s, 3); /* { dg-warning "writing 3 bytes into a region of size 0" } */
}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread-2.c b/gcc/testsuite/gcc.dg/Wstringop-overread-2.c
new file mode 100644
index 0000000..16dc06d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread-2.c
@@ -0,0 +1,117 @@
+/* Verify -Wstringop-overread is issued for reading more than the maximum
+ object size but not for writing.
+ { dg-do compile }
+ { dg-options "-O2 -Wno-stringop-overflow -ftrack-macro-expansion=0" } */
+
+#define PTRDIFF_MAX __PTRDIFF_MAX__
+#define SIZE_MAX __SIZE_MAX__
+
+#define NOIPA __attribute__ ((noipa))
+
+typedef __SIZE_TYPE__ size_t;
+
+void* memchr (const void*, int, size_t);
+int memcmp (const void*, const void*, size_t);
+void* memcpy (const void*, const void*, size_t);
+
+int strncmp (const char*, const char*, size_t);
+char* strncat (char*, const char*, size_t);
+char* strncpy (char*, const char*, size_t);
+size_t strnlen (const char*, size_t);
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+#define T(exp) sink (exp)
+
+NOIPA void test_memchr (const void *p, int x)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (memchr (p, x, dmax));
+
+ T (memchr (p, x, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (memchr (p, x, dmax * 2)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (memchr (p, x, smax)); // { dg-warning "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA void test_memcmp (const void *p, const void *q)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (memcmp (p, q, dmax));
+
+ T (memcmp (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (memcmp (p, q, dmax * 2)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (memcmp (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA void test_memcpy (void *p, const void *q)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (memcpy (p, q, dmax));
+
+ T (memcpy (p, q, dmax + 1)); // -Wstringop-overflow disabled
+ T (memcpy (p, q, dmax * 2)); // ditto
+ T (memcpy (p, q, smax)); // ditto
+}
+
+
+NOIPA void test_strncmp (const char *p, const char *q)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (strncmp (p, q, dmax));
+
+ T (strncmp (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" "strncmp" }
+ T (strncmp (p, q, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" "strncmp" }
+ T (strncmp (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" "strncmp" }
+}
+
+NOIPA void test_strncat (char *p, const char *q)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (strncat (p, q, dmax));
+
+ T (strncat (p, q, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (strncat (p, q, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" }
+ T (strncat (p, q, smax)); // { dg-warning "\\\[-Wstringop-overread" }
+}
+
+NOIPA void test_strncpy (char *p, const char *q)
+{
+#if 0
+ /* Disabled: strncpy calls with an excissve bound trigger both
+ -Wstringop-overflow and, when the former option is disabled,
+ -Wstringop-overread. The latter should probably not trigger. */
+
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (strncpy (p, q, dmax));
+
+ T (strncpy (p, q, dmax + 1)); // -Wstringop-overflow disabled
+ T (strncpy (p, q, dmax * 2)); // ditto
+ T (strncpy (p, q, smax)); // ditto
+#endif
+}
+
+NOIPA void test_strnlen (const char *p)
+{
+ size_t dmax = PTRDIFF_MAX;
+ size_t smax = SIZE_MAX;
+
+ T (strnlen (p, dmax));
+
+ T (strnlen (p, dmax + 1)); // { dg-warning "specified bound \[0-9\]+ exceeds maximum object size" }
+ T (strnlen (p, dmax * 2)); // { dg-warning "\\\[-Wstringop-overread" }
+ T (strnlen (p, smax)); // { dg-warning "\\\[-Wstringop-overread" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread-3.c b/gcc/testsuite/gcc.dg/Wstringop-overread-3.c
new file mode 100644
index 0000000..6c2c6b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread-3.c
@@ -0,0 +1,188 @@
+/* Verify that calling strndup and strnlen with an unknown bound isn't
+ diagnosed regardless of the size of the array and the type of the bound.
+ { dg-do compile }
+ { dg-options "-O -Wall" } */
+
+#define NOIPA __attribute__ ((noipa))
+
+typedef __SIZE_TYPE__ size_t;
+
+extern char* strndup (const char*, size_t);
+extern size_t strnlen (const char*, size_t);
+
+/* TO DO: Passing a zero-length array to any function is almost certainly
+ a bug and should be diagnosed except perpaphs when the function also
+ takes a bound and its value is known to be zero. When this is
+ implemented this test will need to be adjusted. */
+extern char a0[0];
+
+extern char a1[1];
+
+NOIPA char* strndup_a0_si (short n)
+{
+ return strndup (a0, n);
+}
+
+NOIPA char* strndup_a0_i (int n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a0_li (long n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a0_lli (long long n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA char* strndup_a0_usi (unsigned short n)
+{
+ return strndup (a0, n);
+}
+
+NOIPA char* strndup_a0_ui (unsigned n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a0_uli (unsigned long n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a0_ulli (unsigned long long n)
+{
+ return strndup (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+
+NOIPA char* strndup_a1_si (short n)
+{
+ return strndup (a1, n);
+}
+
+NOIPA char* strndup_a1_i (int n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a1_li (long n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a1_lli (long long n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA char* strndup_a1_usi (unsigned short n)
+{
+ return strndup (a1, n);
+}
+
+NOIPA char* strndup_a1_ui (unsigned n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a1_uli (unsigned long n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA char* strndup_a1_ulli (unsigned long long n)
+{
+ return strndup (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA size_t strnlen_a0_si (short n)
+{
+ return strnlen (a0, n);
+}
+
+NOIPA size_t strnlen_a0_i (int n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a0_li (long n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a0_lli (long long n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA size_t strnlen_a0_usi (unsigned short n)
+{
+ return strnlen (a0, n);
+}
+
+NOIPA size_t strnlen_a0_ui (unsigned n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a0_uli (unsigned long n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a0_ulli (unsigned long long n)
+{
+ return strnlen (a0, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+
+NOIPA size_t strnlen_a1_si (short n)
+{
+ return strnlen (a1, n);
+}
+
+NOIPA size_t strnlen_a1_i (int n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a1_li (long n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a1_lli (long long n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+
+NOIPA size_t strnlen_a1_usi (unsigned short n)
+{
+ return strnlen (a1, n);
+}
+
+NOIPA size_t strnlen_a1_ui (unsigned n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a1_uli (unsigned long n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
+
+NOIPA size_t strnlen_a1_ulli (unsigned long long n)
+{
+ return strnlen (a1, n); // { dg-bogus "\\\[-Wstringop-overread" }
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread-4.c b/gcc/testsuite/gcc.dg/Wstringop-overread-4.c
new file mode 100644
index 0000000..8248dad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread-4.c
@@ -0,0 +1,58 @@
+/* Verify -Wstringop-overread with a source pointer pointing either
+ before the beginning or past the end of an object.
+ { dg-do compile }
+ { dg-options "-O -Wall" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+size_t strlen (const char *);
+
+
+extern char a[1];
+
+volatile size_t n;
+
+void len_si_1_max (int i)
+{
+ if (i < 1) i = 1;
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n = strlen (a + i + 1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+}
+
+void len_ui_1_max (unsigned i)
+{
+ if (i < 1) i = 1;
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n = strlen (a + i + 1); // { dg-warning "reading 1 or more bytes from a region of size 0" "" { xfail ilp32 } }
+}
+
+void len_sl_1_max (long i)
+{
+ if (i < 1) i = 1;
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n = strlen (a + i + 1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+}
+
+void len_ul_1_max (unsigned long i)
+{
+ if (i < 1) i = 1;
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n = strlen (a + i + 1); // { dg-warning "reading 1 or more bytes from a region of size 0" "" { xfail *-*-* } }
+}
+
+
+void len_si_min_m1 (int i)
+{
+ if (i > -1) i = -1;
+ n = strlen (a + i - 1); // { dg-warning "reading 1 or more bytes from a region of size 0" "" { xfail lp64 } }
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" "" { xfail *-*-* } }
+ n = strlen (a + i + 2);
+}
+
+void len_sl_min_m1 (long i)
+{
+ if (i > -1) i = -1;
+ n = strlen (a + i - 1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n = strlen (a + i); // { dg-warning "reading 1 or more bytes from a region of size 0" "" { xfail *-*-* } }
+ n = strlen (a + i + 2);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread-5.c b/gcc/testsuite/gcc.dg/Wstringop-overread-5.c
new file mode 100644
index 0000000..b75002b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread-5.c
@@ -0,0 +1,76 @@
+/* Verify -Wstringop-overread with a source pointer pointing either
+ before the beginning or past the end of an object.
+ { dg-do compile }
+ { dg-options "-O -Wall -Wno-array-bounds" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+size_t strlen (const char *);
+
+void sink (void*, ...);
+
+void off_sz_or_1 (size_t i)
+{
+ i |= 1;
+
+ /* Verify the offset in the notes only mentions the meaningful lower
+ bound and not a range with the excessive (and meaningless) upper
+ bound like [2, 9223372036854775807]. */
+ extern char a[1];
+ // { dg-message "at offset 1 into source object 'a'" "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 2 " "note" { target *-*-* } .-2 }
+
+ char *p1 = a + i;
+ char *p2 = p1 + 1;
+ char *p3 = p1 - 1;
+
+ size_t n = 0;
+ n += strlen (p1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p2); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p3);
+
+ sink (p1, p2, p3, n);
+}
+
+
+void off_sz_or_2 (size_t i)
+{
+ i |= 2;
+
+ extern char b[2];
+ // { dg-message "at offset 2 " "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 3 " "note" { target *-*-* } .-2 }
+
+ char *p1 = b + i;
+ char *p2 = p1 + 1;
+ char *p3 = p1 - 1;
+
+ size_t n = 0;
+ n += strlen (p1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p2); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p3);
+
+ sink (p1, p2, p3, n);
+}
+
+
+void off_sz_or_4 (size_t i)
+{
+ i |= 4;
+
+ extern char c[3];
+ // { dg-message "at offset 4 " "note" { target *-*-* } .-1 }
+ // { dg-message "at offset 5 " "note" { target *-*-* } .-2 }
+ // { dg-message "at offset 3 " "note" { target *-*-* } .-3 }
+
+ char *p1 = c + i;
+ char *p2 = p1 + 1;
+ char *p3 = p1 - 1;
+
+ size_t n = 0;
+ n += strlen (p1); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p2); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+ n += strlen (p3); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+
+ sink (p1, p2, p3, n);
+}
diff --git a/gcc/testsuite/gcc.dg/Wstringop-overread.c b/gcc/testsuite/gcc.dg/Wstringop-overread.c
new file mode 100644
index 0000000..0343e43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wstringop-overread.c
@@ -0,0 +1,716 @@
+/* Verify -Wstringop-overread is issued appropriately.
+ { dg-do compile }
+ { dg-options "-O2 -ftrack-macro-expansion=0" } */
+
+typedef __SIZE_TYPE__ size_t;
+
+// <libint.h> functions.
+
+char* gettext (const char *);
+
+// <stdio.h> functions.
+
+int puts (const char*);
+int puts_unlocked (const char*);
+
+// <string.h> functions.
+
+char* strchr (const char*, int);
+
+int strcmp (const char*, const char*);
+int strncmp (const char*, const char*, size_t);
+
+char* strcat (char*, const char*);
+char* strcpy (char*, const char*);
+char* strncpy (char*, const char*, size_t);
+char* strdup (const char*);
+char* strndup (const char*, size_t);
+
+char* strpbrk (char*, const char*);
+size_t strcspn (const char*, const char*);
+size_t strspn (const char*, const char*);
+char* strstr (char*, const char*);
+
+size_t strlen (const char*);
+size_t strnlen (const char*, size_t);
+
+
+void sink (int, ...);
+#define sink(...) sink (0, __VA_ARGS__)
+
+extern char *d;
+extern char a0[0]; // { dg-message "source object 'a0'" }
+extern char a1[1]; // { dg-message "source object 'a1'" }
+extern char a2[2]; // { dg-message "source object 'a2'" }
+
+extern char b1[1];
+extern char b2[2];
+extern char bx[];
+
+const char s0[0] = { }; // { dg-message "source object 's0'" }
+const char s1[1] = ""; // { dg-message "source object 's1'" }
+const char s2[2] = "1"; // { dg-message "source object 's2'" }
+
+#define T(x) sink (0, (x))
+
+
+void test_strcat_array (const char *s, int i, int i0)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strcat (d, a0)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, a0 + i)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, a0 + i + 1)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+
+ T (strcat (d, a0 + i0)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+
+ T (strcat (d, a1));
+ T (strcat (d, a1 + 1)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, a1 + i));
+ T (strcat (d, a1 + i + 1));
+
+ T (strcat (d, a1 + i0));
+ T (strcat (d, a1 + i0 + 1)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+
+ T (strcat (d, a2));
+ T (strcat (d, a2 + 1));
+ T (strcat (d, a2 + 2)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, a2 + i));
+ T (strcat (d, a2 + i + 2));
+
+ T (strcat (d, a2 + i0));
+ T (strcat (d, a2 + i0 + 1));
+ T (strcat (d, a2 + i0 + 2)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+
+ // Repeat the above with the arguments reversed.
+
+ T (strcat (a0, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+ T (strcat (a0 + i, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+ T (strcat (a0 + i + 1, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+
+ T (strcat (a0 + i0, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+
+ T (strcat (a1, s));
+ T (strcat (a1 + 1, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+ T (strcat (a1 + i, s));
+ T (strcat (a1 + i + 1, s));
+
+ T (strcat (a1 + i0, s));
+ T (strcat (a1 + i0 + 1, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+
+ T (strcat (a2, s));
+ T (strcat (a2 + 1, s));
+ T (strcat (a2 + 2, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+ T (strcat (a2 + i, s));
+ T (strcat (a2 + i + 2, s));
+
+ T (strcat (a2 + i0, s));
+ T (strcat (a2 + i0 + 1, s));
+ T (strcat (a2 + i0 + 2, s)); // { dg-warning "'strcat' writing 1 or more bytes into a region of size 0" }
+}
+
+void test_strcat_literal (int i)
+{
+ T (strcat (d, ""));
+ T (strcat (d, "" + 0));
+ T (strcat (d, "" + i));
+
+ T (strcat (d, "1"));
+ T (strcat (d, "1" + 1));
+ T (strcat (d, "1" + 2)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, "1" + i));
+
+ T (strcat (d, "12"));
+ T (strcat (d, "12" + 1));
+ T (strcat (d, "12" + 2));
+ T (strcat (d, "12" + 3)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, "12" + i));
+}
+
+void test_strcat_string (int i)
+{
+ T (strcat (d, s0)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s0 + 1)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s0 + i)); // { dg-warning "'strcat' (reading 1 or more bytes from a region of size 0|argument missing terminating nul)" }
+
+ T (strcat (d, s1));
+ T (strcat (d, s1 + 1)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s1 + 2)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s1 + i));
+
+ T (strcat (d, s2));
+ T (strcat (d, s2 + 1));
+ T (strcat (d, s2 + 2)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s2 + 3)); // { dg-warning "'strcat' reading 1 or more bytes from a region of size 0" }
+ T (strcat (d, s2 + i));
+}
+
+
+void test_strcpy_array (int i, int i0)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strcpy (d, a0)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, a0 + i)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, a0 + i + 1)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+
+ T (strcpy (d, a0 + i0)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+
+ T (strcpy (d, a1));
+ T (strcpy (d, a1 + 1)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, a1 + i));
+ T (strcpy (d, a1 + i + 1));
+
+ T (strcpy (d, a1 + i0));
+ T (strcpy (d, a1 + i0 + 1)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+
+ T (strcpy (d, a2));
+ T (strcpy (d, a2 + 1));
+ T (strcpy (d, a2 + 2)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, a2 + i));
+ T (strcpy (d, a2 + i + 2));
+
+ T (strcpy (d, a2 + i0));
+ T (strcpy (d, a2 + i0 + 1));
+ T (strcpy (d, a2 + i0 + 2)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+}
+
+void test_strcpy_literal (int i)
+{
+ T (strcpy (d, ""));
+ T (strcpy (d, "" + 0));
+ T (strcpy (d, "" + i));
+
+ T (strcpy (d, "1"));
+ T (strcpy (d, "1" + 1));
+ T (strcpy (d, "1" + 2)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, "1" + i));
+
+ T (strcpy (d, "12"));
+ T (strcpy (d, "12" + 1));
+ T (strcpy (d, "12" + 2));
+ T (strcpy (d, "12" + 3)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, "12" + i));
+}
+
+void test_strcpy_string (int i)
+{
+ T (strcpy (d, s0)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s0 + 1)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s0 + i)); // { dg-warning "'strcpy' (reading 1 or more bytes from a region of size 0|argument missing terminating nul)" }
+
+ T (strcpy (d, s1));
+ T (strcpy (d, s1 + 1)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s1 + 2)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s1 + i));
+
+ T (strcpy (d, s2));
+ T (strcpy (d, s2 + 1));
+ T (strcpy (d, s2 + 2)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s2 + 3)); // { dg-warning "'strcpy' reading 1 or more bytes from a region of size 0" }
+ T (strcpy (d, s2 + i));
+}
+
+
+void test_strncpy_array (int i)
+{
+ T (strncpy (d, a0, 0));
+ T (strncpy (d, a0, 1)); // { dg-warning "'strncpy' reading 1 byte from a region of size 0" }
+ T (strncpy (d, a0 + i, 0));
+ T (strncpy (d, a0 + i, 1)); // { dg-warning "'strncpy' reading 1 byte from a region of size 0" }
+
+ T (strncpy (d, a1, 0));
+ T (strncpy (d, a1, 1));
+ T (strncpy (d, a1 + 1, 0));
+ T (strncpy (d, a1 + 1, 1)); // { dg-warning "'strncpy' reading 1 byte from a region of size 0" }
+ T (strncpy (d, a1 + i, 0));
+ T (strncpy (d, a1 + i, 1));
+ T (strncpy (d, a1 + i, 2));
+}
+
+
+void test_strncpy_literal (int i, int i0)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strncpy (d, "", 0));
+ T (strncpy (d, "", 1));
+ T (strncpy (d, "", 2));
+
+ T (strncpy (d, "" + i, 0));
+ T (strncpy (d, "" + i, 1));
+ T (strncpy (d, "" + i0, 1));
+ T (strncpy (d, "" + i0, 1));
+
+ T (strncpy (d, "" + 1, 0));
+ T (strncpy (d, "" + 1, 1)); // { dg-warning "'strncpy' reading 1 byte from a region of size 0" }
+
+ T (strncpy (d, "1", 0));
+ T (strncpy (d, "1" + 1, 0));
+ T (strncpy (d, "1" + 1, 1));
+ T (strncpy (d, "1" + 1, 2));
+ T (strncpy (d, "1" + i, 2));
+
+ T (strncpy (d, "1" + 2, 0));
+ T (strncpy (d, "1" + 2, 1)); // { dg-warning "'strncpy' reading 1 byte from a region of size 0" }
+}
+
+
+void test_strlen_array (int i, int i0)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strlen (a0)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+ T (strlen (a0 + i)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+ T (strlen (a0 + i + 1)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+
+ T (strlen (a0 + i0)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+
+ T (strlen (a1));
+ T (strlen (a1 + 1)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+ T (strlen (a1 + i));
+ T (strlen (a1 + i + 1));
+
+ T (strlen (a1 + i0));
+ T (strlen (a1 + i0 + 1)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+
+ T (strlen (a2));
+ T (strlen (a2 + 1));
+ T (strlen (a2 + 2)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+ T (strlen (a2 + i));
+ T (strlen (a2 + i + 2));
+
+ T (strlen (a2 + i0));
+ T (strlen (a2 + i0 + 1));
+ T (strlen (a2 + i0 + 2)); // { dg-warning "'strlen' reading 1 or more bytes from a region of size 0" }
+}
+
+
+void test_strnlen_array (int i, int i0, unsigned n)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strnlen (a0, 0));
+ T (strnlen (a0, 1)); // { dg-warning "'strnlen' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strnlen (a0, i0));
+ T (strnlen (a0, i0 + 1)); // { dg-warning "'strnlen' (reading between 1 and \[0-9\]+ bytes from a region of size 0|specified bound \\\[1, \[0-9\]+\\\] exceeds source size 0)" }
+ T (strnlen (a0, n));
+ T (strnlen (a0 + i, 0));
+ T (strnlen (a0 + i, 1)); // { dg-warning "'strnlen' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strnlen (a0 + i, i0));
+ T (strnlen (a0 + i, n));
+ T (strnlen (a0 + i + 1, 0));
+ T (strnlen (a0 + i + 1, 1)); // { dg-warning "'strnlen' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+
+ T (strnlen (a0 + i0, 0));
+ T (strnlen (a0 + i0, 1)); // { dg-warning "'strnlen' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strnlen (a0 + i0, n));
+
+ T (strnlen (a1, 0));
+ T (strnlen (a1, 1));
+ T (strnlen (a1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" { xfail *-*-* } }
+ T (strnlen (a1, n));
+
+ T (strnlen (a1 + 1, 0));
+ T (strnlen (a1 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + 1, i0));
+ T (strnlen (a1 + 1, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a1 + 1, n));
+ T (strnlen (a1 + i, 0));
+ T (strnlen (a1 + i, 1));
+ T (strnlen (a1 + i, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
+ T (strnlen (a1 + i, n));
+ T (strnlen (a1 + i + 1, 0));
+ T (strnlen (a1 + i + 1, 1));
+ T (strnlen (a1 + i + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
+ T (strnlen (a1 + i + 1, n));
+
+ T (strnlen (a1 + i0, 0));
+ T (strnlen (a1 + i0, 1));
+ T (strnlen (a1 + i0, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" }
+ T (strnlen (a1 + i0, n));
+ T (strnlen (a1 + i0 + 1, 0));
+ T (strnlen (a1 + i0 + 1, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a1 + i0 + 1, n));
+
+ T (strnlen (a2, 0));
+ T (strnlen (a2, 1));
+ T (strnlen (a2, 2));
+ T (strnlen (a2, n));
+ T (strnlen (a2 + 1, 0));
+ T (strnlen (a2 + 1, 1));
+ T (strnlen (a2 + 1, 2)); // { dg-warning "'strnlen' specified bound 2 exceeds source size 1" "pr87492" { xfail *-*-* } }
+ T (strnlen (a2 + 1, n));
+ T (strnlen (a2 + 2, 0));
+ T (strnlen (a2 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + 2, n));
+ T (strnlen (a2 + i, 0));
+ T (strnlen (a2 + i, 1));
+ T (strnlen (a2 + i, 2));
+ T (strnlen (a2 + i + 2, 0));
+ T (strnlen (a2 + i + 2, 1));
+ T (strnlen (a2 + i + 2, 2));
+ T (strnlen (a2 + i + 2, n));
+
+ T (strnlen (a2 + i0, 0));
+ T (strnlen (a2 + i0, 1));
+ T (strnlen (a2 + i0, 2));
+ T (strnlen (a2 + i0, 3)); // { dg-warning "'strnlen' specified bound 3 exceeds source size 2" }
+ T (strnlen (a2 + i0, n));
+
+ T (strnlen (a2 + i0 + 1, 0));
+ T (strnlen (a2 + i0 + 1, 1));
+ T (strnlen (a2 + i0 + 1, 2));
+ T (strnlen (a2 + i0 + 1, n));
+
+ T (strnlen (a2 + i0 + 2, 0));
+ T (strnlen (a2 + i0 + 2, 1)); // { dg-warning "'strnlen' reading 1 byte from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, i0));
+ T (strnlen (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strnlen' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strnlen (a2 + i0 + 2, n));
+}
+
+
+void test_strcmp_array (const char *s, int i)
+{
+ T (strcmp (a0, "")); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-* } }
+
+ T (strcmp (a0, s)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+ T (strcmp (a0 + i, s)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+
+ T (strcmp (a1, s));
+ T (strcmp (a1 + 1, s)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+ T (strcmp (a1 + i, s));
+ T (strcmp (a1 + i + 1, s));
+
+
+ // Repeat the above with the arguments reversed.
+
+ T (strcmp ("", a0)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-*} }
+
+ T (strcmp (s, a0)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+ T (strcmp (s, a0 + i)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+
+ T (strcmp (s, a1));
+ T (strcmp (s, a1 + 1)); // { dg-warning "'strcmp' reading 1 or more bytes from a region of size 0" }
+ T (strcmp (s, a1 + i));
+ T (strcmp (s, a1 + i + 1));
+}
+
+/* The number of characters read is considered to be bounded not just
+ by the third argument to strncmp but also by the length of the shorter
+ of the two strings. When the string length is unknowm, verify that
+ a warning is only issued for certain reading past the end but not
+ otherwise. */
+
+void test_strncmp_array (const char *s, int i)
+{
+ T (strncmp (a0, a0, 0));
+
+ T (strncmp (a0, s, 0));
+ T (strncmp (a0, s, 1)); // { dg-warning "'strncmp' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-* } }
+
+ T (strncmp (a0, s, 2)); // { dg-warning "'strncmp' (reading between 1 and 2 bytes from a region of size 0|specified bound 2 exceeds source size 0)" }
+ T (strncmp (a1, s, 0));
+ T (strncmp (a1, s, 1));
+ T (strncmp (a1 + 1, s, 1)); // { dg-warning "'strncmp' reading 1 byte from a region of size 0" "pr?????" { xfail *-*-*} }
+ T (strncmp (a1, s, 1));
+ T (strncmp (a1 + 1, s, 2)); // { dg-warning "'strncmp' (reading between 1 and 2 bytes from a region of size 0|specified bound 2 exceeds source size 0)" }
+
+ T (strncmp (a2, s, 1));
+ T (strncmp (a2, s, 2));
+ T (strncmp (a2, s, 3));
+
+ T (strncmp (a2 + 1, s, 1));
+ T (strncmp (a2 + 2, s, 2)); // { dg-warning "'strncmp' (reading between 1 and 2 bytes from a region of size 0|specified bound 2 exceeds source size 0)" }
+
+ T (strncmp (a1, b1, 0));
+ T (strncmp (a1, b1, 1));
+ T (strncmp (a1, b1, 2)); // { dg-warning "'strncmp' specified bound 2 exceeds source size 1" }
+}
+
+
+void test_strncmp_literal (const char *s, int i)
+{
+ T (strncmp (a0, "", 0));
+ T (strncmp (a0, "1", 0));
+ T (strncmp (a0, "12", 0));
+
+ /* The calls with a bound in excess of the length of the literal are
+ folded early (most into strcmp) so the warning doesn't trigger. */
+ T (strncmp (s, "", 0));
+
+ T (strncmp (s, "1", 0));
+ T (strncmp (s, "1", 1));
+ T (strncmp (s, "1", 2)); // { dg-warning "\\\[-Wstringop-overread" "pr93665" { xfail *-*-* } }
+
+ T (strncmp (s, "12", 0));
+ T (strncmp (s, "12", 1));
+ T (strncmp (s, "12", 2));
+ T (strncmp (s, "12", 3)); // { dg-warning "\\\[-Wstringop-overread" "pr93665" { xfail *-*-* } }
+
+ T (strncmp (s, "123", 0));
+ T (strncmp (s, "123", 1));
+ T (strncmp (s, "123", 2));
+ T (strncmp (s, "123", 3));
+ T (strncmp (s, "123", 4)); // { dg-warning "\\\[-Wstringop-overread" "pr93665" { xfail *-*-* } }
+}
+
+
+void test_strchr_array (int x, int i)
+{
+ T (strchr (a0, x)); // { dg-warning "'strchr' reading 1 or more bytes from a region of size 0" }
+ T (strchr (a0 + i, x)); // { dg-warning "'strchr' reading 1 or more bytes from a region of size 0" }
+
+ T (strchr (a1, x));
+ T (strchr (a1 + 1, x)); // { dg-warning "'strchr' reading 1 or more bytes from a region of size 0" }
+ T (strchr (a1 + i, x));
+ T (strchr (a1 + i + 1, x));
+}
+
+
+void test_strdup_array (int i)
+{
+ T (strdup (a0)); // { dg-warning "'strdup' reading 1 or more bytes from a region of size 0" }
+ T (strdup (a0 + i)); // { dg-warning "'strdup' reading 1 or more bytes from a region of size 0" }
+
+ T (strdup (a1));
+ T (strdup (a1 + 1)); // { dg-warning "'strdup' reading 1 or more bytes from a region of size 0" }
+ T (strdup (a1 + i));
+ T (strdup (a1 + i + 1));
+}
+
+
+void test_strndup_array (int i, int i0, unsigned n)
+{
+ if (i0 < 0)
+ i0 = 0;
+
+ T (strndup (a0, 0));
+ T (strndup (a0, 1)); // { dg-warning "'strndup' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strndup (a0, i0));
+ T (strndup (a0, i0 + 1)); // { dg-warning "'strndup' (reading between 1 and \[0-9\]+ bytes from a region of size 0|specified bound \\\[1, \[0-9\]+\\\] exceeds source size 0)" }
+ T (strndup (a0, n));
+ T (strndup (a0 + i, 0));
+ T (strndup (a0 + i, 1)); // { dg-warning "'strndup' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strndup (a0 + i, i0));
+ T (strndup (a0 + i, n));
+ T (strndup (a0 + i + 1, 0));
+ T (strndup (a0 + i + 1, 1)); // { dg-warning "'strndup' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+
+ T (strndup (a0 + i0, 0));
+ T (strndup (a0 + i0, 1)); // { dg-warning "'strndup' (reading 1 byte from a region of size 0|specified bound 1 exceeds source size 0)" }
+ T (strndup (a0 + i0, n));
+
+ T (strndup (a1, 0));
+ T (strndup (a1, 1));
+ T (strndup (a1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
+ T (strndup (a1, n));
+ T (strndup (a1 + 1, 0));
+ T (strndup (a1 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + 1, i0));
+ T (strndup (a1 + 1, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a1 + 1, n));
+ T (strndup (a1 + i, 0));
+ T (strndup (a1 + i, 1));
+ T (strndup (a1 + i, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
+ T (strndup (a1 + i, n));
+ T (strndup (a1 + i + 1, 0));
+ T (strndup (a1 + i + 1, 1));
+ T (strndup (a1 + i + 1, 2)); // { dg-warning "'strndup' specified bound 2 exceeds source size 1" }
+ T (strndup (a1 + i + 1, n));
+
+ T (strndup (a1 + i0, 0));
+ T (strndup (a1 + i0, 1));
+ T (strndup (a1 + i0, n));
+ T (strndup (a1 + i0 + 1, 0));
+ T (strndup (a1 + i0 + 1, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a1 + i0 + 1, n));
+
+ T (strndup (a2, 0));
+ T (strndup (a2, 1));
+ T (strndup (a2, 2));
+ T (strndup (a2, n));
+ T (strndup (a2 + 1, 0));
+ T (strndup (a2 + 1, 1));
+ T (strndup (a2 + 1, 2));
+ T (strndup (a2 + 1, n));
+ T (strndup (a2 + 2, 0));
+ T (strndup (a2 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + 2, n));
+ T (strndup (a2 + i, 0));
+ T (strndup (a2 + i, 1));
+ T (strndup (a2 + i, 2));
+ T (strndup (a2 + i + 2, 0));
+ T (strndup (a2 + i + 2, 1));
+ T (strndup (a2 + i + 2, 2));
+ T (strndup (a2 + i + 2, n));
+
+ T (strndup (a2 + i0, 0));
+ T (strndup (a2 + i0, 1));
+ T (strndup (a2 + i0, 2));
+ T (strndup (a2 + i0, 3)); // { dg-warning "'strndup' specified bound 3 exceeds source size 2" }
+ T (strndup (a2 + i0, n));
+
+ T (strndup (a2 + i0 + 1, 0));
+ T (strndup (a2 + i0 + 1, 1));
+ T (strndup (a2 + i0 + 1, 2));
+ T (strndup (a2 + i0 + 1, n));
+
+ T (strndup (a2 + i0 + 2, 0));
+ T (strndup (a2 + i0 + 2, 1)); // { dg-warning "'strndup' reading 1 byte from a region of size 0" }
+ T (strndup (a2 + i0 + 2, i0));
+ T (strndup (a2 + i0 + 2, i0 + 1)); // { dg-warning "'strndup' reading between 1 and \[0-9\]+ bytes from a region of size 0" }
+ T (strndup (a2 + i0 + 2, n));
+}
+
+
+void test_strpbrk_array (char *s, int i)
+{
+ T (strpbrk (a0, "")); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-* } }
+
+ T (strpbrk (a0, s)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+ T (strpbrk (a0 + i, s)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+
+ T (strpbrk (a1, s));
+ T (strpbrk (a1 + 1, s)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+ T (strpbrk (a1 + i, s));
+ T (strpbrk (a1 + i + 1, s));
+
+
+ // Repeat the above with the arguments reversed.
+
+ T (strpbrk ("", a0)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+
+ T (strpbrk (s, a0)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+ T (strpbrk (s, a0 + i)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+
+ T (strpbrk (s, a1));
+ T (strpbrk (s, a1 + 1)); // { dg-warning "'strpbrk' reading 1 or more bytes from a region of size 0" }
+ T (strpbrk (s, a1 + i));
+ T (strpbrk (s, a1 + i + 1));
+}
+
+
+void test_strspn_array (const char *s, int i)
+{
+ T (strspn (a0, "")); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-* } }
+
+ T (strspn (a0, s)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+ T (strspn (a0 + i, s)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+
+ T (strspn (a1, s));
+ T (strspn (a1 + 1, s)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+ T (strspn (a1 + i, s));
+ T (strspn (a1 + i + 1, s));
+
+
+ // Repeat the above with the arguments reversed.
+
+ T (strspn ("", a0)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-*} }
+
+ T (strspn (s, a0)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+ T (strspn (s, a0 + i)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+
+ T (strspn (s, a1));
+ T (strspn (s, a1 + 1)); // { dg-warning "'strspn' reading 1 or more bytes from a region of size 0" }
+ T (strspn (s, a1 + i));
+ T (strspn (s, a1 + i + 1));
+}
+
+
+void test_strcspn_array (const char *s, int i)
+{
+ /* The call below is tranformed to strlen() so the warning references
+ the latter function instead of strcspn. Avoid testing that aspect. */
+ T (strcspn (a0, "")); // { dg-warning "reading 1 or more bytes from a region of size 0" }
+
+ T (strcspn (a0, s)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+ T (strcspn (a0 + i, s)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+
+ T (strcspn (a1, s));
+ T (strcspn (a1 + 1, s)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+ T (strcspn (a1 + i, s));
+ T (strcspn (a1 + i + 1, s));
+
+
+ // Repeat the above with the arguments reversed.
+
+ T (strcspn ("", a0)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-*} }
+
+ T (strcspn (s, a0)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+ T (strcspn (s, a0 + i)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+
+ T (strcspn (s, a1));
+ T (strcspn (s, a1 + 1)); // { dg-warning "'strcspn' reading 1 or more bytes from a region of size 0" }
+ T (strcspn (s, a1 + i));
+ T (strcspn (s, a1 + i + 1));
+}
+
+
+void test_strstr_array (char *s, int i)
+{
+ T (strstr (a0, "")); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" "pr?????" { xfail *-*-* } }
+
+ T (strstr (a0, s)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+ T (strstr (a0 + i, s)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+
+ T (strstr (a1, s));
+ T (strstr (a1 + 1, s)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+ T (strstr (a1 + i, s));
+ T (strstr (a1 + i + 1, s));
+
+
+ // Repeat the above with the arguments reversed.
+
+ T (strstr ("", a0)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+
+ T (strstr (s, a0)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+ T (strstr (s, a0 + i)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+
+ T (strstr (s, a1));
+ T (strstr (s, a1 + 1)); // { dg-warning "'strstr' reading 1 or more bytes from a region of size 0" }
+ T (strstr (s, a1 + i));
+ T (strstr (s, a1 + i + 1));
+}
+
+
+void test_puts_array (int i)
+{
+ T (puts (a0)); // { dg-warning "'puts' reading 1 or more bytes from a region of size 0" }
+ T (puts (a0 + i)); // { dg-warning "'puts' reading 1 or more bytes from a region of size 0" }
+
+ T (puts (a1));
+ T (puts (a1 + 1)); // { dg-warning "'puts' reading 1 or more bytes from a region of size 0" }
+ T (puts (a1 + i));
+ T (puts (a1 + i + 1));
+}
+
+
+void test_puts_unlocked_array (int i)
+{
+ T (puts_unlocked (a0)); // { dg-warning "'puts_unlocked' reading 1 or more bytes from a region of size 0" }
+ T (puts_unlocked (a0 + i)); // { dg-warning "'puts_unlocked' reading 1 or more bytes from a region of size 0" }
+
+ T (puts_unlocked (a1));
+ T (puts_unlocked (a1 + 1)); // { dg-warning "'puts_unlocked' reading 1 or more bytes from a region of size 0" }
+ T (puts_unlocked (a1 + i));
+ T (puts_unlocked (a1 + i + 1));
+}
+
+
+void test_gettext_array (int i)
+{
+ T (gettext (a0)); // { dg-warning "'gettext' reading 1 or more bytes from a region of size 0" }
+ T (gettext (a0 + i)); // { dg-warning "'gettext' reading 1 or more bytes from a region of size 0" }
+
+ T (gettext (a1));
+ T (gettext (a1 + 1)); // { dg-warning "'gettext' reading 1 or more bytes from a region of size 0" }
+ T (gettext (a1 + i));
+ T (gettext (a1 + i + 1));
+}
diff --git a/gcc/testsuite/gcc.dg/Wunused-var-4.c b/gcc/testsuite/gcc.dg/Wunused-var-4.c
new file mode 100644
index 0000000..08ddcf4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wunused-var-4.c
@@ -0,0 +1,33 @@
+/* PR c/96571 */
+/* { dg-do compile } */
+/* { dg-options "-std=c99 -O2 -Wunused-but-set-variable" } */
+
+enum E { V };
+
+int
+foo (void)
+{
+ enum E v; /* { dg-bogus "set but not used" } */
+ return _Generic (v, enum E : 0);
+}
+
+int
+bar (void)
+{
+ int a = 0; /* { dg-bogus "set but not used" } */
+ return _Generic (0, int : a);
+}
+
+int
+baz (void)
+{
+ int a; /* { dg-bogus "set but not used" } */
+ return _Generic (0, long long : a, int : 0);
+}
+
+int
+qux (void)
+{
+ int a; /* { dg-bogus "set but not used" } */
+ return _Generic (0, long long : a, default: 0);
+}
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-2.c b/gcc/testsuite/gcc.dg/Wvla-parameter-2.c
new file mode 100644
index 0000000..ba93241
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-2.c
@@ -0,0 +1,75 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify the -Wvla-parameter warnings correctly diagnose mismatches
+ between multimensional array arguments with one or more variable
+ bounds in redeclarations of the same function.
+ { dg-do compile }
+ { dg-options "-Wall -Wvla-parameter" } */
+
+void fmn_a1n_axn (int n, int[1][n]); // { dg-message "previously declared as 'int\\\[1]\\\[n]' with 1 variable bound" "note" }
+void fmn_a1n_axn (int n, int[*][n]); // { dg-warning "argument 2 of type 'int\\\[\\\*]\\\[n]' declared with 2 variable bounds" }
+
+
+void fmn_axn_a2n (int n, int[*][n]); // { dg-message "previously declared as 'int\\\[\\\*]\\\[n]' with 2 variable bounds" "note" }
+void fmn_axn_a2n (int n, int[2][n]); // { dg-warning "argument 2 of type 'int\\\[2]\\\[n]' declared with 1 variable bound" }
+
+
+void fmn_amn_axn (int m, int n, int[m][n]); // { dg-message "previously declared as 'int\\\[m]\\\[n]' with 0 unspecified variable bounds" "note" }
+void fmn_amn_axn (int m, int n, int[*][n]); // { dg-warning "argument 3 of type 'int\\\[\\\*]\\\[n]' declared with 1 unspecified variable bound" }
+
+// Same as above but a different function name.
+void gmn_amn_axn (int m, int n, int[m][n]); // { dg-message "previously declared as 'int\\\[m]\\\[n]' with 0 unspecified variable bounds" "note" }
+void gmn_amn_axn (int m, int n, int[*][n]); // { dg-warning "argument 3 of type 'int\\\[\\\*]\\\[n]' declared with 1 unspecified variable bound" }
+
+typedef int A7[7];
+
+void fm_A7_m_5 (int m, A7[m][5]); // { dg-message "previously declared as 'int\\\[m]\\\[5]\\\[7]' with bound argument 1" "note" }
+void fm_A7_m_5 (int n, A7[n][5]);
+
+void fm_A7_m_5 (int n, A7[n + 1][5]); // { dg-warning "argument 2 of type 'int\\\[n \\\+ 1]\\\[5]\\\[7]' declared with mismatched bound 'n \\\+ 1'" }
+
+
+int n1, n2, n3, n4, n5, n6, n7, n8, n9;
+void f (int[n1][2][n3][4][n5][6][n7][8][n9]); // { dg-message "previously declared as 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' with 0 unspecified variable bounds" "note" }
+ // { dg-message "with 5 variable bounds" "note" { target *-*-* } .-1 }
+void f (int[n1][2][n3][4][n5][6][n7][8][n9]);
+
+/* Due to a limitation and because [*] is represented the same as [0]
+ only the most significant array bound is rendered as [*]; the others
+ are rendered as [0]. */
+void f (int[n1][2][n3][4][n5][6][n7][8][*]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[\\\*]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } }
+// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[0]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 }
+void f (int[n1][2][n3][4][n5][6][*][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[\\\*]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } }
+// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[0]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 }
+void f (int[n1][2][n3][4][*][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[\\\*]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-*} }
+// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[n3]\\\[4]\\\[0]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 }
+void f (int[n1][2][*][4][n5][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[\\\*]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { xfail *-*-* } }
+// { dg-warning "argument 1 of type 'int\\\[n1]\\\[2]\\\[0]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" "pr?????" { target *-*-* } .-1 }
+void f (int[*][2][n3][4][n5][6][n7][8][n9]); // { dg-warning "argument 1 of type 'int\\\[\\\*]\\\[2]\\\[n3]\\\[4]\\\[n5]\\\[6]\\\[n7]\\\[8]\\\[n9]' declared with 1 unspecified variable bound" }
+
+void f (int[n1][n2][n3][n4][n5][n6][n7][n8][n9]); // { dg-warning "argument 1 of type 'int\\\[n1]\\\[n2]\\\[n3]\\\[n4]\\\[n5]\\\[n6]\\\[n7]\\\[n8]\\\[n9]' declared with 9 variable bounds" }
+
+// Verify that arrays of pointers to arrays...etc are handled correctly.
+void a2pampan (int (*(*(*[2])[n1])[n2]));
+// { dg-message "previously declared as 'int \\\* \\\(\\\* \\\(\\\*\\\[2]\\\)\\\[n1]\\\)\\\[n2]'" "note" { target *-*-* } .-1 }
+void a2pampan (int (*(*(*[2])[n1])[1]));
+// { dg-warning "argument 1 of type 'int \\\* \\\(\\\* \\\(\\\*\\\[2]\\\)\\\[n1]\\\)\\\[1]' declared with 1 variable bound" "" { target *-*-* } .-1 }
+void a2pampan (int (*(*(*[2])[1])[n2]));
+// { dg-warning "argument 1 of type 'int \\\* \\\(\\\* \\\(\\\*\\\[2]\\\)\\\[1]\\\)\\\[n2]' declared with 1 variable bound" "" { target *-*-* } .-1 }
+void a2pampan (int (*(*(*[2])[n1])[n1]));
+// { dg-warning "argument 1 of type 'int \\\* \\\(\\\* \\\(\\\*\\\[2]\\\)\\\[n1]\\\)\\\[n1]' declared with mismatched bound 'n1'" "" { target *-*-* } .-1 }
+void a2pampan (int (*(*(*[2])[n1])[n2]));
+
+
+/* Verify that the presence or absence of static with VLA dooesn't cause
+ unwanted warnings. */
+
+int f2ia1_1 (int n, int [n][n]); // { sg-message "previously declared as 'int\\\[n]\\\[n]' with bound argument 1" }
+int f2ia1_1 (int n, int[static n][n]);
+int f2ia1_1 (int n, int a[static n][n]) { return sizeof *a; }
+int f2ia1_1 (int n, int[static n + 1][n]); // { dg-warning "argument 2 of type 'int\\\[n \\\+ 1]\\\[n]' declared with mismatched bound 'n \\\+ 1'" }
+
+int f2ias1_1 (int n, int [static n][n]); // { dg-message "previously declared as 'int\\\[n]\\\[n]' with bound argument 1" }
+int f2ias1_1 (int n, int[n][n]);
+int f2ias1_1 (int n, int a[++n][n]) // { dg-warning "argument 2 of type 'int\\\[\\\+\\\+n]\\\[n]' declared with mismatched bound ' ?\\+\\+n'" }
+{ return sizeof *a; }
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-3.c b/gcc/testsuite/gcc.dg/Wvla-parameter-3.c
new file mode 100644
index 0000000..51f0172
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-3.c
@@ -0,0 +1,68 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify that redeclarations of functions with pointer parameters to
+ arrays with variable bounds are diagnosed if the bounds don't match
+ either in kind or in the variable expression.
+ { dg-do compile }
+ { dg-options "-Wall -Wvla-parameter" } */
+
+extern int m, n;
+
+void pa_ (int (*)[]); // { dg-message "previously declared as 'int \\\(\\\*\\\)\\\[]'" "note" }
+void pa_ (int (*)[n]); // { dg-warning "\\\[-Wvla-parameter" }
+void pa_ (int (*)[n + 1]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int *\\\(\\\*\\\)\\\[n \\\+ 1\\\]'" }
+
+void ppa_ (int (**)[]); // { dg-message "previously declared as 'int \\\(\\\*\\\*\\\)\\\[]'" "note" }
+void ppa_ (int (**)[n]); // { dg-warning "\\\[-Wvla-parameter" }
+void ppa_ (int (**)[n + 1]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\*\\\)\\\[n \\\+ 1\\\]'" }
+
+void pa1 (int (*)[1]); // { dg-message "previously declared as 'int \\\(\\\*\\\)\\\[1]'" "note" }
+void pa1 (int (*)[n]); // { dg-warning "\\\[-Wvla-parameter" }
+void pa1 (int (*)[1]);
+void pa1 (int (*)[n + 1]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int *\\\(\\\*\\\)\\\[n \\\+ 1\\\]'" }
+
+void ppax (int (**)[*]); // { dg-message "previously declared as 'int \\\(\\\*\\\*\\\)\\\[.]'" "note" }
+void ppax (int (**)[n]); // { dg-warning "\\\[-Wvla-parameter" }
+/* A VLA with an unspecified bound is represented the same as [0] so
+ so the pretty printer can't differentiate between the two forms. */
+void ppax (int (**)[1]); // { dg-bogus "\\\[-Warray-parameter" "pr?????" { xfail *-*-* } }
+ // { dg-warning "\\\[-Wvla-parameter" "pr?????" { xfail *-*-* } .-1 }
+void ppax (int (**)[n + 1]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int *\\\(\\\*\\\*\\\)\\\[n \\\+ 1\\\]'" }
+
+
+void pa1_n (int (*)[1][n]);
+void pa1_n (int (*)[1][n]);
+void pa1_n (int (*)[*][n]); // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[\\\*]\\\[n]'" "pr?????" { xfail *-*-*} }
+ // { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[0]\\\[n]'" "pr?????" { target *-*-* } .-1 }
+
+void pa1_n_2 (int (*)[1][n][2]);
+void pa1_n_2 (int (*)[1][n][*]); // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[\\\*]'" "pr?????" { xfail *-*-* } }
+ // { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[0]'" "pr?????" { target *-*-* } .-1 }
+
+
+void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[1][n][2]);
+// { dg-message "previously declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[2]'" "note" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[1][n][n]);
+// { dg-warning "mismatch in bound 3 of argument 2 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[n]'" "" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[1][3][2]);
+// { dg-warning "mismatch in bound 2 of argument 2 declared as 'int \\\(\\\*\\\)\\\[1]\\\[3]\\\[2]'" "" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[n][n][2]);
+// { dg-warning "mismatch in bound 1 of argument 2 declared as 'int \\\(\\\*\\\)\\\[n]\\\[n]\\\[2]'" "" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[1][n][n], int (*)[1][n][2]);
+// { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[1]\\\[n]\\\[n]'" "" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[n][n][2], int (*)[1][n][2]);
+// { dg-warning "mismatch in bound 1 of argument 1 declared as 'int \\\(\\\*\\\)\\\[n]\\\[n]\\\[2]'" "" { target *-*-* } .-1 }
+void pa1_n_2_a1_n_2 (int (*)[*][*][*], int (*)[*][*][2]);
+// { dg-warning "mismatch in bounds 1, 2, 3 of argument 1 declared as 'int \\\(\\\*\\\)\\\[.]\\\[.]\\\[.]'" "" { target *-*-* } .-1 }
+// { dg-warning "mismatch in bounds 1, 2 of argument 2 declared as 'int \\\(\\\*\\\)\\\[.]\\\[.]\\\[2]'" "" { target *-*-* } .-2 }
+void pa1_n_2_a1_n_2 (int (*)[1][n][2], int (*)[1][n][2]);
+
+/* Verify that pointers to arrays of pointers to arrays...etc are handled
+ correctly. */
+void pa2pampan (int (*(*(*(*)[2])[m])[n]));
+// { dg-message "previously declared as 'int \\\* \\\(\\\* \\\(\\\* \\\(\\\*\\\)\\\[2]\\\)\\\[m]\\\)\\\[n]'" "note" { target *-*-* } .-1 }
+void pa2pampan (int (*(*(*(*)[2])[m])[1]));
+// { dg-warning "mismatch in bound 3 of argument 1 declared as 'int \\\* \\\(\\\* \\\(\\\* \\\(\\\*\\\)\\\[2]\\\)\\\[m]\\\)\\\[1]'" "" { target *-*-* } .-1 }
+void pa2pampan (int (*(*(*(*)[2])[1])[n]));
+// { dg-warning "mismatch in bound 2 of argument 1 declared as 'int \\\* \\\(\\\* \\\(\\\* \\\(\\\*\\\)\\\[2]\\\)\\\[1]\\\)\\\[n]'" "" { target *-*-* } .-1 }
+void pa2pampan (int (*(*(*(*)[2])[m])[n]));
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-4.c b/gcc/testsuite/gcc.dg/Wvla-parameter-4.c
new file mode 100644
index 0000000..599ad19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-4.c
@@ -0,0 +1,99 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify warnings for redeclarations of functions with pointer parameters
+ to arrays with variable bounds involving typedefs.
+ { dg-do compile }
+ { dg-options "-Wall -Wvla-parameter" } */
+
+extern int m, n;
+
+typedef int IA3[3];
+
+/* Verify the warning points to the declaration with more unspecified
+ bounds, guiding the user to specify them rather than making them all
+ unspecified. */
+void* f_pIA3ax (IA3 *x[*]); // { dg-warning "argument 1 of type 'int \\\(\\\*\\\[\\\*]\\\)\\\[3]' .aka '\[^\n\r\}\]+'. declared with 1 unspecified variable bound" }
+void* f_pIA3ax (IA3 *x[*]);
+void* f_pIA3ax (IA3 *x[n]); // { dg-message "subsequently declared as 'int \\\(\\\*\\\[n]\\\)\\\[3]' with 0 unspecified variable bounds" "note" }
+void* f_pIA3ax (IA3 *x[n]) { return x; }
+
+
+void* f_pIA3an (IA3 *x[n]); // { dg-message "previously declared as 'int \\\(\\\*\\\[n]\\\)\\\[3]' with 0 unspecified variable bounds" "note" }
+void* f_pIA3an (IA3 *x[n]);
+void* f_pIA3an (IA3 *x[*]); // { dg-warning "argument 1 of type 'int \\\(\\\*\\\[\\\*]\\\)\\\[3]' .aka '\[^\n\r\}\]+'. declared with 1 unspecified variable bound" }
+void* f_pIA3an (IA3 *x[n]) { return x; }
+
+
+void nowarn_local_fndecl (void)
+{
+ typedef int IAm[m];
+
+ void* f_IAm (IAm);
+ void* f_IAm (int[m]);
+ void* f_IAm (IAm);
+
+ void* f_iam (int[m]);
+ void* f_iam (IAm);
+ void* f_iam (int[m]);
+
+ typedef int IA3[3];
+ typedef IA3 IAn_3[n];
+ typedef IAn_3 IA2_n_3[2];
+ typedef IA2_n_3 IAm_2_n_3[m];
+
+ void f_IAm_2_n_3 (IAm_2_n_3);
+ void f_IAm_2_n_3 (IA2_n_3[m]);
+ void f_IAm_2_n_3 (IAn_3[m][2]);
+ void f_IAm_2_n_3 (IA3[m][2][n]);
+ void f_IAm_2_n_3 (int[m][2][n][3]);
+
+ void f_iam_2_n_3 (int[m][2][n][3]);
+ void f_iam_2_n_3 (IA3[m][2][n]);
+ void f_iam_2_n_3 (IAn_3[m][2]);
+ void f_iam_2_n_3 (IAm_2_n_3);
+
+ void f_IAx_m_2_n_3 (IAm_2_n_3[*]);
+ void f_IAx_m_2_n_3 (IA2_n_3[*][m]);
+ void f_IAx_m_2_n_3 (IAn_3[*][m][2]);
+ void f_IAx_m_2_n_3 (IA3[*][m][2][n]);
+ void f_IAx_m_2_n_3 (int[*][m][2][n][3]);
+
+ void f_IA__m_2_n_3 (IAm_2_n_3[]);
+ void f_IA__m_2_n_3 (IA2_n_3[][m]);
+ void f_IA__m_2_n_3 (IAn_3[][m][2]);
+ void f_IA__m_2_n_3 (IA3[][m][2][n]);
+ void f_IA__m_2_n_3 (int[][m][2][n][3]);
+}
+
+
+void warn_local_fndecl (void)
+{
+ typedef int IAm[m];
+ typedef int IAn[n];
+
+ void* g_IAm (IAm); // { dg-message "previously declared as 'int\\\[m]' with bound 'm'" }
+ void* g_IAm (int[n]); // { dg-warning "argument 1 of type 'int\\\[n]' declared with mismatched bound 'n'" }
+ void* g_IAm (IAm);
+
+ void* g_iam (int[m]); // { dg-message "previously declared as 'int\\\[m]' with bound 'm'" }
+ void* g_iam (IAn); // { dg-warning "argument 1 of type 'int\\\[n]' declared with mismatched bound 'n'" }
+ void* g_iam (int[m]);
+
+
+ typedef int IA3[3];
+ typedef IA3 IAn_3[n];
+ typedef IAn_3 IA2_n_3[2];
+ typedef IA2_n_3 IAm_2_n_3[m];
+
+ typedef IA3 IAm_3[m];
+ typedef IAm_3 IA2_m_3[2];
+ typedef IA2_m_3 IAm_2_m_3[m];
+
+ void* g_IAm_2_n_3 (IAm_2_n_3);
+ void* g_IAm_2_n_3 (int[m][2][m][3]); // { dg-warning "argument 1 of type 'int\\\[m]\\\[2]\\\[m]\\\[3]' declared with mismatched bound 'm'" }
+ void* g_IAm_2_n_3 (IAm_2_n_3);
+
+ void* g_iam_2_n_2 (int[m][2][n][3]);
+ void* g_iam_2_n_2 (IAm_2_m_3); // { dg-warning "argument 1 of type 'int\\\[m]\\\[2]\\\[m]\\\[3]' declared with mismatched bound 'm'" }
+ void* g_iam_2_n_2 (int[m][2][n][3]);
+}
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-5.c b/gcc/testsuite/gcc.dg/Wvla-parameter-5.c
new file mode 100644
index 0000000..16b40d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-5.c
@@ -0,0 +1,22 @@
+/* Verify that combinations of array type qualifiers render correctly.
+ { dg-do compile }
+ { dg-options "-Wvla-parameter" } */
+
+extern int n1, n2;
+
+void fcx_n1 (int [const][n1]); // { dg-message "previously declared as 'int\\\[const]\\\[n1]' with bound 'n1'" "note" }
+void fcx_n1 (int [const][n2]); // { dg-warning "argument 1 of type 'int\\\[const]\\\[n2]' declared with mismatched bound 'n2'" }
+
+/* The mismatch in the array bound should not be diagnosed without
+ -Warray-parameter but the mismatch in the VLA should still be
+ diagnosed. */
+void fc3_n1 (int [const 3][n1]); // { dg-message "previously declared as 'int\\\[const 3]\\\[n1]' with bound 'n1'" "note" }
+void fc3_n1 (int [const 5][n2]); // { dg-warning "argument 1 of type 'int\\\[const 5]\\\[n2]' declared with mismatched bound 'n2'" }
+
+
+void frx_n1 (int [restrict][n1]); // { dg-message "previously declared as 'int\\\[restrict]\\\[n1]' with bound 'n1'" "note" }
+void frx_n1 (int [restrict][n2]); // { dg-warning "argument 1 of type 'int\\\[restrict]\\\[n2]' declared with mismatched bound 'n2'" }
+
+
+void fvx_n2 (int [volatile][n2]); // { dg-message "previously declared as 'int\\\[volatile]\\\[n2]' with bound 'n2'" "note" }
+void fvx_n2 (int [volatile][n1]); // { dg-warning "argument 1 of type 'int\\\[volatile]\\\[n1]' declared with mismatched bound 'n1'" }
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-6.c b/gcc/testsuite/gcc.dg/Wvla-parameter-6.c
new file mode 100644
index 0000000..268aeec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-6.c
@@ -0,0 +1,34 @@
+/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
+ and attribute access
+ Also verify the right arguments are underlined in the notes.
+ { dg-do compile }
+ { dg-options "-Wall -fdiagnostics-show-caret" } */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+RW (2, 3) void f1 (int n, int[n], int);
+/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
+ { dg-begin-multiline-output "" }
+ RW (2, 3) void f1 (int n, int[n], int);
+ ^~
+ { dg-end-multiline-output "" }
+ { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-6 }
+ { dg-begin-multiline-output "" }
+ RW (2, 3) void f1 (int n, int[n], int);
+ ~~~~^ ~~~~~~
+ { dg-end-multiline-output "" } */
+
+
+RW (2) void f2 (int, int[*], int);
+/* { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
+ { dg-begin-multiline-output "" }
+ RW (2, 3) void f2 (int, int[], int);
+ ^~~~~
+ { dg-end-multiline-output "" } */
+
+RW (2, 3) void f2 (int, int[], int);
+/* { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
+ { dg-begin-multiline-output "" }
+ RW (2) void f2 (int, int[*], int);
+ ^~~~~~
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter-7.c b/gcc/testsuite/gcc.dg/Wvla-parameter-7.c
new file mode 100644
index 0000000..14ce75f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter-7.c
@@ -0,0 +1,36 @@
+/* PR middle-end/97189 - ICE on redeclaration of a function with VLA argument
+ and attribute access
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+RW (2, 3) void f1 (int n, int[n], int);
+/* { dg-warning "attribute 'access \\(read_write, 2, 3\\)' positional argument 2 conflicts with previous designation by argument 3" "warning" { target *-*-* } .-1 }
+ { dg-message "designating the bound of variable length array argument 2" "note" { target *-*-* } .-2 } */
+
+void call_f1 (int *p)
+{
+ /* Verify that a warning is issued. Ideally, it seems the VLA bound
+ should take precedence over the attribute and the warning would
+ reference argument 1 but since the conflict in the redeclarations
+ of the function is already diagnosed don't test that (and let it
+ be acceptable for this warning to reference argument 3). */
+ f1 (-1, p, -1);
+ // { dg-warning "argument \\d value -1 is negative" "warning" { target *-*-* } .-1 }
+}
+
+RW (2) void f2 (int, int[*], int);
+// { dg-message "previously declared as a variable length array 'int\\\[\\\*]'" "note" { target *-*-* } .-1 }
+RW (2, 3) void f2 (int, int[], int);
+// { dg-warning "argument 2 of type 'int\\\[]' declared as an ordinary array" "warning" { target *-*-* } .-1 }
+
+void call_f2 (int *p)
+{
+ f2 (-1, p, 0);
+
+ /* Verify that the attribute access on the redeclaration of f2() takes
+ precedence over the one on the first declaration. */
+ f2 (0, p, -1);
+ // { dg-warning "argument 3 value -1 is negative" "warning" { target *-*-* } .-1 }
+}
diff --git a/gcc/testsuite/gcc.dg/Wvla-parameter.c b/gcc/testsuite/gcc.dg/Wvla-parameter.c
new file mode 100644
index 0000000..6e4df02
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wvla-parameter.c
@@ -0,0 +1,136 @@
+/* PR c/50584 - No warning for passing small array to C99 static array
+ declarator
+ Verify the -Wvla-parameter warnings correctly diagnose mismatches
+ between one-dimensional VLA and non-VLA arguments in redeclarations
+ of the same function.
+ Also verify that the array/pointer argument form in a mismatched
+ redeclaration doesn't override the form in the initial declaration.
+ { dg-do compile }
+ { dg-options "-Wall -Wvla-parameter" } */
+
+/* Verify that redeclaring an argument as a VLA with an unspecified
+ bound that was first declared as an ordinary array with an unspecified
+ bound triggers a warning. */
+void f1ia_x (int[]); // { dg-message "previously declared as an ordinary array 'int\\\[]'" "note" }
+void f1ia_x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ia_x (int[]);
+void f1ia_x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+/* Also verify that a definition of the same form as the first declaration
+ doesn't trigger a warning and doesn't prevent warnings for subsequent
+ mismatches. */
+void f1ia_x (int a[]) { (void)&a;}
+void f1ia_x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+
+/* Repeat the above but starting with an ordinary array with a constant
+ bound. */
+void f1ia1x (int[1]); // { dg-message "previously declared as an ordinary array 'int\\\[1]'" "note" }
+void f1ia1x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ia1x (int a[1]) { (void)&a; }
+void f1ia1x (int[1]);
+void f1ia1x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+
+void f1ipx (int*); // { dg-message "previously declared as a pointer 'int ?\\\*'" "note" }
+void f1ipx (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ipx (int*);
+void f1ipx (int *p) { (void)&p; }
+void f1ipx (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ipx (int*);
+
+void f2ipx (int*, int*); // { dg-message "previously declared as a pointer 'int ?\\\*'" "note" }
+void f2ipx (int*, int[*]); // { dg-warning "argument 2 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f2ipx (int*, int*);
+void f2ipx (int*, int[*]); // { dg-warning "argument 2 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f2ipx (int *p, int *q) { (void)&p; (void)&q; }
+void f2ipx (int*, int[*]); // { dg-warning "argument 2 of type 'int\\\[\\\*]' declared as a variable length array" }
+
+void f1ias2x (int[static 2]); // { dg-message "previously declared as an ordinary array 'int\\\[static 2]'" }
+void f1ias2x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ias2x (int[static 2]);
+void f1ias2x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ias2x (int a[static 2]) { (void)&a; }
+void f1ias2x (int[*]); // { dg-warning "argument 1 of type 'int\\\[\\\*]' declared as a variable length array" }
+void f1ias2x (int[static 2]);
+
+extern int nelts;
+
+void f1sa_var (short[]); // { dg-message "previously declared as an ordinary array 'short int\\\[]'" }
+void f1sa_var (short[nelts]); // { dg-warning "argument 1 of type 'short int\\\[nelts]' declared as a variable length array" }
+void f1sa_var (short[]);
+void f1sa_var (short[nelts]); // { dg-warning "argument 1 of type 'short int\\\[nelts]' declared as a variable length array" }
+void f1sa_var (short a[]) { (void)&a; }
+void f1sa_var (short[nelts]); // { dg-warning "argument 1 of type 'short int\\\[nelts]' declared as a variable length array" }
+void f1sa_var (short[]);
+
+void f1sa_expr (int[]); // { dg-message "previously declared as an ordinary array 'int\\\[]'" }
+void f1sa_expr (int[nelts + 1]); // { dg-warning "argument 1 of type 'int\\\[nelts \\\+ 1]' declared as a variable length array" }
+void f1sa_expr (int[]);
+void f1sa_expr (int[nelts * 2]); // { dg-warning "argument 1 of type 'int\\\[nelts \\\* 2]' declared as a variable length array" }
+void f1sa_expr (int a[]) { (void)&a; }
+void f1sa_expr (int[nelts / 3]); // { dg-warning "argument 1 of type 'int\\\[nelts / 3]' declared as a variable length array" }
+void f1sa_expr (int[]);
+
+extern int f (int);
+
+void f1ia_f (int[]); // { dg-message "previously declared as an ordinary array 'int\\\[]'" }
+void f1ia_f (int[f (1)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(1\\\)]' declared as a variable length array" }
+void f1ia_f (int[]);
+void f1ia_f (int[f (2)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(2\\\)]' declared as a variable length array" }
+void f1ia_f (int a[]) { (void)&a; }
+void f1ia_f (int[f (3)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(3\\\)]' declared as a variable length array" }
+void f1ia_f (int[f (4)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(4\\\)]' declared as a variable length array" }
+void f1ia_f (int[]);
+
+void f1iaf0_f1 (int[f (0)]); // { dg-message "previously declared as 'int\\\[f *\\\(0\\\)]'" }
+void f1iaf0_f1 (int[f (1)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(1\\\)]' declared with mismatched bound" }
+void f1iaf0_f1 (int[f (0)]);
+void f1iaf0_f1 (int[f (1)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(1\\\)]' declared with mismatched bound" }
+void f1iaf0_f1 (int a[f (0)]) { (void)&a; }
+void f1iaf0_f1 (int[f (1)]); // { dg-warning "argument 1 of type 'int\\\[f *\\\(1\\\)]' declared with mismatched bound" }
+void f1iaf0_f1 (int[f (0)]);
+
+void f1la_ (long[]); // { dg-message "previously declared as an ordinary array 'long int\\\[]'" }
+void f1la_ (long[nelts]); // { dg-warning "argument 1 of type 'long int\\\[nelts]' declared as a variable length array" }
+void f1la_ (long[]);
+void f1la_ (long a[nelts]) // { dg-warning "argument 1 of type 'long int\\\[nelts]' declared as a variable length array" }
+{ (void)&a; }
+void f1la_ (long[]);
+
+void f2ca_ (int, char[]); // { dg-message "previously declared as an ordinary array 'char\\\[]'" }
+void f2ca_ (int n, char[n]); // { dg-warning "argument 2 of type 'char\\\[n]' declared as a variable length array" }
+void f2ca_ (int, char[]);
+void f2ca_ (int n, char a[n]) // { dg-warning "argument 2 of type 'char\\\[n]' declared as a variable length array" }
+{ (void)&n; (void)&a; }
+
+void f2ia1_f (int n, int[n]); // { dg-message "previously declared as 'int\\\[n]' with bound argument 1" }
+void f2ia1_f (int, int[f (0)]); // { dg-warning "argument 2 of type 'int\\\[f *\\\(0\\\)]' declared with mismatched bound 'f *\\\(0\\\)'" }
+void f2ia1_f (int m, int[m]);
+void f2ia1_f (int, int[f (1)]); // { dg-warning "argument 2 of type 'int\\\[f *\\\(1\\\)]' declared with mismatched bound 'f *\\\(1\\\)'" }
+void f2ia1_f (int x, int a[x]) { (void)&x; (void)&a; }
+void f2ia1_f (int, int[f (2)]); // { dg-warning "argument 2 of type 'int\\\[f *\\\(2\\\)]' declared with mismatched bound 'f *\\\(2\\\)'" }
+void f2ia1_f (int y, int[y]);
+
+void f2iaf_1 (int, int[f (0)]); // { dg-message "previously declared as 'int\\\[f *\\\(0\\\)]'" }
+void f2iaf_1 (int n, int[n]); // { dg-warning "argument 2 of type 'int\\\[n]' declared with mismatched bound argument 1" }
+void f2iaf_1 (int, int[f (0)]);
+void f2iaf_1 (int m, int[m]); // { dg-warning "argument 2 of type 'int\\\[m]' declared with mismatched bound argument 1" }
+void f2iaf_1 (int x, int a[f (0)]) { (void)&x; (void)&a; }
+void f2iaf_1 (int y, int[y]); // { dg-warning "argument 2 of type 'int\\\[y]' declared with mismatched bound argument 1" }
+
+
+void f3ia1 (int n, int, int[n]); // { dg-message "previously declared as 'int\\\[n]' with bound argument 1" }
+void f3ia1 (int, int n, int[n]); // { dg-warning "argument 3 of type 'int\\\[n]' declared with mismatched bound argument 2" }
+void f3ia1 (int n, int, int[n]);
+
+
+extern int g (int);
+
+void f1iaf_g (int[f (1)]); // { dg-message "previously declared as 'int\\\[f *\\\(1\\\)]'" }
+void f1iaf_g (int[g (1)]); // { dg-warning "argument 1 of type 'int\\\[g *\\\(1\\\)]' declared with mismatched bound" }
+void f1iaf_g (int[f (1)]);
+
+
+void nrf1iaf_g (int[f (1)]); // { dg-message "previously declared as 'int\\\[f *\\\(1\\\)]'" }
+__attribute__ ((nonnull))
+void nrf1iaf_g (int[g (1)]); // { dg-warning "argument 1 of type 'int\\\[g *\\\(1\\\)]' declared with mismatched bound" }
+__attribute__ ((noreturn))
+void nrf1iaf_g (int[f (1)]);
diff --git a/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue-2.c b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue-2.c
new file mode 100644
index 0000000..57fd30a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue-2.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-fanalyzer-show-duplicate-count" } */
+
+#include <stdlib.h>
+
+typedef struct _krb5_data {
+ char *data;
+} krb5_data;
+
+/* Ensure that we de-duplicate the various paths to reach here,
+ and only emit one diagnostic. */
+
+void
+recvauth_common(krb5_data common)
+{
+ free(common.data);
+ free(common.data); /* { dg-warning "double-'free' of 'common.data'" "inner warning" } */
+ /* { dg-warning "double-'free' of 'inbuf_a.data' " "inbuf_a warning" { target *-*-* } .-1 } */
+ /* { dg-warning "double-'free' of 'inbuf_b.data' " "inbuf_b warning" { target *-*-* } .-2 } */
+ /* { dg-message "2 duplicates" "duplicates notification" { xfail *-*-* } .-3 } */
+}
+
+void krb5_recvauth(krb5_data inbuf_a)
+{
+ recvauth_common(inbuf_a);
+}
+
+void krb5_recvauth_version(krb5_data inbuf_b)
+{
+ recvauth_common(inbuf_b);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c
index b43148c..0fc865f 100644
--- a/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c
+++ b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-dedupe-issue.c
@@ -14,7 +14,7 @@ recvauth_common(krb5_data inbuf)
{
free(inbuf.data);
free(inbuf.data); /* { dg-warning "double-'free'" "warning" } */
- /* { dg-message "2 duplicates" "duplicates notification" { target *-*-* } .-1 } */
+ /* { dg-message "2 duplicates" "duplicates notification" { xfail *-*-* } .-1 } */
}
void krb5_recvauth(krb5_data inbuf)
diff --git a/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c
index aa9deb3..5edbdb1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c
+++ b/gcc/testsuite/gcc.dg/analyzer/CVE-2005-1689-minimal.c
@@ -1,4 +1,5 @@
#include <stdlib.h>
+#include "analyzer-decls.h"
typedef struct _krb5_data {
char *data;
@@ -28,3 +29,63 @@ test_3 (krb5_data inbuf, int flag)
}
free((char *)inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */
}
+
+extern void unknown_fn (void *);
+
+void
+test_4 (krb5_data inbuf)
+{
+ unknown_fn (NULL);
+ free(inbuf.data); /* { dg-message "first 'free' here" } */
+ free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" } */
+}
+
+void
+test_5 (krb5_data inbuf)
+{
+ unknown_fn (&inbuf);
+ free(inbuf.data); /* { dg-message "first 'free' here" } */
+ free(inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" "inbuf.data" } */
+ /* { dg-bogus "double-'free' of 'inbuf'" "inbuf" { target *-*-* } .-1 } */
+}
+
+typedef struct _padded_krb5_data {
+ int pad;
+ char *data;
+} padded_krb5_data;
+
+void
+test_6 (padded_krb5_data inbuf)
+{
+ unknown_fn (&inbuf.data);
+ free((char *)inbuf.data); /* { dg-message "first 'free' here" } */
+ free((char *)inbuf.data); /* { dg-warning "double-'free' of 'inbuf.data'" "inbuf.data" } */
+}
+
+void
+test_7 (padded_krb5_data inbuf)
+{
+ unknown_fn (&inbuf.data);
+ free((char *)inbuf.data);
+
+ unknown_fn (&inbuf.data);
+ free((char *)inbuf.data);
+}
+
+void
+test_8 (padded_krb5_data inbuf, int flag)
+{
+ if (flag)
+ {
+ unknown_fn (&inbuf.data);
+ free((char *)inbuf.data);
+ }
+ /* Should have two enodes, one for the explicit "freed" state, and one
+ for the implicit "start" state. */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
+ unknown_fn (&inbuf.data);
+
+ /* Should have just one enode, for the implicit "start" state. */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/abs-1.c b/gcc/testsuite/gcc.dg/analyzer/abs-1.c
new file mode 100644
index 0000000..d6ce8d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/abs-1.c
@@ -0,0 +1,22 @@
+#include "analyzer-decls.h"
+
+extern long int labs (long int x)
+ __attribute__ ((__nothrow__ , __leaf__))
+ __attribute__ ((__const__));
+
+long int test_1 (long int x)
+{
+ return labs (x);
+}
+
+static long __attribute__((noinline))
+hide_long (long x)
+{
+ return x;
+}
+
+long int test_2 (long int x)
+{
+ __analyzer_eval (labs (hide_long (42)) == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (labs (hide_long (-17)) == 17); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-1.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-1.c
new file mode 100644
index 0000000..26050f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/aliasing-1.c
@@ -0,0 +1,25 @@
+#include "analyzer-decls.h"
+
+int a;
+void test (int *p, int x)
+{
+ int y;
+
+ a = 17;
+ x = 42;
+ y = 13;
+
+ __analyzer_eval (a == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (y == 13); /* { dg-warning "TRUE" } */
+
+ __analyzer_eval (p == &a); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (p == &x); /* { dg-warning "FALSE" } */
+ __analyzer_eval (p == &y); /* { dg-warning "FALSE" } */
+
+ *p = 73;
+
+ __analyzer_eval (a == 17); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (x == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (y == 13); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-2.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-2.c
new file mode 100644
index 0000000..38ceeff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/aliasing-2.c
@@ -0,0 +1,32 @@
+#include "analyzer-decls.h"
+
+extern void escape (int *p);
+
+int a;
+void test (int *p, int x)
+{
+ int y;
+
+ a = 17;
+ x = 42;
+ y = 13;
+
+ __analyzer_eval (a == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (y == 13); /* { dg-warning "TRUE" } */
+
+ escape (&x);
+ __analyzer_eval (a == 17); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (x == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (y == 13); /* { dg-warning "TRUE" } */
+
+ __analyzer_eval (p == &a); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (p == &x); /* { dg-warning "FALSE" } */
+ __analyzer_eval (p == &y); /* { dg-warning "FALSE" } */
+
+ *p = 73;
+
+ __analyzer_eval (a == 17); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (x == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (y == 13); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/alloca-leak.c b/gcc/testsuite/gcc.dg/analyzer/alloca-leak.c
index 6d9fe34..9331993 100644
--- a/gcc/testsuite/gcc.dg/analyzer/alloca-leak.c
+++ b/gcc/testsuite/gcc.dg/analyzer/alloca-leak.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target alloca } */
+
#include <alloca.h>
void *test (void)
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
index 180e873..d96b3f2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h
@@ -7,6 +7,11 @@
/* Trigger a breakpoint in the analyzer when reached. */
extern void __analyzer_break (void);
+/* Emit a warning describing the 2nd argument (which can be of any
+ type), at the given verbosity level. This is for use when
+ debugging, and may be of use in DejaGnu tests. */
+extern void __analyzer_describe (int verbosity, ...);
+
/* Dump copious information about the analyzer’s state when reached. */
extern void __analyzer_dump (void);
@@ -20,8 +25,6 @@ extern void __analyzer_dump (void);
will also dump all of the states within those nodes. */
extern void __analyzer_dump_exploded_nodes (int);
-extern void __analyzer_dump_num_heap_regions (void);
-
/* Emit a placeholder "note" diagnostic with a path to this call site,
if the analyzer finds a feasible path to it. */
extern void __analyzer_dump_path (void);
diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
index ac9c495..d72fef3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
+++ b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
@@ -30,7 +30,7 @@ if [info exists DEFAULT_CFLAGS] then {
}
# If a testcase doesn't have special options, use these.
-set DEFAULT_CFLAGS "-fanalyzer -fdiagnostics-path-format=separate-events -Wanalyzer-too-complex -fanalyzer-call-summaries"
+set DEFAULT_CFLAGS "-fanalyzer -Wanalyzer-too-complex -fanalyzer-call-summaries"
# Initialize `dg'.
dg-init
diff --git a/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c b/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
index e0bf1f4..70bb921 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
+++ b/gcc/testsuite/gcc.dg/analyzer/attribute-nonnull.c
@@ -12,9 +12,10 @@ extern void bar(void *ptrA, void *ptrB, void *ptrC) /* { dg-message "argument 1
void test_1 (void *p, void *q, void *r)
{
foo(p, q, r);
- foo(NULL, q, r);
+ foo(NULL, q, r); /* { dg-warning "use of NULL where non-null expected" "warning" } */
+ /* { dg-message "argument 1 NULL where non-null expected" "note" { target *-*-* } .-1 } */
foo(p, NULL, r);
- foo(p, q, NULL);
+ foo(p, q, NULL); /* { dg-warning "use of NULL where non-null expected" } */
}
void test_1a (void *q, void *r)
@@ -27,9 +28,10 @@ void test_1a (void *q, void *r)
void test_2 (void *p, void *q, void *r)
{
bar(p, q, r);
- bar(NULL, q, r);
- bar(p, NULL, r);
- bar(p, q, NULL);
+ bar(NULL, q, r); /* { dg-warning "use of NULL where non-null expected" "warning" } */
+ bar(p, NULL, r); /* { dg-warning "use of NULL where non-null expected" "warning" } */
+ /* { dg-message "argument 2 NULL where non-null expected" "note" { target *-*-* } .-1 } */
+ bar(p, q, NULL); /* { dg-warning "use of NULL where non-null expected" "warning" } */
}
void test_3 (void *q, void *r)
diff --git a/gcc/testsuite/gcc.dg/analyzer/bzero-1.c b/gcc/testsuite/gcc.dg/analyzer/bzero-1.c
new file mode 100644
index 0000000..8945086
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/bzero-1.c
@@ -0,0 +1,11 @@
+#include "analyzer-decls.h"
+
+extern void bzero(void *s, __SIZE_TYPE__ n);
+
+void test_1 (void)
+{
+ char tmp[1024];
+ bzero (tmp, 1024);
+ __analyzer_eval (tmp[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (tmp[1023] == 0); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/bzip2-arg-parse-1.c b/gcc/testsuite/gcc.dg/analyzer/bzip2-arg-parse-1.c
new file mode 100644
index 0000000..1f1d829
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/bzip2-arg-parse-1.c
@@ -0,0 +1,95 @@
+/* Integration test to verify that we don't explode in this
+ argument-parsing logic.
+ Adapted from part of bzip2-1.0.8: bzip2.c: main. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "analyzer-decls.h"
+
+/* This test file has been heavily modified from the bzip2.c original,
+ which has the following license boilerplate. */
+/* ------------------------------------------------------------------
+ This file is part of bzip2/libbzip2, a program and library for
+ lossless, block-sorting data compression.
+
+ bzip2/libbzip2 version 1.0.8 of 13 July 2019
+ Copyright (C) 1996-2019 Julian Seward <jseward@acm.org>
+
+ Please read the WARNING, DISCLAIMER and PATENTS sections in the
+ README file.
+
+ This program is released under the terms of the license contained
+ in the file LICENSE.
+ ------------------------------------------------------------------ */
+
+typedef char Char;
+typedef unsigned char Bool;
+typedef int Int32;
+
+#define True ((Bool)1)
+#define False ((Bool)0)
+
+typedef
+ struct zzzz {
+ Char *name;
+ struct zzzz *link;
+ }
+ Cell;
+
+Int32 verbosity;
+Bool keepInputFiles, smallMode;
+Bool forceOverwrite, noisy;
+Int32 blockSize100k;
+Int32 opMode;
+Int32 srcMode;
+Char *progName;
+
+extern void license ( void );
+extern void usage ( Char *fullProgName );
+
+void test (Cell *argList)
+{
+ Cell *aa;
+ Int32 i, j;
+
+ for (aa = argList; aa != NULL; aa = aa->link) {
+ if (aa->name[0] == '-' && aa->name[1] != '-') {
+ for (j = 1; aa->name[j] != '\0'; j++) {
+ switch (aa->name[j]) {
+ case 'c': srcMode = 2; break;
+ case 'd': opMode = 2; break;
+ case 'z': opMode = 1; break;
+ case 'f': forceOverwrite = True; break;
+ case 't': opMode = 3; break;
+ case 'k': keepInputFiles = True; break;
+ case 's': smallMode = True; break;
+ case 'q': noisy = False; break;
+ case '1': blockSize100k = 1; break;
+ case '2': blockSize100k = 2; break;
+ case '3': blockSize100k = 3; break;
+ case '4': blockSize100k = 4; break;
+ case '5': blockSize100k = 5; break;
+ case '6': blockSize100k = 6; break;
+ case '7': blockSize100k = 7; break;
+ case '8': blockSize100k = 8; break;
+ case '9': blockSize100k = 9; break;
+ case 'V':
+ case 'L': license(); break;
+ case 'v': verbosity++; break;
+ case 'h': usage ( progName );
+ exit ( 0 );
+ break;
+ default: fprintf ( stderr, "%s: Bad flag `%s'\n",
+ progName, aa->name );
+ usage ( progName );
+ exit ( 1 );
+ break;
+ }
+ }
+ }
+ }
+
+ /* The analyzer ought to be able to successfully merge all of the
+ above changes that can reach here into a single state. */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/casts-1.c b/gcc/testsuite/gcc.dg/analyzer/casts-1.c
new file mode 100644
index 0000000..15cd85f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/casts-1.c
@@ -0,0 +1,49 @@
+#include "analyzer-decls.h"
+
+struct s1
+{
+ char a;
+ char b;
+ char c;
+ char d;
+};
+
+struct s2
+{
+ char arr[4];
+};
+
+void test_1 ()
+{
+ struct s1 x = {'A', 'B', 'C', 'D'};
+ __analyzer_eval (x.a == 'A'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.b == 'B'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.c == 'C'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.d == 'D'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (((struct s2 *)&x)->arr[0] == 'A'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (((struct s2 *)&x)->arr[1] == 'B'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (((struct s2 *)&x)->arr[2] == 'C'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (((struct s2 *)&x)->arr[3] == 'D'); /* { dg-warning "TRUE" } */
+
+ ((struct s2 *)&x)->arr[1] = '#';
+ __analyzer_eval (((struct s2 *)&x)->arr[1] == '#'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.b == '#'); /* { dg-warning "TRUE" } */
+}
+
+void test_2 ()
+{
+ struct s2 x = {{'A', 'B', 'C', 'D'}};
+ __analyzer_eval (x.arr[0] == 'A'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.arr[1] == 'B'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.arr[2] == 'C'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (x.arr[3] == 'D'); /* { dg-warning "TRUE" } */
+ struct s1 *p = (struct s1 *)&x;
+ __analyzer_eval (p->a == 'A'); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ __analyzer_eval (p->b == 'B'); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ __analyzer_eval (p->c == 'C'); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ __analyzer_eval (p->d == 'D'); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/casts-2.c b/gcc/testsuite/gcc.dg/analyzer/casts-2.c
new file mode 100644
index 0000000..3eef717
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/casts-2.c
@@ -0,0 +1,15 @@
+#include "analyzer-decls.h"
+
+void test_1 (int i)
+{
+ char c1 = i;
+ char c2 = i;
+ __analyzer_eval (c1 == i); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (c1 == c2); /* { dg-warning "TRUE" } */
+}
+
+void test_2 (char c)
+{
+ int i = c;
+ __analyzer_eval (i == c); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c
index bb03487..0f07818 100644
--- a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-1.c
@@ -40,13 +40,13 @@ void test_4 (void)
struct ptr_wrapper r;
r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */
} /* { dg-warning "leak of 'r.ptr'" } */
-/* { dg-bogus "leak of '<unknown>'" "unknown leak" { xfail *-*-* } .-1 } */
+/* { dg-bogus "leak of '<unknown>'" "unknown leak" { target *-*-* } .-1 } */
static struct ptr_wrapper __attribute__((noinline))
called_by_test_5a (void)
{
struct ptr_wrapper r;
- r.ptr = malloc (sizeof (int));
+ r.ptr = malloc (sizeof (int)); /* { dg-message "allocated here" } */
return r;
}
@@ -54,15 +54,14 @@ void test_5a (void)
{
struct ptr_wrapper q = called_by_test_5a ();
} /* { dg-warning "leak of 'q.ptr'" } */
-/* TODO: show the allocation point. */
static struct ptr_wrapper __attribute__((noinline))
called_by_test_5b (void)
{
struct ptr_wrapper r;
r.ptr = malloc (sizeof (int));
- return r; /* { dg-warning "leak" } */
- /* TODO: show the allocation point. */
+ return r; /* { dg-warning "leak of '<return-value>.ptr'" } */
+ /* TODO: show the allocation point; improve above message. */
}
void test_5b (void)
diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-3.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-3.c
index 5083faa..4925926 100644
--- a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-3.c
@@ -22,4 +22,4 @@ test_2 (void)
{
struct union_wrapper uw2;
uw2.u.ptr = malloc (1024);
-} /* { dg-warning "leak of '\\(void \\*\\)uw2.u'" } */
+} /* { dg-warning "leak of 'uw2.u.ptr'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-4.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-4.c
new file mode 100644
index 0000000..5c0a5f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-4.c
@@ -0,0 +1,28 @@
+#include "analyzer-decls.h"
+
+struct coord
+{
+ int x;
+ int y;
+};
+
+void test_1 (void)
+{
+ struct coord arr[16];
+
+ arr[2].y = 4;
+ arr[3].x = 5;
+ arr[3].y = 6;
+ arr[4].x = 7;
+ arr[6].y = 8;
+ arr[8].x = 9;
+
+ arr[7] = arr[3];
+
+ __analyzer_eval (arr[7].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[7].y == 6); /* { dg-warning "TRUE" } */
+
+ /* Make sure we don't touch the neighbors. */
+ __analyzer_eval (arr[6].y == 8); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[8].x == 9); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c
new file mode 100644
index 0000000..ccf8fe3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c
@@ -0,0 +1,142 @@
+#include "analyzer-decls.h"
+
+struct coord
+{
+ int x;
+ int y;
+};
+
+/* Copying from one on-stack array to another. */
+
+void test_1 (void)
+{
+ struct coord arr_a[16];
+ struct coord arr_b[16];
+ arr_a[3].x = 5;
+ arr_a[3].y = 6;
+
+ arr_b[7] = arr_a[3];
+
+ __analyzer_eval (arr_b[7].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr_b[7].y == 6); /* { dg-warning "TRUE" } */
+}
+
+/* Copying from an on-stack array to a global array. */
+
+struct coord glob_arr[16];
+
+void test_2 (void)
+{
+ struct coord arr[16];
+ arr[3].x = 5;
+ arr[3].y = 6;
+
+ glob_arr[7] = arr[3];
+
+ __analyzer_eval (glob_arr[7].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (glob_arr[7].y == 6); /* { dg-warning "TRUE" } */
+}
+
+/* Copying from a partially initialized on-stack array to a global array. */
+
+struct coord glob_arr[16];
+
+void test_3 (void)
+{
+ struct coord arr[16];
+ arr[3].y = 6;
+
+ glob_arr[7] = arr[3]; // or should the uninit warning be here?
+
+ __analyzer_eval (glob_arr[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ __analyzer_eval (glob_arr[7].y == 6); /* { dg-warning "TRUE" } */
+}
+
+/* Symbolic bindings: copying from one array to another. */
+
+struct coord glob_arr[16];
+
+void test_4 (int i)
+{
+ struct coord arr_a[16];
+ struct coord arr_b[16];
+ arr_a[i].x = 5;
+ arr_a[i].y = 6;
+ __analyzer_eval (arr_a[i].x == 5); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+ __analyzer_eval (arr_a[i].y == 6); /* { dg-warning "TRUE" } */
+
+ arr_b[i] = arr_a[i];
+
+ __analyzer_eval (arr_b[i].x == 5); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+ __analyzer_eval (arr_b[i].y == 6); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+}
+
+/* Symbolic bindings: copying within an array: symbolic src and dest */
+
+struct coord glob_arr[16];
+
+void test_5a (int i, int j)
+{
+ struct coord arr[16];
+ arr[i].x = 5;
+ arr[i].y = 6;
+
+ arr[j] = arr[i];
+
+ __analyzer_eval (arr[j].x == 5); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+ __analyzer_eval (arr[j].y == 6); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+}
+
+/* Symbolic bindings: copying within an array: symbolic src, concrete dest. */
+
+struct coord glob_arr[16];
+
+void test_5b (int i)
+{
+ struct coord arr[16];
+ arr[i].x = 5;
+ arr[i].y = 6;
+
+ arr[3] = arr[i];
+
+ __analyzer_eval (arr[3].x == 5); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+ __analyzer_eval (arr[3].y == 6); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+}
+
+/* Symbolic bindings: copying within an array: concrete src, symbolic dest. */
+
+struct coord glob_arr[16];
+
+void test_5c (int i)
+{
+ struct coord arr[16];
+ arr[3].x = 5;
+ arr[3].y = 6;
+
+ arr[i] = arr[3];
+
+ __analyzer_eval (arr[i].x == 5); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+ __analyzer_eval (arr[i].y == 6); /* { dg-warning "TRUE" "TRUE" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "UNKNOWN" { xfail *-*-* } .-1 } */
+}
+
+/* No info on the subregion being copied, and hence
+ binding_cluster2::maybe_get_compound_binding should return NULL. */
+
+void test_6 (void)
+{
+ struct coord arr[16];
+ arr[7] = glob_arr[3];
+
+ __analyzer_eval (arr[7].x == 5); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[7].y == 6); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c b/gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c
index a00127b..b1ac541 100644
--- a/gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c
+++ b/gcc/testsuite/gcc.dg/analyzer/conditionals-notrans.c
@@ -7,15 +7,12 @@ void test (int i, int j)
{
__analyzer_eval (i > 4); /* { dg-warning "TRUE" } */
__analyzer_eval (i <= 4); /* { dg-warning "FALSE" } */
- __analyzer_eval (i > 3); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i > 3); /* { dg-warning "TRUE" } */
__analyzer_eval (i > 5); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (i != 3); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i != 3); /* { dg-warning "TRUE" } */
- __analyzer_eval (i == 3); /* { dg-warning "FALSE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 3); /* { dg-warning "FALSE" } */
__analyzer_eval (i != 4); /* { dg-warning "TRUE" } */
__analyzer_eval (i == 4); /* { dg-warning "FALSE" } */
@@ -43,21 +40,17 @@ void test (int i, int j)
__analyzer_eval (i <= 4); /* { dg-warning "TRUE" } */
__analyzer_eval (i > 3); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (i > 5); /* { dg-warning "FALSE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i > 5); /* { dg-warning "FALSE" } */
__analyzer_eval (i != 3); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (i == 3); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (i != 4); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (i == 4); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (i == 5); /* { dg-warning "FALSE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
- __analyzer_eval (i != 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 5); /* { dg-warning "FALSE" } */
+ __analyzer_eval (i != 5); /* { dg-warning "TRUE" } */
__analyzer_eval (i < 5); /* { dg-warning "TRUE" } */
- __analyzer_eval (i <= 5); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i <= 5); /* { dg-warning "TRUE" } */
}
}
@@ -101,8 +94,7 @@ void test_range_int_gt_lt (int i)
{
if (i > 3)
if (i < 5)
- __analyzer_eval (i == 4); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 4); /* { dg-warning "TRUE" } */
}
void test_range_float_gt_lt (float f)
@@ -116,8 +108,7 @@ void test_range_int_ge_lt (int i)
{
if (i >= 4)
if (i < 5)
- __analyzer_eval (i == 4); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 4); /* { dg-warning "TRUE" } */
}
void test_range_float_ge_lt (float f)
@@ -131,8 +122,7 @@ void test_range_int_gt_le (int i)
{
if (i > 3)
if (i <= 4)
- __analyzer_eval (i == 4); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 4); /* { dg-warning "TRUE" } */
}
void test_range_float_gt_le (float f)
@@ -146,8 +136,7 @@ void test_range_int_ge_le (int i)
{
if (i >= 4)
if (i <= 4)
- __analyzer_eval (i == 4); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (i == 4); /* { dg-warning "TRUE" } */
}
void test_range_float_ge_le (float f)
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
index 1db9913..3f16a38 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-1.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target alloca } */
+
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
@@ -179,15 +181,8 @@ int test_12d (struct coord c)
{
struct coord d;
d = c;
- __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "actual" { target *-*-* } .-1 } */
- /* TODO(xfail): c and d share the same unknown value of type "coord", but
- attempts to access the fields lead to different unknown values. */
-
- __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "actual" { target *-*-* } .-1 } */
- // TODO(xfail): likewise
-
+ __analyzer_eval (d.x == c.x); /* { dg-warning "TRUE" } */
+ __analyzer_eval (d.y == c.y); /* { dg-warning "TRUE" } */
__analyzer_eval (d.x == d.y); /* { dg-warning "UNKNOWN" } */
/* d and c share an unknown value of type "struct coord".
But d.x and d.y should be different unknown values (although they inherit
@@ -209,25 +204,21 @@ void test_13 (struct outer *o)
{
__analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */
o->mid.in.f = 0.f;
- __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "TRUE" "PR 93356" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "disabled float comparisons" { target *-*-* } .-1 } */
+ __analyzer_eval (o->mid.in.f == 0.f); /* { dg-warning "TRUE" } */
}
void test_14 (struct outer o)
{
__analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "UNKNOWN" } */
o.mid.in.f = 0.f;
- __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "TRUE" "PR 93356" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "disabled float comparisons" { target *-*-* } .-1 } */
+ __analyzer_eval (o.mid.in.f == 0.f); /* { dg-warning "TRUE" } */
}
void test_15 (const char *str)
{
char ch = str[0];
__analyzer_eval (ch == 'a'); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (ch == str[0]); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (ch == str[0]); /* { dg-warning "TRUE" } */
ch = 'a';
__analyzer_eval (ch == 'a'); /* { dg-warning "TRUE" } */
@@ -240,15 +231,15 @@ void test_16 (void)
__analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */
- __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */
- __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */
__analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */
+
+ /* Out-of-bounds. */
+ __analyzer_eval (msg[100] == 'e'); /* { dg-warning "UNKNOWN" } */
+ // TODO: some kind of warning for the out-of-bounds access
}
static const char *__attribute__((noinline))
@@ -263,13 +254,9 @@ void test_16_alt (void)
__analyzer_eval (msg != NULL); /* { dg-warning "TRUE" } */
- __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (msg[0] == 'h'); /* { dg-warning "TRUE" } */
- __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (msg[1] == 'e'); /* { dg-warning "TRUE" } */
__analyzer_eval (strlen (msg) == 11); /* { dg-warning "TRUE" } */
}
@@ -332,9 +319,6 @@ void test_16e (int i)
__analyzer_eval (j == i); /* { dg-warning "UNKNOWN" } */
}
-/* TODO: and more complicated graph-like examples, where anything that's
- reachable from the pointer might be modified. */
-
void test_17 (int i)
{
int j = 42;
@@ -475,13 +459,7 @@ void test_23 (struct foo *f, struct foo *g)
i = f->i + g->i;
j = f->i + g->i;
k = f->i * g->i;
- __analyzer_eval (i == j); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- /* TODO(xfail): we'd need to record that the two unknown values are both
- the sum of the two unknown input values (and thus are the same); not
- yet sure if we want arbitrary expression trees in the representation
- (analysis termination concerns). */
-
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
__analyzer_eval (i == k); /* { dg-warning "UNKNOWN" } */
}
@@ -494,9 +472,7 @@ void test_24 (struct foo *f)
/* Overwriting a whole struct should invalidate our knowledge
about fields within it. */
g = *f;
- __analyzer_eval (g.i == 42); /* { dg-warning "UNKNOWN" "desired" { xfail *-*-* } } */
- /* { dg-warning "TRUE" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (g.i == 42); /* { dg-warning "UNKNOWN" } */
}
void test_25 (struct foo *f)
@@ -511,16 +487,14 @@ void test_25 (struct foo *f)
source value should update our knowledge about fields within
the dest value. */
g = *f;
- __analyzer_eval (g.i == 43); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "FALSE" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail)
+ __analyzer_eval (g.i == 43); /* { dg-warning "TRUE" } */
}
void test_26 (struct coord *p, struct coord *q)
{
p->x = 42;
- q->y = 17;
- __analyzer_eval (p->x == 42); /* { dg-warning "TRUE" } */
+ q->y = 17; /* could clobber p->x. */
+ __analyzer_eval (p->x == 42); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (p->y); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (q->y == 17); /* { dg-warning "TRUE" } */
@@ -529,26 +503,21 @@ void test_26 (struct coord *p, struct coord *q)
source value should update our knowledge about fields within
the dest value. */
*p = *q;
- __analyzer_eval (p->x); /* { dg-warning "UNKNOWN" "desired" { xfail *-*-* } } */
- /* { dg-warning "TRUE" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail): should have been overwritten
+ __analyzer_eval (p->x); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (p->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
// TODO(xfail): should have been overwritten with q->y
__analyzer_eval (q->x); /* { dg-warning "UNKNOWN" } */
- __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (q->y == 17); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
}
void test_27 (struct coord *p)
{
memset (p, 0, sizeof (struct coord));
- __analyzer_eval (p->x == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
- __analyzer_eval (p->y == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- // TODO(xfail):
+ __analyzer_eval (p->x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (p->y == 0); /* { dg-warning "TRUE" } */
}
void test_28 (struct coord *p)
@@ -661,6 +630,8 @@ void test_29a (struct coord p[])
__analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
q -= 2;
+ __analyzer_eval (q == &p[7]); /* { dg-warning "UNKNOWN" } */
+ // TODO: make this be TRUE
__analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
__analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
@@ -709,6 +680,7 @@ void test_29b (void)
__analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
q -= 2;
+ __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */
__analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
__analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
@@ -757,6 +729,7 @@ void test_29c (int len)
__analyzer_eval (q[-2].y == 107025); /* { dg-warning "TRUE" } */
q -= 2;
+ __analyzer_eval (q == &p[7]); /* { dg-warning "TRUE" } */
__analyzer_eval (q->x == 107024); /* { dg-warning "TRUE" } */
__analyzer_eval (q->y == 107025); /* { dg-warning "TRUE" } */
@@ -934,12 +907,12 @@ void test_41 (void)
union u u;
u.i = 42;
__analyzer_eval (u.i == 42); /* { dg-warning "TRUE" } */
- __analyzer_eval (u.ptr == NULL); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (u.ptr == NULL); /* { dg-warning "UNKNOWN|FALSE" } */
/* Writes to a union member should invalidate knowledge about other members. */
u.ptr = NULL;
__analyzer_eval (u.ptr == NULL); /* { dg-warning "TRUE" } */
- __analyzer_eval (u.i == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (u.i == 42); /* { dg-warning "UNKNOWN|FALSE" } */
}
void test_42 (void)
@@ -948,8 +921,7 @@ void test_42 (void)
float f;
i = 42;
f = i;
- __analyzer_eval (f == 42.0); /* { dg-warning "TRUE" "PR 93356" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "disabled float comparisons" { target *-*-* } .-1 } */
+ __analyzer_eval (f == 42.0); /* { dg-warning "TRUE" } */
}
void test_43 (void)
@@ -1061,10 +1033,8 @@ void test_51 (struct coord c)
{
struct coord d;
memcpy (&d, &c, sizeof (struct coord));
- __analyzer_eval (c.x == d.x); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
- __analyzer_eval (c.y == d.y); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ __analyzer_eval (c.x == d.x); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c.y == d.y); /* { dg-warning "TRUE" } */
}
struct big
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-13.c b/gcc/testsuite/gcc.dg/analyzer/data-model-13.c
index e7cb845..31c1896 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-13.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-13.c
@@ -14,8 +14,5 @@ void test_1 (void)
void test_2 (void)
{
global_union.ptr_val = malloc (1024); /* { dg-message "allocated here" } */
- global_union.int_val = 0;
-} /* { dg-warning "leak of '<unknown>' " } */
-/* TODO: something better than "<unknown>". */
-/* TODO: better location for the leak. */
-
+ global_union.int_val = 0; /* { dg-warning "leak of 'global_union.ptr_val' " } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-14.c b/gcc/testsuite/gcc.dg/analyzer/data-model-14.c
index f9bb540..1dbcb70 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-14.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-14.c
@@ -1,6 +1,3 @@
-/* FIXME: we shouldn't need this. */
-/* { dg-additional-options "-fanalyzer-fine-grained" } */
-
#include <stdlib.h>
void *global_ptr;
@@ -8,14 +5,12 @@ void *global_ptr;
void test_1 (int i)
{
global_ptr = malloc (1024); /* { dg-message "allocated here" } */
- *(int *)&global_ptr = i; /* { dg-warning "leak of '<unknown>'" } */
- // TODO: something better than "<unknown>" here ^^^
+ *(int *)&global_ptr = i; /* { dg-warning "leak of 'global_ptr'" } */
}
void test_2 (int i)
{
- void *p = malloc (1024); /* { dg-message "allocated here" "" { xfail *-*-* } } */
- // TODO(xfail)
+ void *p = malloc (1024); /* { dg-message "allocated here" } */
global_ptr = p;
*(int *)&p = i;
p = global_ptr;
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-16.c b/gcc/testsuite/gcc.dg/analyzer/data-model-16.c
index a8acfbe..616d353 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-16.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-16.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target label_values } */
+
/* Labels as values. */
#include "analyzer-decls.h"
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-18.c b/gcc/testsuite/gcc.dg/analyzer/data-model-18.c
index 0a9ae9f..86e8110 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-18.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-18.c
@@ -16,7 +16,5 @@ void test (int *p, int i, int j)
__analyzer_eval (p[3] == 42); /* { dg-warning "UNKNOWN" } */
__analyzer_eval (p[i] == 17); /* { dg-warning "TRUE" } */
- __analyzer_eval (p[j] == 17); /* { dg-warning "UNKNOWN" "desired" { xfail *-*-* } } */
- /* { dg-bogus "TRUE" "status quo" { xfail *-*-* } .-1 } */
- // FIXME(xfails) ^^^
+ __analyzer_eval (p[j] == 17); /* { dg-warning "UNKNOWN" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-20.c b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c
new file mode 100644
index 0000000..8fdbb6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-20.c
@@ -0,0 +1,25 @@
+/* { dg-additional-options "-Wno-analyzer-too-complex" } */
+
+#include <stdlib.h>
+
+struct foo { int dummy; };
+
+struct foo **
+test (int n) {
+ struct foo **arr;
+ int i;
+
+ if ((arr = (struct foo **)malloc(n * sizeof(struct foo *))) == NULL)
+ return NULL;
+
+ for (i = 0; i < n; i++) {
+ if ((arr[i] = (struct foo *)malloc(sizeof(struct foo))) == NULL) {
+ for (; i >= 0; i++) {
+ free(arr[i]); /* { dg-bogus "double-'free'" } */
+ }
+ free(arr);
+ return NULL;
+ }
+ }
+ return arr;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-5.c b/gcc/testsuite/gcc.dg/analyzer/data-model-5.c
index 5cf3347..2135c70 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-5.c
@@ -90,11 +90,20 @@ void unref (base_obj *obj)
{
if (--obj->ob_refcnt == 0) /* { dg-bogus "dereference of uninitialized pointer 'obj'" } */
obj->ob_type->tp_dealloc (obj);
+ /* { dg-warning "dereference of NULL 'obj'" "deref of NULL" { target *-*-* } .-2 } */
+ /* FIXME: ideally we wouldn't issue this, as we've already issued a
+ warning about str_obj which is now in the "stop" state; the cast
+ confuses things. */
}
void test_1 (const char *str)
{
base_obj *obj = new_string_obj (str);
- //__analyzer_dump();
unref (obj);
-} /* { dg-bogus "leak" } */
+} /* { dg-bogus "leak" "" { xfail *-*-* } } */
+/* XFAIL (false leak):
+ Given that we only know "len" symbolically, this line:
+ str_obj->str_buf[len] = '\0';
+ is a symbolic write which could clobber the ob_type or ob_refcnt.
+ It reports a leak when following the path where the refcount is clobbered
+ to be a value that leads to the deallocator not being called. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-5b.c b/gcc/testsuite/gcc.dg/analyzer/data-model-5b.c
index 76e351d..cd6a4df 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-5b.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-5b.c
@@ -86,8 +86,10 @@ void test_1 (const char *str)
//__analyzer_dump();
if (obj)
unref (obj);
-} /* { dg-bogus "leak of 'obj'" "" { xfail *-*-* } } */
-/* TODO(xfail): the false leak report involves the base_obj.ob_refcnt
- being 1, but the string_obj.str_base.ob_refcnt being unknown (when
- they ought to be the same region), thus allowing for a path in which
- the object is allocated but not freed. */
+} /* { dg-bogus "leak" "" { xfail *-*-* } } */
+/* XFAIL (false leak):
+ Given that we only know "len" symbolically, this line:
+ str_obj->str_buf[len] = '\0';
+ is a symbolic write which could clobber the ob_type or ob_refcnt.
+ It reports a leak when following the path where the refcount is clobbered
+ to be a value that leads to the deallocator not being called. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-5c.c b/gcc/testsuite/gcc.dg/analyzer/data-model-5c.c
index 3aba7bd..ad4e1d2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-5c.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-5c.c
@@ -75,9 +75,10 @@ void test_1 (const char *str)
string_obj *obj = new_string_obj (str);
if (obj)
unref (obj);
-} /* { dg-bogus "leak of 'obj'" "" { xfail *-*-* } } */
-/* TODO(xfail): the false leak report involves the base_obj.ob_refcnt
- being 1, but the string_obj.str_base.ob_refcnt being unknown (when
- they ought to be the same region), thus allowing for a path in which
- the object is allocated but not freed. */
-
+} /* { dg-bogus "leak" "" { xfail *-*-* } } */
+/* XFAIL (false leak):
+ Given that we only know "len" symbolically, this line:
+ str_obj->str_buf[len] = '\0';
+ is a symbolic write which could clobber the ob_type or ob_refcnt.
+ It reports a leak when following the path where the refcount is clobbered
+ to be a value that leads to the deallocator not being called. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-5d.c b/gcc/testsuite/gcc.dg/analyzer/data-model-5d.c
index 8c7bfa9..b4d77a9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-5d.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-5d.c
@@ -5,34 +5,33 @@
#include <stdlib.h>
#include "analyzer-decls.h"
-typedef struct base_obj base_obj;
-typedef struct type_obj type_obj;
-typedef struct string_obj string_obj;
-
-struct base_obj
+typedef struct base_obj
{
struct type_obj *ob_type;
int ob_refcnt;
-};
+} base_obj;
-struct type_obj
+typedef struct type_obj
{
base_obj tp_base;
-};
+ void (*tp_dealloc) (base_obj *);
+} type_obj;
-struct string_obj
+typedef struct boxed_int_obj
{
- base_obj str_base;
- size_t str_len;
- char str_buf[];
-};
+ base_obj int_base;
+ int int_val;
+} boxed_int_obj;
+
+extern void int_del (base_obj *);
type_obj type_type = {
- { &type_type, 1},
+ { &type_type, 1}
};
-type_obj str_type = {
- { &str_type, 1},
+type_obj boxed_int_type = {
+ { &type_type, 1},
+ int_del
};
base_obj *alloc_obj (type_obj *ob_type, size_t sz)
@@ -45,20 +44,28 @@ base_obj *alloc_obj (type_obj *ob_type, size_t sz)
return obj;
}
+base_obj *new_int_obj (int val)
+{
+ boxed_int_obj *int_obj
+ = (boxed_int_obj *)alloc_obj (&boxed_int_type, sizeof (boxed_int_obj));
+ if (!int_obj)
+ return NULL;
+ int_obj->int_val = val;
+ return (base_obj *)int_obj;
+}
+
void unref (base_obj *obj)
{
- //__analyzer_dump();
if (--obj->ob_refcnt == 0)
- free (obj);
+ obj->ob_type->tp_dealloc (obj);
}
-void test_1 ()
+void test_1 (const char *str)
{
- base_obj *obj = alloc_obj (&str_type, sizeof (string_obj));
- if (obj)
- {
- __analyzer_dump_num_heap_regions (); /* { dg-warning "num heap regions: '1'" } */
- unref (obj);
- __analyzer_dump_num_heap_regions (); /* { dg-warning "num heap regions: '0'" } */
- }
-}
+ base_obj *obj = new_int_obj (42);
+ if (!obj)
+ return;
+ __analyzer_eval (((boxed_int_obj *)obj)->int_val == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (obj->ob_refcnt == 1); /* { dg-warning "TRUE" } */
+ unref (obj);
+} /* { dg-bogus "leak" "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-6.c b/gcc/testsuite/gcc.dg/analyzer/data-model-6.c
deleted file mode 100644
index 78a797e..0000000
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-6.c
+++ /dev/null
@@ -1,14 +0,0 @@
-#include <stdlib.h>
-#include "analyzer-decls.h"
-
-/* Verify that we don't accumulate state after a malloc/free pair. */
-
-void test (void)
-{
- void *ptr;
- __analyzer_dump_num_heap_regions (); /* { dg-warning "num heap regions: '0'" } */
- ptr = malloc (1024);
- __analyzer_dump_num_heap_regions (); /* { dg-warning "num heap regions: '1'" } */
- free (ptr);
- __analyzer_dump_num_heap_regions (); /* { dg-warning "num heap regions: '0'" } */
-}
diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-8.c b/gcc/testsuite/gcc.dg/analyzer/data-model-8.c
index 939b4c2..3e69d0f 100644
--- a/gcc/testsuite/gcc.dg/analyzer/data-model-8.c
+++ b/gcc/testsuite/gcc.dg/analyzer/data-model-8.c
@@ -21,6 +21,5 @@ void test (void)
struct base *bp = (struct base *)&s;
- __analyzer_eval (bp->i == 3); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ __analyzer_eval (bp->i == 3); /* { dg-warning "TRUE" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/describe-1.c b/gcc/testsuite/gcc.dg/analyzer/describe-1.c
new file mode 100644
index 0000000..bc57c6e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/describe-1.c
@@ -0,0 +1,11 @@
+/* Smoketest for __analyzer_describe. */
+
+#include "analyzer-decls.h"
+
+void test (int i)
+{
+ __analyzer_describe (0, 42); /* { dg-warning "svalue: '\\(int\\)42'" } */
+ __analyzer_describe (0, i); /* { dg-warning "svalue: 'INIT_VAL\\(i.*\\)'" } */
+ __analyzer_describe (0, &i); /* { dg-warning "svalue: '&i'" } */
+ /* Further cases would risk overspecifying things. */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/dot-output.c b/gcc/testsuite/gcc.dg/analyzer/dot-output.c
index 7b69c62..ff418b1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/dot-output.c
+++ b/gcc/testsuite/gcc.dg/analyzer/dot-output.c
@@ -18,8 +18,7 @@ int *test (int *buf, int n, int *out)
/* A loop, to ensure we have phi nodes. */
for (i = 0; i < n; i++)
- result[i] = buf[i] + i; /* { dg-warning "possibly-NULL" "" { xfail *-*-* } } */
- /* TODO(xfail): why isn't the warning appearing? */
+ result[i] = buf[i] + i; /* { dg-warning "possibly-NULL" } */
/* Example of a "'" (to test quoting). */
*out = some_call (i, 'a');
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-1.c b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
index 6b62e8e..9b95afd 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-1.c
@@ -47,7 +47,7 @@ void test (void)
{
default:
case 0:
- *pp = malloc (16);
+ *pp = malloc (16); /* { dg-warning "leak" } */
break;
case 1:
free (*pp);
diff --git a/gcc/testsuite/gcc.dg/analyzer/explode-2.c b/gcc/testsuite/gcc.dg/analyzer/explode-2.c
index d786aa9..70d8fec 100644
--- a/gcc/testsuite/gcc.dg/analyzer/explode-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/explode-2.c
@@ -19,31 +19,31 @@ void test (void)
{
default:
case 0:
- p0 = malloc (16);
+ p0 = malloc (16); /* { dg-warning "leak" } */
break;
case 1:
- free (p0); /* { dg-warning "double-'free' of 'p0'" } */
+ free (p0); /* { dg-warning "double-'free' of 'p0'" "" { xfail *-*-* } } */
break;
case 2:
- p1 = malloc (16);
+ p1 = malloc (16); /* { dg-warning "leak" } */
break;
case 3:
- free (p1); /* { dg-warning "double-'free' of 'p1'" } */
+ free (p1); /* { dg-warning "double-'free' of 'p1'" "" { xfail *-*-* } } */
break;
case 4:
- p2 = malloc (16);
+ p2 = malloc (16); /* { dg-warning "leak" } */
break;
case 5:
- free (p2); /* { dg-warning "double-'free' of 'p2'" } */
+ free (p2); /* { dg-warning "double-'free' of 'p2'" "" { xfail *-*-* } } */
break;
case 6:
- p3 = malloc (16);
+ p3 = malloc (16); /* { dg-warning "leak" } */
break;
case 7:
- free (p3); /* { dg-warning "double-'free' of 'p3'" } */
+ free (p3); /* { dg-warning "double-'free' of 'p3'" "" { xfail *-*-* } } */
break;
}
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-1.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-1.c
new file mode 100644
index 0000000..f2a8a4c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-1.c
@@ -0,0 +1,62 @@
+#include "analyzer-decls.h"
+
+void test_1 (void)
+{
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+void test_2 (int flag)
+{
+ if (flag)
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+void test_3 (int flag)
+{
+ if (flag)
+ if (!flag)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+int global_for_test_4;
+static void __attribute__((noinline)) called_by_test_4 () {}
+void test_4 (void)
+{
+ /* Verify that a state change that happens in a stmt that
+ isn't the first within its BB can affect path feasibility. */
+ global_for_test_4 = 0;
+ global_for_test_4 = 1;
+ /* Thwart the optimizer. */
+ called_by_test_4 ();
+ if (global_for_test_4)
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+/* Verify that loops don't confuse the feasibility checker. */
+
+void test_5 (void)
+{
+ for (int i = 0; i < 1024; i++)
+ {
+ }
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+/* Reproducer for an issue seen with CVE-2005-1689 (PR analyzer/96374): if we
+ take the shortest path and update state and check feasibility per-edge, we
+ can erroneously reject valid diagnostics. */
+
+int test_6 (int a, int b)
+{
+ int problem = 0;
+ if (a)
+ problem = 1;
+ if (b)
+ {
+ if (!problem)
+ problem = 2;
+ __analyzer_dump_path (); /* { dg-message "path" "" { xfail *-*-* } } */
+ /* XFAIL is PR analyzer/96374. */
+ }
+ return problem;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-2.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-2.c
new file mode 100644
index 0000000..9fe62d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/feasibility-2.c
@@ -0,0 +1,20 @@
+/* Verify that -fno-analyzer-feasibility works. */
+/* { dg-additional-options "-fno-analyzer-feasibility" } */
+
+#include "analyzer-decls.h"
+
+void test_1 (int flag)
+{
+ int a;
+ if (flag)
+ a = 1;
+ else
+ a = 2;
+
+ if (a == 1) /* (can only be the case when "flag" was true above). */
+ if (!flag)
+ {
+ __analyzer_dump_path (); /* { dg-message "note: path" "path diag" } */
+ /* { dg-message "infeasible" "infeasibility event" { target *-*-* } .-1 } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/first-field-1.c b/gcc/testsuite/gcc.dg/analyzer/first-field-1.c
new file mode 100644
index 0000000..8b71e1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/first-field-1.c
@@ -0,0 +1,24 @@
+#include "analyzer-decls.h"
+
+typedef struct base_obj
+{
+ int m_first;
+ int m_second;
+} base_obj;
+
+typedef struct sub_obj
+{
+ base_obj base;
+} sub_obj;
+
+void test (sub_obj *sub)
+{
+ sub->base.m_first = 1;
+ sub->base.m_second = 2;
+ __analyzer_eval (sub->base.m_first == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (sub->base.m_second == 2); /* { dg-warning "TRUE" } */
+
+ base_obj *base = (struct base_obj *)sub;
+ __analyzer_eval (base->m_first == 1); /* { dg-warning "TRUE" } */
+ __analyzer_eval (base->m_second == 2); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/first-field-2.c b/gcc/testsuite/gcc.dg/analyzer/first-field-2.c
new file mode 100644
index 0000000..2fb98d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/first-field-2.c
@@ -0,0 +1,33 @@
+/* A toy re-implementation of CPython's object model. */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "analyzer-decls.h"
+
+typedef struct base_obj base_obj;
+typedef struct string_obj string_obj;
+
+struct base_obj
+{
+ int ob_refcnt;
+};
+
+struct string_obj
+{
+ base_obj str_base;
+ size_t str_len;
+ char str_buf[];
+};
+
+base_obj *alloc_obj (const char *str)
+{
+ size_t len = strlen (str);
+ base_obj *obj = (base_obj *)malloc (sizeof (string_obj) + len + 1);
+ if (!obj)
+ return NULL;
+ obj->ob_refcnt = 1;
+ string_obj *str_obj = (string_obj *)obj;
+ __analyzer_eval (str_obj->str_base.ob_refcnt == 1); /* { dg-warning "TRUE" } */
+ return obj;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/getchar-1.c b/gcc/testsuite/gcc.dg/analyzer/getchar-1.c
new file mode 100644
index 0000000..25595e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/getchar-1.c
@@ -0,0 +1,19 @@
+#include <stdio.h>
+#include "analyzer-decls.h"
+
+int test_1 (void)
+{
+ int c = getchar ();
+ return c;
+}
+
+int glob_2;
+int test_2 (void)
+{
+ int c;
+ glob_2 = 42;
+ __analyzer_eval (glob_2 == 42); /* { dg-warning "TRUE" } */
+ c = getchar ();
+ __analyzer_eval (glob_2 == 42); /* { dg-warning "TRUE" } */
+ return c;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/init.c b/gcc/testsuite/gcc.dg/analyzer/init.c
new file mode 100644
index 0000000..e51d88e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/init.c
@@ -0,0 +1,136 @@
+/* Tests of brace-enclosed initializers
+ Some of these use the CONSTRUCTOR tree code, but it appears
+ only for a full zero-init; it appears that by the time the analyzer
+ runs that this initialization has been converted into field-wise
+ gimple assign stmts, with just "zero-init everything" CONSTRUCTORs
+ and "clobber" CONSTRUCTORs. */
+
+#include "analyzer-decls.h"
+
+struct coord
+{
+ int x;
+ int y;
+};
+
+struct tri
+{
+ struct coord v[3];
+};
+
+union iap
+{
+ int i;
+ void *p;
+};
+
+void test_1 (void)
+{
+ struct coord c = {3, 4};
+ __analyzer_eval (c.x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c.y == 4); /* { dg-warning "TRUE" } */
+}
+
+void test_2 (void)
+{
+ struct coord c = {3};
+ __analyzer_eval (c.x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c.y == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_3 (void)
+{
+ struct coord c = {};
+ __analyzer_eval (c.x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c.y == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_4 (void)
+{
+ int c[2] = {3, 4};
+ __analyzer_eval (c[0] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1] == 4); /* { dg-warning "TRUE" } */
+}
+
+void test_5 (void)
+{
+ int c[2] = {3};
+ __analyzer_eval (c[0] == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1] == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_6 (void)
+{
+ int c[2] = {};
+ __analyzer_eval (c[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1] == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_7 (void)
+{
+ struct coord c[2] = {{3, 4}, {5, 6}};
+ __analyzer_eval (c[0].x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[0].y == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].y == 6); /* { dg-warning "TRUE" } */
+}
+
+void test_8 (void)
+{
+ struct coord c[2] = {{3}, {5}};
+ __analyzer_eval (c[0].x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[0].y == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].y == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_9 (void)
+{
+ struct coord c[2] = {{}, {}};
+ __analyzer_eval (c[0].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[0].y == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].y == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_10 (void)
+{
+ struct coord c[2] = {{.y = 4, .x = 3}, {5, 6}};
+ __analyzer_eval (c[0].x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[0].y == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].y == 6); /* { dg-warning "TRUE" } */
+}
+
+void test_11 (void)
+{
+ struct coord c[2] = {{.y = 4}, {5, 6}};
+ __analyzer_eval (c[0].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[0].y == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c[1].y == 6); /* { dg-warning "TRUE" } */
+}
+
+void test_12 (void)
+{
+ struct tri t = {};
+ __analyzer_eval (t.v[0].x == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[2].y == 0); /* { dg-warning "TRUE" } */
+}
+
+void test_13 (void)
+{
+ struct tri t = {3, 4, 5, 6, 7, 8};
+ __analyzer_eval (t.v[0].x == 3); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[0].y == 4); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[1].x == 5); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[1].y == 6); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[2].x == 7); /* { dg-warning "TRUE" } */
+ __analyzer_eval (t.v[2].y == 8); /* { dg-warning "TRUE" } */
+}
+
+void test_14 (void)
+{
+ union iap u = {};
+ __analyzer_eval (u.i == 0); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-2.c b/gcc/testsuite/gcc.dg/analyzer/leak-2.c
new file mode 100644
index 0000000..bba3e81
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/leak-2.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+void *ptr;
+
+void *test (void)
+{
+ ptr = malloc (1024);
+ ptr = NULL; /* { dg-warning "leak of 'ptr'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c
new file mode 100644
index 0000000..2b03527
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1-with-iter-obj.c
@@ -0,0 +1,74 @@
+#include <stdlib.h>
+
+#include "analyzer-decls.h"
+
+struct iter
+{
+ int start;
+ int end;
+ int step;
+ int val;
+};
+
+struct iter * __attribute__((noinline))
+iter_new (int start, int end, int step)
+{
+ struct iter *it = (struct iter *)malloc (sizeof (struct iter));
+ if (!it)
+ abort ();
+ it->start = start;
+ it->end = end;
+ it->step = step;
+ it->val = start;
+ return it;
+}
+
+int __attribute__((noinline))
+iter_done_p (struct iter *it)
+{
+ return it->val >= it->end;
+}
+
+void __attribute__((noinline))
+iter_next (struct iter *it)
+{
+ it->val += it->step;
+}
+
+/* Example of an iterator object, to see how well we cope with a well-disguised
+ iteration from 0 to n with a step of 1. */
+
+void test(int n)
+{
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ struct iter *it = iter_new (0, n, 1);
+ while (!iter_done_p (it))
+ {
+ __analyzer_eval (it->val < n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ __analyzer_eval (it->val == 0); /* { dg-warning "TRUE" "true on 1st iter" } */
+ /* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
+ /* TODO: should we ought to figure out i > 0 after 1st iteration? */
+
+ __analyzer_eval (it->val >= 0); /* { dg-warning "TRUE" } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
+ iter_next (it);
+ }
+
+ __analyzer_eval (it->val >= n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ __analyzer_eval (it->val == n); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
+
+ free (it);
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ // TODO: why 2 enodes here, rather than 1
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c
new file mode 100644
index 0000000..d49ed13
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-0-up-to-n-by-1.c
@@ -0,0 +1,31 @@
+#include "analyzer-decls.h"
+
+void test(int n)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = 0; i < n; i++) {
+ __analyzer_eval (i < n); /* { dg-warning "TRUE" } */
+ /* (should report TRUE twice). */
+
+ __analyzer_eval (i == 0); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ __analyzer_eval (i >= 0); /* { dg-warning "TRUE" } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_eval (i >= n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ __analyzer_eval (i == n); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-2a.c b/gcc/testsuite/gcc.dg/analyzer/loop-2a.c
index a392ffc..16b6449 100644
--- a/gcc/testsuite/gcc.dg/analyzer/loop-2a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-2a.c
@@ -14,10 +14,7 @@ void test(void)
for (u.i=0; u.i<256; u.i++) {
- __analyzer_eval (u.i < 256); /* { dg-warning "TRUE" "1st" } */
- /* { dg-warning "TRUE" "2nd" { xfail *-*-* } .-1 } */
- /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-2 } */
- /* (should report TRUE twice). */
+ __analyzer_eval (u.i < 256); /* { dg-warning "TRUE" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
@@ -26,11 +23,10 @@ void test(void)
/* TODO(xfail^^^): we're only capturing the first iteration, so
we erroneously get i == 0. */
- //__analyzer_eval (u.i >= 0); /* { d-todo-g-warning "TRUE" } */
+ __analyzer_eval (u.i >= 0); /* { dg-warning "TRUE" } */
}
- __analyzer_eval (u.i >= 256); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ __analyzer_eval (u.i >= 256); /* { dg-warning "TRUE" } */
__analyzer_eval (u.i == 256); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-3.c b/gcc/testsuite/gcc.dg/analyzer/loop-3.c
index 1d01771..0bcf707 100644
--- a/gcc/testsuite/gcc.dg/analyzer/loop-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-3.c
@@ -6,11 +6,8 @@ void test(int c)
char *buffer = (char*)malloc(256);
for (i=0; i<255; i++) {
- buffer[i] = c; /* { dg-warning "use after 'free' of 'buffer'" } */
- /* BUG: the malloc could have failed
- TODO: the checker doesn't yet pick up on this, perhaps
- due to the pointer arithmetic not picking up on the
- state */
+ buffer[i] = c; /* { dg-warning "use after 'free' of 'buffer'" "use after free" { xfail *-*-* } } */
+ /* { dg-warning "possibly-NULL 'buffer'" "deref of unchecked" { target *-*-* } .-1 } */
free(buffer); /* { dg-warning "double-'free' of 'buffer'" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-4.c b/gcc/testsuite/gcc.dg/analyzer/loop-4.c
index e5767de..b66a345 100644
--- a/gcc/testsuite/gcc.dg/analyzer/loop-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-4.c
@@ -1,6 +1,3 @@
-// FIXME:
-/* { dg-additional-options "-fno-analyzer-state-purge" } */
-
/* Example of nested loops. */
#include "analyzer-decls.h"
@@ -13,8 +10,7 @@ void test(void)
for (i=0; i<256; i++) {
- __analyzer_eval (i >= 0); /* { dg-warning "TRUE" "true" } */
- /* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
+ __analyzer_eval (i >= 0); /* { dg-warning "TRUE" } */
__analyzer_eval (i < 256); /* { dg-warning "TRUE" } */
@@ -23,7 +19,9 @@ void test(void)
__analyzer_eval (j >= 0); /* { dg-warning "TRUE" "true" } */
/* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
- __analyzer_eval (j < 256); /* { dg-warning "TRUE" } */
+ __analyzer_eval (j < 256); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
@@ -32,7 +30,8 @@ void test(void)
__analyzer_eval (k >= 0); /* { dg-warning "TRUE" "true" } */
/* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
- __analyzer_eval (k < 256); /* { dg-warning "TRUE" } */
+ __analyzer_eval (k < 256); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "4 processed enodes" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c b/gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c
new file mode 100644
index 0000000..553cd2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-n-down-to-1-by-1.c
@@ -0,0 +1,35 @@
+#include "analyzer-decls.h"
+
+void test(int n)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = n; i > 0; i--) {
+ __analyzer_eval (i > 0); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_eval (i == n); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ __analyzer_eval (i <= n); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "TRUE" "2nd" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i >= 0 for all iterations. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_eval (i <= 0); /* { dg-warning "TRUE" "true" } */
+
+
+ __analyzer_eval (i == 0); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c b/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c
new file mode 100644
index 0000000..3513bf4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-1.c
@@ -0,0 +1,35 @@
+#include "analyzer-decls.h"
+
+void test(int start, int end, int step)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = start; i > end; i --) {
+ __analyzer_eval (i > end); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_eval (i == start); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ __analyzer_eval (i <= start); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_eval (i >= end); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ // FIXME: do we know this? What if we overshoot?
+ __analyzer_eval (i == end); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c b/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c
new file mode 100644
index 0000000..2692c50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-start-down-to-end-by-step.c
@@ -0,0 +1,30 @@
+#include "analyzer-decls.h"
+
+void test(int start, int end, int step)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = start; i > end; i -= step) {
+ __analyzer_eval (i > end); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_eval (i == start); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ /* We don't know the direction of step. */
+ __analyzer_eval (i <= start); /* { dg-warning "TRUE" "true" } */
+ /* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_eval (i <= end); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c b/gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c
new file mode 100644
index 0000000..3fc1362
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-start-to-end-by-step.c
@@ -0,0 +1,36 @@
+#include "analyzer-decls.h"
+
+void test(int start, int end, int step)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = start; i < end; i += step) {
+ __analyzer_eval (i < end); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_eval (i == start); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ /* We don't know the direction of step. */
+ __analyzer_eval (i >= start); /* { dg-warning "TRUE" "true" } */
+ /* { dg-warning "UNKNOWN" "unknown" { target *-*-* } .-1 } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ // FIXME: do we know this? What about direction of step?
+ __analyzer_eval (i >= end); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ // FIXME: do we know this? What if we overshoot?
+ __analyzer_eval (i == end); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= 256, rather than i == 256. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c b/gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c
new file mode 100644
index 0000000..5e21890
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/loop-start-up-to-end-by-1.c
@@ -0,0 +1,32 @@
+#include "analyzer-decls.h"
+
+void test(int start, int end)
+{
+ int i;
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (i = start; i < end; i++) {
+ __analyzer_eval (i < end); /* { dg-warning "TRUE" "true" } */
+
+ __analyzer_eval (i == start); /* { dg-warning "TRUE" "1st" } */
+ /* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
+ /* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
+
+ __analyzer_eval (i >= start); /* { dg-warning "TRUE" "true" } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+ /* TODO(xfail^^^): should report TRUE twice. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_eval (i >= end); /* { dg-warning "TRUE" "true" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
+
+ __analyzer_eval (i == end); /* { dg-warning "TRUE" "desired" { xfail *-*-* } } */
+ /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-1 } */
+ /* TODO(xfail^^^): it only figures out i >= end, rather than i == end. */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/loop.c b/gcc/testsuite/gcc.dg/analyzer/loop.c
index 37b757b..c4cfd88 100644
--- a/gcc/testsuite/gcc.dg/analyzer/loop.c
+++ b/gcc/testsuite/gcc.dg/analyzer/loop.c
@@ -1,5 +1,3 @@
-/* { dg-additional-options "-fno-analyzer-state-purge" } */
-
#include "analyzer-decls.h"
void test(void)
@@ -12,15 +10,12 @@ void test(void)
__analyzer_eval (i < 256); /* { dg-warning "TRUE" } */
/* (should report TRUE twice). */
- __analyzer_eval (i == 0); /* { dg-warning "TRUE" "1st" } */
+ __analyzer_eval (i == 0); /* { dg-warning "TRUE" } */
/* { dg-warning "FALSE" "2nd" { xfail *-*-* } .-1 } */
/* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
/* TODO(xfail^^^): ideally we ought to figure out i > 0 after 1st iteration. */
- __analyzer_eval (i >= 0); /* { dg-warning "TRUE" "1st" } */
- /* { dg-warning "TRUE" "2nd" { xfail *-*-* } } */
- /* { dg-warning "UNKNOWN" "status quo" { target *-*-* } .-2 } */
- /* TODO(xfail^^^): ideally we ought to figure out i >= 0 for all iterations. */
+ __analyzer_eval (i >= 0); /* { dg-warning "TRUE" } */
__analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
index 3024e546..c3e1330 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-1.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target alloca } */
+
#include <alloca.h>
#include <stdlib.h>
@@ -358,7 +360,7 @@ void test_30 (void)
struct link tmp;
tmp.m_ptr = (struct link *)malloc (sizeof (struct link)); /* { dg-message "allocated here" } */
} /* { dg-warning "leak of 'tmp.m_ptr'" } */
-/* { dg-bogus "leak of '<unknown>'" "" { xfail *-*-* } .-1 } */
+/* { dg-bogus "leak of '<unknown>'" "leak of unknown" { target *-*-* } .-1 } */
void test_31 (void)
{
@@ -366,7 +368,7 @@ void test_31 (void)
void *ptr = malloc (sizeof (struct link)); /* { dg-message "allocated here" } */
tmp.m_ptr = (struct link *)ptr;
} /* { dg-warning "leak of 'ptr'" } */
-/* { dg-bogus "leak of 'tmp.m_ptr'" "" { xfail *-*-* } .-1 } */
+/* { dg-bogus "leak of 'tmp.m_ptr'" "" { target *-*-* } .-1 } */
void test_32 (void)
{
@@ -505,8 +507,7 @@ void test_42c (void)
void *p = malloc (1024);
void *q = p + 64;
free (q - 64); /* this is probably OK. */
-} /* { dg-bogus "leak of 'p'" "" { xfail *-*-* } } */
-// TODO(xfail)
+} /* { dg-bogus "leak of 'p'" } */
#if 0
void test_31 (void *p)
@@ -529,10 +530,8 @@ struct link global_link;
void test_43 (void)
{
global_link.m_ptr = malloc (sizeof (struct link)); /* { dg-message "allocated here" } */
- global_link.m_ptr = NULL;
-} /* { dg-warning "leak of '<unknown>'" } */
-/* TODO: should be more precise than just '<unknown>', and
- ideally would be at the assigment to NULL. */
+ global_link.m_ptr = NULL; /* { dg-warning "leak of 'global_link.m_ptr'" } */
+}
struct link *global_ptr;
@@ -589,3 +588,16 @@ void test_48 (void)
int *p = NULL; /* { dg-message "'p' is NULL" } */
*p = 1; /* { dg-warning "dereference of NULL 'p'" } */
}
+
+/* As test_48, but where the assignment of NULL is not at the start of a BB. */
+
+int test_49 (int i)
+{
+ int *p;
+ int x;
+
+ x = i * 2;
+ p = NULL; /* { dg-message "'p' is NULL" } */
+ *p = 1; /* { dg-warning "dereference of NULL 'p'" } */
+ return x;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-4.c b/gcc/testsuite/gcc.dg/analyzer/malloc-4.c
index c9c275a..908bb28 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-4.c
@@ -10,11 +10,11 @@ void *hv (struct foo **tm)
*tm = p;
if (!p)
abort ();
- return p; /* { dg-warning "leak of 'tm'" } */
+ return p;
}
void a5 (void)
{
struct bar *qb = NULL;
hv (&qb);
-} /* { dg-warning "leak of '\\(struct foo \\*\\)qb'" } */
+} /* { dg-warning "leak of 'qb'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c b/gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c
new file mode 100644
index 0000000..a8c85a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-in-loop.c
@@ -0,0 +1,19 @@
+#include <stdlib.h>
+#include "analyzer-decls.h"
+
+extern void foo (int *);
+
+void test (int n)
+{
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ for (int i = 0; i < n; i++)
+ {
+ int *ptr = (int *)malloc (sizeof (int) * i);
+ foo (ptr);
+ free (ptr);
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ }
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c
index f86e8ac..580862b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-double-free.c
@@ -1,6 +1,6 @@
/* Example of a multilevel wrapper around malloc/free, with a double-'free'. */
-/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fanalyzer-verbose-state-changes -fdiagnostics-show-caret" } */
+/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
#include <stdlib.h>
@@ -61,111 +61,133 @@ void test (int i)
| | |
| | (2) calling 'make_boxed_int' from 'test'
|
- +--> 'make_boxed_int': events 3-6
+ +--> 'make_boxed_int': events 3-4
|
| NN | make_boxed_int (int i)
| | ^~~~~~~~~~~~~~
| | |
| | (3) entry to 'make_boxed_int'
- |......
+ | NN | {
+ | NN | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+ | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | | |
+ | | (4) calling 'wrapped_malloc' from 'make_boxed_int'
+ |
+ +--> 'wrapped_malloc': events 5-6
+ |
+ | NN | void *wrapped_malloc (size_t size)
+ | | ^~~~~~~~~~~~~~
+ | | |
+ | | (5) entry to 'wrapped_malloc'
+ | NN | {
+ | NN | return malloc (size);
+ | | ~~~~~~~~~~~~~
+ | | |
+ | | (6) allocated here
+ |
+ <------+
+ |
+ 'make_boxed_int': events 7-10
+ |
+ | NN | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+ | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ | | |
+ | | (7) returning to 'make_boxed_int' from 'wrapped_malloc'
| NN | if (!result)
- | | ~
+ | | ~
| | |
- | | (4) following 'false' branch (when 'result' is non-NULL)...
+ | | (8) assuming 'result' is non-NULL
+ | | (9) following 'false' branch (when 'result' is non-NULL)...
| NN | abort ();
| NN | result->i = i;
- | | ~~~~~~~~~~~~~
+ | | ~~~~~~~~~~~~~
| | |
- | | (5) ...to here
- | NN | return result;
- | | ~~~~~~
- | | |
- | | (6) state of '<return-value>': 'start' -> 'nonnull' (origin: NULL)
+ | | (10) ...to here
|
<------+
|
- 'test': events 7-8
+ 'test': events 11-12
|
| NN | boxed_int *obj = make_boxed_int (i);
| | ^~~~~~~~~~~~~~~~~~
| | |
- | | (7) returning to 'test' from 'make_boxed_int'
+ | | (11) returning to 'test' from 'make_boxed_int'
| NN |
| NN | free_boxed_int (obj);
| | ~~~~~~~~~~~~~~~~~~~~
| | |
- | | (8) calling 'free_boxed_int' from 'test'
+ | | (12) calling 'free_boxed_int' from 'test'
|
- +--> 'free_boxed_int': events 9-10
+ +--> 'free_boxed_int': events 13-14
|
| NN | free_boxed_int (boxed_int *bi)
| | ^~~~~~~~~~~~~~
| | |
- | | (9) entry to 'free_boxed_int'
+ | | (13) entry to 'free_boxed_int'
| NN | {
| NN | wrapped_free (bi);
| | ~~~~~~~~~~~~~~~~~
| | |
- | | (10) calling 'wrapped_free' from 'free_boxed_int'
+ | | (14) calling 'wrapped_free' from 'free_boxed_int'
|
- +--> 'wrapped_free': events 11-12
+ +--> 'wrapped_free': events 15-16
|
| NN | void wrapped_free (void *ptr)
| | ^~~~~~~~~~~~
| | |
- | | (11) entry to 'wrapped_free'
+ | | (15) entry to 'wrapped_free'
| NN | {
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
- | | (12) first 'free' here (state of 'ptr': 'nonnull' -> 'freed', origin: NULL)
+ | | (16) first 'free' here
|
<------+
|
- 'free_boxed_int': event 13
+ 'free_boxed_int': event 17
|
| NN | wrapped_free (bi);
| | ^~~~~~~~~~~~~~~~~
| | |
- | | (13) returning to 'free_boxed_int' from 'wrapped_free'
+ | | (17) returning to 'free_boxed_int' from 'wrapped_free'
|
<------+
|
- 'test': events 14-15
+ 'test': events 18-19
|
| NN | free_boxed_int (obj);
| | ^~~~~~~~~~~~~~~~~~~~
| | |
- | | (14) returning to 'test' from 'free_boxed_int'
+ | | (18) returning to 'test' from 'free_boxed_int'
| NN |
| NN | free_boxed_int (obj);
| | ~~~~~~~~~~~~~~~~~~~~
| | |
- | | (15) passing freed pointer 'obj' in call to 'free_boxed_int' from 'test'
+ | | (19) passing freed pointer 'obj' in call to 'free_boxed_int' from 'test'
|
- +--> 'free_boxed_int': events 16-17
+ +--> 'free_boxed_int': events 20-21
|
| NN | free_boxed_int (boxed_int *bi)
| | ^~~~~~~~~~~~~~
| | |
- | | (16) entry to 'free_boxed_int'
+ | | (20) entry to 'free_boxed_int'
| NN | {
| NN | wrapped_free (bi);
| | ~~~~~~~~~~~~~~~~~
| | |
- | | (17) passing freed pointer 'bi' in call to 'wrapped_free' from 'free_boxed_int'
+ | | (21) passing freed pointer 'bi' in call to 'wrapped_free' from 'free_boxed_int'
|
- +--> 'wrapped_free': events 18-19
+ +--> 'wrapped_free': events 22-23
|
| NN | void wrapped_free (void *ptr)
| | ^~~~~~~~~~~~
| | |
- | | (18) entry to 'wrapped_free'
+ | | (22) entry to 'wrapped_free'
| NN | {
| NN | free (ptr);
| | ~~~~~~~~~~
| | |
- | | (19) second 'free' here; first 'free' was at (12) ('ptr' is in state 'freed')
+ | | (23) second 'free' here; first 'free' was at (16)
|
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
index a778a29..3200447 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-ipa-8-unchecked.c
@@ -1,6 +1,6 @@
/* Example of a multilevel wrapper around malloc, with an unchecked write. */
-/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fdiagnostics-show-caret -fanalyzer-verbose-state-changes" } */
+/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fanalyzer-checker=malloc -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
#include <stdlib.h>
@@ -49,7 +49,7 @@ make_boxed_int (int i)
| NN | return malloc (size);
| | ~~~~~~~~~~~~~
| | |
- | | (4) this call could return NULL (state of '<return-value>': 'start' -> 'unchecked', origin: NULL)
+ | | (4) this call could return NULL
|
<------+
|
@@ -62,6 +62,6 @@ make_boxed_int (int i)
| NN | result->i = i;
| | ~~~~~~~~~~~~~
| | |
- | | (6) 'result' could be NULL: unchecked value from (4) ('result' is in state 'unchecked')
+ | | (6) 'result' could be NULL: unchecked value from (4)
|
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
index 10b97a0..35c9385 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-8.c
@@ -1,4 +1,5 @@
/* { dg-additional-options "-fanalyzer-transitivity" } */
+/* { dg-require-effective-target alloca } */
#include <stddef.h>
#include <alloca.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c
index c5ff96e..a3cacc0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-paths-9.c
@@ -112,8 +112,7 @@ int test_3 (int x, int y)
free (ptr); /* No double-'free' warning: we've already attempted
to dereference it above. */
return *ptr; /* { dg-warning "use after 'free' of 'ptr'" "use-after-free" } */
- // TODO: two warnings here: one is from sm-malloc, the other from region model
- /* { dg-warning "leak of 'ptr'" "leak" { target *-*-* } .-2 } */
+ /* { dg-warning "leak of 'ptr'" "leak" { target *-*-* } .-1 } */
}
/* "dereference of possibly-NULL 'ptr'". */
@@ -241,59 +240,3 @@ int test_3 (int x, int y)
| | (7) 'ptr' leaks here; was allocated at (1)
|
{ dg-end-multiline-output "" } */
-
-/* "use after 'free' of 'ptr'". */
-/* { dg-begin-multiline-output "" }
- NN | *ptr = 19;
- | ~~~~~^~~~
- 'test_3': events 1-3
- |
- | NN | if (x)
- | | ^
- | | |
- | | (1) following 'true' branch (when 'x != 0')...
- | NN | free (ptr);
- | | ~~~~~~~~~~
- | | |
- | | (2) ...to here
- | NN |
- | NN | *ptr = 19;
- | | ~~~~~~~~~
- | | |
- | | (3) use after 'free' of 'ptr' here
- |
- { dg-end-multiline-output "" } */
-
-/* "use after 'free' of 'ptr'". */
-/* { dg-begin-multiline-output "" }
- NN | return *ptr;
- | ^~~~
- 'test_3': events 1-5
- |
- | NN | if (x)
- | | ^
- | | |
- | | (1) following 'false' branch (when 'x == 0')...
- |......
- | NN | *ptr = 19;
- | | ~~~~~~~~~
- | | |
- | | (2) ...to here
- |......
- | NN | if (y)
- | | ~
- | | |
- | | (3) following 'true' branch (when 'y != 0')...
- | NN | free (ptr);
- | | ~~~~~~~~~~
- | | |
- | | (4) ...to here
- | NN | to dereference it above
- | NN | return *ptr;
- | | ~~~~
- | | |
- | | (5) use after 'free' of 'ptr' here
- |
- { dg-end-multiline-output "" } */
-/* TODO: this is really a duplicate; can we either eliminate it, or
- improve the path? */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
index d47dfa8..bf77862 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-1a.c
@@ -11,7 +11,7 @@ do_stuff (int *p, int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL 'p'" } */
for (i = 0; i < n; i++)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
return sum;
@@ -48,10 +48,10 @@ int test_repeated_predicate_1 (int n)
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
- // FIXME: why 3 here?
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
- // FIXME: why 3 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -105,8 +105,8 @@ int test_explicit_flag (int n)
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
- // FIXME: why 3 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (need_to_free)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -131,8 +131,8 @@ int test_pointer_comparison (int n)
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
- // FIXME: why 3 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+
if (ptr != buf)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -169,8 +169,8 @@ int test_initial_flag (int n)
result = do_stuff (ptr, n);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ // FIXME: why 3 here?
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
index 89bd511..9001fe6 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-2.c
@@ -31,13 +31,13 @@ int test_repeated_predicate_1 (int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL" } */
for (i = 0; i < n; i++)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -65,11 +65,11 @@ int test_repeated_predicate_1a (int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL" } */
result = sum;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (n > 10)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -126,13 +126,13 @@ int test_explicit_flag (int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL" } */
for (i = 0; i < n; i++)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (need_to_free)
free (ptr); /* { dg-bogus "not on the heap" } */
@@ -160,13 +160,13 @@ int test_pointer_comparison (int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL" } */
for (i = 0; i < n; i++)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
if (ptr != buf)
free (ptr); /* { dg-bogus "not on the heap" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c
index d20a275..0196389 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/malloc-vs-local-3.c
@@ -30,16 +30,15 @@ int test_1 (int n)
int sum = 0;
int i;
for (i = 0; i < n; i++)
- p[i] = i;
+ p[i] = i; /* { dg-warning "dereference of possibly-NULL" } */
for (i = 0; i < n; i++)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
- return result; /* { dg-message "leak of 'p'" } */
- /* FIXME: should this be 'ptr'? */
+ return result; /* { dg-message "leak of 'p'|leak of 'ptr'" } */
}
/* A simpler version of the above. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c b/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c
new file mode 100644
index 0000000..f120eac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/memcpy-1.c
@@ -0,0 +1,43 @@
+#include <string.h>
+#include "analyzer-decls.h"
+
+void *test_1 (void *dst, void *src, size_t n)
+{
+ void *result = memcpy (dst, src, n);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+void *test_1a (void *dst, void *src, size_t n)
+{
+ void *result = __memcpy_chk (dst, src, n, -1);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+void test_2 (int i)
+{
+ int j;
+ memcpy (&j, &i, sizeof (int));
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
+}
+
+void test_2a (int i)
+{
+ int j;
+ __memcpy_chk (&j, &i, sizeof (int), sizeof (int));
+ __analyzer_eval (i == j); /* { dg-warning "TRUE" } */
+}
+
+void test_3 (void *src, size_t n)
+{
+ char buf[40], other[40];
+ buf[0] = 'a';
+ other[0] = 'b';
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "TRUE" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+
+ memcpy (buf, src, n);
+ __analyzer_eval (buf[0] == 'a'); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (other[0] == 'b'); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/memset-1.c b/gcc/testsuite/gcc.dg/analyzer/memset-1.c
new file mode 100644
index 0000000..5748aa1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/memset-1.c
@@ -0,0 +1,114 @@
+#include <string.h>
+#include "analyzer-decls.h"
+
+/* Zero-fill of uninitialized buffer. */
+
+void test_1 (void)
+{
+ char buf[256];
+ memset (buf, 0, 256);
+ __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
+}
+
+/* As above, but with __builtin_memset. */
+
+void test_1a (void)
+{
+ char buf[256];
+ __builtin_memset (buf, 0, 256);
+ __analyzer_eval (buf[42] == 0); /* { dg-warning "TRUE" } */
+}
+
+/* Zero-fill of partially initialized buffer. */
+
+void test_2 (void)
+{
+ char buf[256];
+ buf[42] = 'A';
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
+ memset (buf, 0, 256);
+ __analyzer_eval (buf[42] == '\0'); /* { dg-warning "TRUE" } */
+}
+
+/* A "memset" with known non-zero value. */
+
+void test_3 (int val)
+{
+ char buf[256];
+ memset (buf, 'A', 256);
+ /* We currently merely mark such regions as "unknown", so querying
+ values within them yields UNKNOWN when ideally it would be TRUE. */
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+}
+
+/* A "memset" with unknown value. */
+
+void test_4 (int val)
+{
+ char buf[256];
+ memset (buf, val, 256);
+ /* We currently merely mark such regions as "unknown", so querying
+ values within them yields UNKNOWN when ideally it would be TRUE. */
+ __analyzer_eval (buf[42] == (char)val); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+}
+
+/* A "memset" with unknown num bytes. */
+
+void test_5 (int n)
+{
+ char buf[256];
+ buf[42] = 'A';
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
+ memset (buf, 0, n);
+
+ /* We can't know if buf[42] was written to or not. */
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
+}
+
+/* As test_5, but with "__builtin___memset_chk". */
+
+void test_5a (int n)
+{
+ char buf[256];
+ buf[42] = 'A';
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
+ __builtin___memset_chk (buf, 0, n, __builtin_object_size (buf, 0));
+
+ /* We can't know if buf[42] was written to or not. */
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (buf[42] == '\0'); /* { dg-warning "UNKNOWN" } */
+}
+
+/* A "memset" with unknown value, but with zero size. */
+
+static size_t __attribute__((noinline))
+get_zero (void)
+{
+ return 0;
+}
+
+void test_6 (int val)
+{
+ char buf[256];
+ buf[42] = 'A';
+ memset (buf, 'B', get_zero ());
+ __analyzer_eval (buf[42] == 'A'); /* { dg-warning "TRUE" } */
+}
+
+/* A "memset" of known size that's not the full buffer. */
+
+void test_7 (void)
+{
+ char buf[256];
+ buf[128] = 'A';
+ memset (buf, 0, 128);
+ /* We currently merely mark the whole region as "unknown", so querying
+ values within them yields UNKNOWN. */
+ __analyzer_eval (buf[127] == '\0'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+ __analyzer_eval (buf[128] == 'A'); /* { dg-warning "TRUE" "known nonzero" { xfail *-*-* } } */
+ /* { dg-bogus "UNKNOWN" "status quo" { xfail *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-3.c b/gcc/testsuite/gcc.dg/analyzer/paths-3.c
index 9bd3030..b5ab810 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-3.c
@@ -13,7 +13,7 @@ int test_1 (int a, int b)
else
p = malloc (32);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
if (a > 5)
{
@@ -34,7 +34,7 @@ int test_2 (int a, int b)
else
p = malloc (32);
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
if (a > 6) /* different condition */
{
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-4.c b/gcc/testsuite/gcc.dg/analyzer/paths-4.c
index 2f58763..b72e658 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-4.c
@@ -13,8 +13,8 @@ int test_1 (struct state *s)
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
while (1)
{
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
/* TODO: why does the above need an extra stmt to merge state? */
do_stuff (s, s->mode);
}
@@ -25,13 +25,13 @@ int test_2 (struct state *s)
__analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
while (1)
{
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
/* TODO: why does the above need an extra stmt to merge state? */
switch (s->mode)
{
case 0:
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
do_stuff (s, 0);
break;
case 1:
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-6.c b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
index 8220b8e..ef1a4e6 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-6.c
@@ -89,7 +89,7 @@ void test_3 (int i)
break;
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
__analyzer_eval (f == 3); /* { dg-warning "TRUE" } */
__analyzer_eval (g == 4); /* { dg-warning "TRUE" } */
__analyzer_eval (h == 5); /* { dg-warning "TRUE" } */
@@ -108,7 +108,7 @@ void test_4 (int flag)
q = malloc (256);
p = malloc (256);
}
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
free (p);
free (q);
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/paths-7.c b/gcc/testsuite/gcc.dg/analyzer/paths-7.c
index 243b963..8caaee8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/paths-7.c
+++ b/gcc/testsuite/gcc.dg/analyzer/paths-7.c
@@ -50,8 +50,7 @@ int test_2 (int flag, int *p, int n)
sum += foo (p[i]); /* { dg-bogus "uninitialized" } */
result = sum;
- __analyzer_dump_exploded_nodes (0); /* { dg-warning "5 processed enodes" } */
- // FIXME: why 5 here?
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
free (ptr); /* { dg-warning "double-'free' of 'ptr'" } */
return result;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-simplified.c b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-simplified.c
new file mode 100644
index 0000000..4a08f0f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools-simplified.c
@@ -0,0 +1,22 @@
+/* { dg-do "compile" } */
+
+/* Minimal replacement of system headers. */
+#define NULL ((void *) 0)
+typedef struct _IO_FILE FILE;
+extern FILE *fopen(const char *__restrict __filename,
+ const char *__restrict __modes);
+extern int fclose (FILE *__stream);
+
+extern void unzRepair(const char* file, const char* fileOut, const char* fileOutTmp)
+{
+ FILE* fpZip = fopen(file, "rb");
+ FILE* fpOut = fopen(fileOut, "wb");
+ FILE* fpOutCD = fopen(fileOutTmp, "wb");
+ if (fpZip != NULL && fpOut != NULL) {
+ fclose(fpOutCD);
+ fclose(fpZip);
+ fclose(fpOut);
+ }
+} /* { dg-warning "leak of FILE 'fpZip'" "leak of fpZip" } */
+ /* { dg-warning "leak of FILE 'fpOut'" "leak of fpOut" { target *-*-* } .-1 } */
+ /* { dg-warning "leak of FILE 'fpOutCD'" "leak of fpOutCD" { target *-*-* } .-2 } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c
new file mode 100644
index 0000000..88ab5bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93032-mztools.c
@@ -0,0 +1,331 @@
+/* Integration test to ensure we issue FILE * leak diagnostics for
+ this particular non-trivial case.
+ Adapted from zlib/contrib/minizip/mztools.c, with all #includes
+ removed. */
+
+/* { dg-do "compile" } */
+
+/* Minimal replacement of system headers. */
+
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *) 0)
+
+typedef struct _IO_FILE FILE;
+extern FILE *fopen(const char *__restrict __filename,
+ const char *__restrict __modes);
+extern size_t fread (void *__restrict __ptr, size_t __size,
+ size_t __n, FILE *__restrict __stream);
+extern size_t fwrite (const void *__restrict __ptr, size_t __size,
+ size_t __n, FILE *__restrict __s);
+extern int fclose (FILE *__stream);
+extern int remove (const char *__filename)
+ __attribute__ ((__nothrow__ , __leaf__));
+
+extern void *malloc (size_t __size)
+ __attribute__ ((__nothrow__ , __leaf__))
+ __attribute__ ((__malloc__));
+extern void free (void *__ptr)
+ __attribute__ ((__nothrow__ , __leaf__));
+
+extern size_t strlen (const char *__s)
+ __attribute__ ((__nothrow__ , __leaf__))
+ __attribute__ ((__pure__))
+ __attribute__ ((__nonnull__ (1)));
+
+/* Minimal replacement of zlib headers. */
+
+#define ZEXPORT
+typedef unsigned long uLong; /* 32 bits or more */
+#define Z_OK 0
+#define Z_ERRNO (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_MEM_ERROR (-4)
+
+/*
+ Additional tools for Minizip
+ Code: Xavier Roche '2004
+ License: Same as ZLIB (www.gzip.org)
+*/
+
+/* Code */
+
+#define READ_8(adr) ((unsigned char)*(adr))
+#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
+#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
+
+#define WRITE_8(buff, n) do { \
+ *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
+} while(0)
+#define WRITE_16(buff, n) do { \
+ WRITE_8((unsigned char*)(buff), n); \
+ WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
+} while(0)
+#define WRITE_32(buff, n) do { \
+ WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
+ WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
+} while(0)
+
+extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
+const char* file;
+const char* fileOut;
+const char* fileOutTmp;
+uLong* nRecovered;
+uLong* bytesRecovered;
+{
+ int err = Z_OK;
+ FILE* fpZip = fopen(file, "rb");
+ FILE* fpOut = fopen(fileOut, "wb");
+ FILE* fpOutCD = fopen(fileOutTmp, "wb");
+ if (fpZip != NULL && fpOut != NULL) {
+ int entries = 0;
+ uLong totalBytes = 0;
+ char header[30];
+ char filename[1024];
+ char extra[1024];
+ int offset = 0;
+ int offsetCD = 0;
+ while ( fread(header, 1, 30, fpZip) == 30 ) {
+ int currentOffset = offset;
+
+ /* File entry */
+ if (READ_32(header) == 0x04034b50) {
+ unsigned int version = READ_16(header + 4);
+ unsigned int gpflag = READ_16(header + 6);
+ unsigned int method = READ_16(header + 8);
+ unsigned int filetime = READ_16(header + 10);
+ unsigned int filedate = READ_16(header + 12);
+ unsigned int crc = READ_32(header + 14); /* crc */
+ unsigned int cpsize = READ_32(header + 18); /* compressed size */
+ unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
+ unsigned int fnsize = READ_16(header + 26); /* file name length */
+ unsigned int extsize = READ_16(header + 28); /* extra field length */
+ filename[0] = extra[0] = '\0';
+
+ /* Header */
+ if (fwrite(header, 1, 30, fpOut) == 30) {
+ offset += 30;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fnsize < sizeof(filename)) {
+ if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+ if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+ offset += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (extsize < sizeof(extra)) {
+ if (fread(extra, 1, extsize, fpZip) == extsize) {
+ if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+ offset += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Data */
+ {
+ int dataSize = cpsize;
+ if (dataSize == 0) {
+ dataSize = uncpsize;
+ }
+ if (dataSize > 0) {
+ char* data = malloc(dataSize);
+ if (data != NULL) {
+ if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
+ if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
+ offset += dataSize;
+ totalBytes += dataSize;
+ } else {
+ err = Z_ERRNO;
+ }
+ } else {
+ err = Z_ERRNO;
+ }
+ free(data);
+ if (err != Z_OK) {
+ break;
+ }
+ } else {
+ err = Z_MEM_ERROR;
+ break;
+ }
+ }
+ }
+
+ /* Central directory entry */
+ {
+ char header[46];
+ char* comment = "";
+ int comsize = (int) strlen(comment);
+ WRITE_32(header, 0x02014b50);
+ WRITE_16(header + 4, version);
+ WRITE_16(header + 6, version);
+ WRITE_16(header + 8, gpflag);
+ WRITE_16(header + 10, method);
+ WRITE_16(header + 12, filetime);
+ WRITE_16(header + 14, filedate);
+ WRITE_32(header + 16, crc);
+ WRITE_32(header + 20, cpsize);
+ WRITE_32(header + 24, uncpsize);
+ WRITE_16(header + 28, fnsize);
+ WRITE_16(header + 30, extsize);
+ WRITE_16(header + 32, comsize);
+ WRITE_16(header + 34, 0); /* disk # */
+ WRITE_16(header + 36, 0); /* int attrb */
+ WRITE_32(header + 38, 0); /* ext attrb */
+ WRITE_32(header + 42, currentOffset);
+ /* Header */
+ if (fwrite(header, 1, 46, fpOutCD) == 46) {
+ offsetCD += 46;
+
+ /* Filename */
+ if (fnsize > 0) {
+ if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
+ offsetCD += fnsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ break;
+ }
+
+ /* Extra field */
+ if (extsize > 0) {
+ if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
+ offsetCD += extsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
+ offsetCD += comsize;
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+
+ } else {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+
+ /* Success */
+ entries++;
+
+ } else {
+ break;
+ }
+ }
+
+ /* Final central directory */
+ {
+ int entriesZip = entries;
+ char header[22];
+ char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
+ int comsize = (int) strlen(comment);
+ if (entriesZip > 0xffff) {
+ entriesZip = 0xffff;
+ }
+ WRITE_32(header, 0x06054b50);
+ WRITE_16(header + 4, 0); /* disk # */
+ WRITE_16(header + 6, 0); /* disk # */
+ WRITE_16(header + 8, entriesZip); /* hack */
+ WRITE_16(header + 10, entriesZip); /* hack */
+ WRITE_32(header + 12, offsetCD); /* size of CD */
+ WRITE_32(header + 16, offset); /* offset to CD */
+ WRITE_16(header + 20, comsize); /* comment */
+
+ /* Header */
+ if (fwrite(header, 1, 22, fpOutCD) == 22) {
+
+ /* Comment field */
+ if (comsize > 0) {
+ if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
+ err = Z_ERRNO;
+ }
+ }
+
+ } else {
+ err = Z_ERRNO;
+ }
+ }
+
+ /* Final merge (file + central directory) */
+ fclose(fpOutCD);
+ if (err == Z_OK) {
+ fpOutCD = fopen(fileOutTmp, "rb");
+ if (fpOutCD != NULL) {
+ int nRead;
+ char buffer[8192];
+ while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
+ if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
+ err = Z_ERRNO;
+ break;
+ }
+ }
+ fclose(fpOutCD);
+ }
+ }
+
+ /* Close */
+ fclose(fpZip);
+ fclose(fpOut);
+
+ /* Wipe temporary file */
+ (void)remove(fileOutTmp);
+
+ /* Number of recovered entries */
+ if (err == Z_OK) {
+ if (nRecovered != NULL) {
+ *nRecovered = entries;
+ }
+ if (bytesRecovered != NULL) {
+ *bytesRecovered = totalBytes;
+ }
+ }
+ } else {
+ err = Z_STREAM_ERROR;
+ }
+ return err; /* { dg-warning "leak of FILE 'fpZip'" "leak of fpZip" } */
+ /* { dg-warning "leak of FILE 'fpOut'" "leak of fpOut" { target *-*-* } .-1 } */
+ /* { dg-warning "leak of FILE 'fpOutCD'" "leak of fpOutCD" { target *-*-* } .-2 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c
new file mode 100644
index 0000000..0d470d6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility.c
@@ -0,0 +1,79 @@
+/* Simplified version of test to ensure we issue a FILE * leak diagnostic,
+ reproducing a feasibility issue.
+ Adapted from intl/localealias.c, with all #includes removed. */
+
+/* { dg-do "compile" } */
+/* { dg-additional-options "-fno-analyzer-feasibility" } */
+/* TODO: remove the need for this option. */
+
+/* Handle aliases for locale names.
+ Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* Minimal version of system headers. */
+
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *)0)
+
+typedef struct _IO_FILE FILE;
+extern FILE *fopen (const char *__restrict __filename,
+ const char *__restrict __modes);
+extern int fclose (FILE *__stream);
+
+extern int isspace (int) __attribute__((__nothrow__, __leaf__));
+
+/* Cleaned-up body of localealias.c follows. */
+
+size_t
+read_alias_file (const char *fname, int fname_len)
+{
+ FILE *fp;
+ size_t added;
+ char buf[400];
+ char *alias;
+ char *value;
+ char *cp;
+
+ fp = fopen (fname, "r"); /* { dg-message "opened here" } */
+ if (fp == NULL)
+ return 0;
+
+ cp = buf;
+
+ /* Ignore leading white space. */
+ while (isspace ((unsigned char)cp[0]))
+ ++cp;
+
+ if (cp[0] != '\0' && cp[0] != '#')
+ {
+ alias = cp++;
+ while (cp[0] != '\0' && !isspace ((unsigned char)cp[0]))
+ ++cp;
+ if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ while (isspace ((unsigned char)cp[0]))
+ ++cp;
+
+ if (cp[0] != '\0')
+ return 42; /* { dg-warning "leak of FILE 'fp'" } */
+ }
+
+ fclose(fp);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-simplified.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-simplified.c
new file mode 100644
index 0000000..6f65add
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-simplified.c
@@ -0,0 +1,45 @@
+/* Simplified version of test for ensuring we issue a FILE * leak diagnostic,
+ made trivial.
+ Adapted from intl/localealias.c, with all #includes removed. */
+
+/* { dg-do "compile" } */
+
+/* Handle aliases for locale names.
+ Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* Minimal version of system headers. */
+#define NULL ((void *) 0)
+typedef struct _IO_FILE FILE;
+extern FILE *fopen(const char *__restrict __filename,
+ const char *__restrict __modes);
+extern int fclose(FILE *__stream);
+
+void
+read_alias_file (int flag)
+{
+ FILE *fp;
+
+ fp = fopen ("name", "r"); /* { dg-message "opened here" } */
+ if (fp == NULL)
+ return;
+
+ if (flag)
+ return; /* { dg-warning "leak of FILE 'fp'" } */
+
+ fclose (fp);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias.c
new file mode 100644
index 0000000..043e45f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias.c
@@ -0,0 +1,391 @@
+/* Integration test to ensure we issue a FILE * leak diagnostic for
+ this particular non-trivial case.
+ Adapted from intl/localealias.c, with all #includes removed. */
+
+/* { dg-do "compile" } */
+/* { dg-additional-options "-Wno-analyzer-too-complex -fno-analyzer-feasibility" } */
+/* TODO: remove the need for these options. */
+/* { dg-require-effective-target alloca } */
+
+/* Handle aliases for locale names.
+ Copyright (C) 1995-1999, 2000-2001, 2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
+ USA. */
+
+/* Minimal version of system headers. */
+
+typedef __SIZE_TYPE__ size_t;
+#define NULL ((void *) 0)
+
+#define PATH_SEPARATOR ':'
+typedef struct _IO_FILE FILE;
+extern FILE *fopen(const char *__restrict __filename,
+ const char *__restrict __modes);
+extern int feof_unlocked(FILE *__stream) __attribute__((__nothrow__, __leaf__));
+extern char *fgets_unlocked(char *__restrict __s, int __n,
+ FILE *__restrict __stream);
+extern int fclose(FILE *__stream);
+
+#define alloca __builtin_alloca
+
+extern char *strchr(const char *__s, int __c)
+ __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__))
+ __attribute__((__nonnull__(1)));
+extern void *memcpy(void *__restrict __dest, const void *__restrict __src,
+ size_t __n) __attribute__((__nothrow__, __leaf__))
+ __attribute__((__nonnull__(1, 2)));
+extern void *mempcpy(void *__restrict __dest, const void *__restrict __src,
+ size_t __n) __attribute__((__nothrow__, __leaf__))
+ __attribute__((__nonnull__(1, 2)));
+#define HAVE_MEMPCPY 1
+extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__))
+ __attribute__((__pure__)) __attribute__((__nonnull__(1)));
+
+extern int strcasecmp(const char *__s1, const char *__s2)
+ __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__))
+ __attribute__((__nonnull__(1, 2)));
+
+extern int isspace(int) __attribute__((__nothrow__, __leaf__));
+
+extern void *realloc(void *__ptr, size_t __size)
+ __attribute__((__nothrow__, __leaf__))
+ __attribute__((__warn_unused_result__));
+
+typedef int (*__compar_fn_t)(const void *, const void *);
+extern void *bsearch(const void *__key, const void *__base, size_t __nmemb,
+ size_t __size, __compar_fn_t __compar)
+ __attribute__((__nonnull__(1, 2, 5)));
+
+extern __inline __attribute__((__gnu_inline__)) void *
+bsearch(const void *__key, const void *__base, size_t __nmemb, size_t __size,
+ __compar_fn_t __compar) {
+ size_t __l, __u, __idx;
+ const void *__p;
+ int __comparison;
+
+ __l = 0;
+ __u = __nmemb;
+ while (__l < __u) {
+ __idx = (__l + __u) / 2;
+ __p = (void *)(((const char *)__base) + (__idx * __size));
+ __comparison = (*__compar)(__key, __p);
+ if (__comparison < 0)
+ __u = __idx;
+ else if (__comparison > 0)
+ __l = __idx + 1;
+ else
+ return (void *)__p;
+ }
+
+ return ((void *)0);
+}
+
+extern void qsort(void *__base, size_t __nmemb, size_t __size,
+ __compar_fn_t __compar) __attribute__((__nonnull__(1, 4)));
+
+/* Minimal version of intl headers. */
+
+#define PARAMS(args) args
+
+#define relocate libintl_relocate
+extern const char *libintl_relocate(const char *pathname);
+
+#define LOCALE_ALIAS_PATH "value for LOCALE_ALIAS_PATH"
+
+/* Cleaned-up body of localealias.c follows. */
+
+#ifndef internal_function
+# define internal_function
+#endif
+
+/* Some optimizations for glibc. */
+# define FEOF(fp) feof_unlocked (fp)
+# define FGETS(buf, n, fp) fgets_unlocked (buf, n, fp)
+
+/* For those losing systems which don't have `alloca' we have to add
+ some additional code emulating it. */
+# define freea(p) /* nothing */
+
+struct alias_map
+{
+ const char *alias;
+ const char *value;
+};
+
+# define libc_freeres_ptr(decl) decl
+
+libc_freeres_ptr (static char *string_space);
+static size_t string_space_act;
+static size_t string_space_max;
+libc_freeres_ptr (static struct alias_map *map);
+static size_t nmap;
+static size_t maxmap;
+
+
+/* Prototypes for local functions. */
+static size_t read_alias_file PARAMS ((const char *fname, int fname_len))
+ internal_function;
+static int extend_alias_table PARAMS ((void));
+static int alias_compare PARAMS ((const struct alias_map *map1,
+ const struct alias_map *map2));
+
+
+const char *
+_nl_expand_alias (name)
+ const char *name;
+{
+ static const char *locale_alias_path;
+ struct alias_map *retval;
+ const char *result = NULL;
+ size_t added;
+
+#ifdef _LIBC
+ __libc_lock_lock (lock);
+#endif
+
+ if (locale_alias_path == NULL)
+ locale_alias_path = LOCALE_ALIAS_PATH;
+
+ do
+ {
+ struct alias_map item;
+
+ item.alias = name;
+
+ if (nmap > 0)
+ retval = (struct alias_map *) bsearch (&item, map, nmap,
+ sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *,
+ const void *))
+ ) alias_compare);
+ else
+ retval = NULL;
+
+ /* We really found an alias. Return the value. */
+ if (retval != NULL)
+ {
+ result = retval->value;
+ break;
+ }
+
+ /* Perhaps we can find another alias file. */
+ added = 0;
+ while (added == 0 && locale_alias_path[0] != '\0')
+ {
+ const char *start;
+
+ while (locale_alias_path[0] == PATH_SEPARATOR)
+ ++locale_alias_path;
+ start = locale_alias_path;
+
+ while (locale_alias_path[0] != '\0'
+ && locale_alias_path[0] != PATH_SEPARATOR)
+ ++locale_alias_path;
+
+ if (start < locale_alias_path)
+ added = read_alias_file (start, locale_alias_path - start);
+ }
+ }
+ while (added != 0);
+
+#ifdef _LIBC
+ __libc_lock_unlock (lock);
+#endif
+
+ return result;
+}
+
+
+static size_t
+internal_function
+read_alias_file (fname, fname_len)
+ const char *fname;
+ int fname_len;
+{
+ FILE *fp;
+ char *full_fname;
+ size_t added;
+ static const char aliasfile[] = "/locale.alias";
+
+ full_fname = (char *) alloca (fname_len + sizeof aliasfile);
+#ifdef HAVE_MEMPCPY
+ mempcpy (mempcpy (full_fname, fname, fname_len),
+ aliasfile, sizeof aliasfile);
+#else
+ memcpy (full_fname, fname, fname_len);
+ memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile);
+#endif
+
+ fp = fopen (relocate (full_fname), "r"); /* { dg-message "opened here" } */
+ freea (full_fname);
+ if (fp == NULL)
+ return 0;
+
+#ifdef HAVE___FSETLOCKING
+ /* No threads present. */
+ __fsetlocking (fp, FSETLOCKING_BYCALLER);
+#endif
+
+ added = 0;
+ while (!FEOF (fp))
+ {
+ /* It is a reasonable approach to use a fix buffer here because
+ a) we are only interested in the first two fields
+ b) these fields must be usable as file names and so must not
+ be that long
+ We avoid a multi-kilobyte buffer here since this would use up
+ stack space which we might not have if the program ran out of
+ memory. */
+ char buf[400];
+ char *alias;
+ char *value;
+ char *cp;
+
+ if (FGETS (buf, sizeof buf, fp) == NULL)
+ /* EOF reached. */
+ break;
+
+ cp = buf;
+ /* Ignore leading white space. */
+ while (isspace ((unsigned char) cp[0]))
+ ++cp;
+
+ /* A leading '#' signals a comment line. */
+ if (cp[0] != '\0' && cp[0] != '#')
+ {
+ alias = cp++;
+ while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
+ ++cp;
+ /* Terminate alias name. */
+ if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ /* Now look for the beginning of the value. */
+ while (isspace ((unsigned char) cp[0]))
+ ++cp;
+
+ if (cp[0] != '\0')
+ {
+ size_t alias_len;
+ size_t value_len;
+
+ value = cp++;
+ while (cp[0] != '\0' && !isspace ((unsigned char) cp[0]))
+ ++cp;
+ /* Terminate value. */
+ if (cp[0] == '\n')
+ {
+ /* This has to be done to make the following test
+ for the end of line possible. We are looking for
+ the terminating '\n' which do not overwrite here. */
+ *cp++ = '\0';
+ *cp = '\n';
+ }
+ else if (cp[0] != '\0')
+ *cp++ = '\0';
+
+ if (nmap >= maxmap)
+ if (__builtin_expect (extend_alias_table (), 0))
+ return added; /* { dg-warning "leak of FILE 'fp'" } */
+
+ alias_len = strlen (alias) + 1;
+ value_len = strlen (value) + 1;
+
+ if (string_space_act + alias_len + value_len > string_space_max)
+ {
+ /* Increase size of memory pool. */
+ size_t new_size = (string_space_max
+ + (alias_len + value_len > 1024
+ ? alias_len + value_len : 1024));
+ char *new_pool = (char *) realloc (string_space, new_size);
+ if (new_pool == NULL)
+ return added;
+
+ if (__builtin_expect (string_space != new_pool, 0))
+ {
+ size_t i;
+
+ for (i = 0; i < nmap; i++)
+ {
+ map[i].alias += new_pool - string_space;
+ map[i].value += new_pool - string_space;
+ }
+ }
+
+ string_space = new_pool;
+ string_space_max = new_size;
+ }
+
+ map[nmap].alias = memcpy (&string_space[string_space_act],
+ alias, alias_len);
+ string_space_act += alias_len;
+
+ map[nmap].value = memcpy (&string_space[string_space_act],
+ value, value_len);
+ string_space_act += value_len;
+
+ ++nmap;
+ ++added;
+ }
+ }
+
+ /* Possibly not the whole line fits into the buffer. Ignore
+ the rest of the line. */
+ while (strchr (buf, '\n') == NULL)
+ if (FGETS (buf, sizeof buf, fp) == NULL)
+ /* Make sure the inner loop will be left. The outer loop
+ will exit at the `feof' test. */
+ break;
+ }
+
+ /* Should we test for ferror()? I think we have to silently ignore
+ errors. --drepper */
+ fclose (fp);
+
+ if (added > 0)
+ qsort (map, nmap, sizeof (struct alias_map),
+ (int (*) PARAMS ((const void *, const void *))) alias_compare);
+
+ return added;
+}
+
+
+static int
+extend_alias_table ()
+{
+ size_t new_size;
+ struct alias_map *new_map;
+
+ new_size = maxmap == 0 ? 100 : 2 * maxmap;
+ new_map = (struct alias_map *) realloc (map, (new_size
+ * sizeof (struct alias_map)));
+ if (new_map == NULL)
+ /* Simply don't extend: we don't have any more core. */
+ return -1;
+
+ map = new_map;
+ maxmap = new_size;
+ return 0;
+}
+
+
+static int
+alias_compare (map1, map2)
+ const struct alias_map *map1;
+ const struct alias_map *map2;
+{
+ return strcasecmp (map1->alias, map2->alias);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93382.c b/gcc/testsuite/gcc.dg/analyzer/pr93382.c
index c55696d..210b97d 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr93382.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93382.c
@@ -13,8 +13,8 @@ ql (void)
{
int n1[1];
- fread (n1, sizeof (n1[0]), 1, fp); /* { dg-message "'n1' gets an unchecked value here" } */
- idx = n1[0]; /* { dg-message "'idx' has an unchecked value here \\\(from 'n1'\\\)" } */
+ fread (n1, sizeof (n1[0]), 1, fp); /* { dg-message "'n1' gets an unchecked value here" "" { xfail *-*-* } } */
+ idx = n1[0]; /* { dg-message "'idx' has an unchecked value here \\\(from 'n1'\\\)" "" { xfail *-*-* } } */
}
int arr[10];
@@ -23,5 +23,5 @@ int
pl (void)
{
ql ();
- return arr[idx]; /* { dg-warning "use of tainted value 'idx' in array lookup without bounds checking" } */
+ return arr[idx]; /* { dg-warning "use of tainted value 'idx' in array lookup without bounds checking" "" { xfail *-*-* } } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93546.c b/gcc/testsuite/gcc.dg/analyzer/pr93546.c
index 432a643..66f6805 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr93546.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93546.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target label_values } */
void
ch (int x1)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93938.c b/gcc/testsuite/gcc.dg/analyzer/pr93938.c
new file mode 100644
index 0000000..81d9983
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr93938.c
@@ -0,0 +1,13 @@
+/* Taken from gcc.dg/pr70022.c, adding -O1 to the options
+ (and -fanalyzer, implicitly). */
+
+/* { dg-do compile } */
+/* { dg-options "-w -Wno-psabi -O1" } */
+
+typedef int v4si __attribute__ ((vector_size (16)));
+
+int
+foo (v4si v)
+{
+ return v[~0UL];
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94099.c b/gcc/testsuite/gcc.dg/analyzer/pr94099.c
index a116c49..1d7a5d7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94099.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94099.c
@@ -21,7 +21,8 @@ pl (void)
for (sc = 0; sc < 1; ++sc)
{
th.gk.hk = 0;
- th.gk.bg[sc] = 0; /* { dg-warning "uninitialized" "uninit-warning-removed" { xfail *-*-* } } */
+ th.gk.bg[sc] = 0; /* { dg-warning "dereference of NULL '0'" } */
+ // TODO: above message could be improved
l3 (&th);
}
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94399.c b/gcc/testsuite/gcc.dg/analyzer/pr94399.c
new file mode 100644
index 0000000..e897c04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94399.c
@@ -0,0 +1,13 @@
+#include <stdlib.h>
+
+#define _cleanup_(f) __attribute__((cleanup(f)))
+
+static inline void freep(void **p) {
+ free(*p);
+}
+
+void test(void) {
+ _cleanup_(freep) void *ptr;
+
+ ptr = malloc(3);
+} /* { dg-bogus "leak" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94447.c b/gcc/testsuite/gcc.dg/analyzer/pr94447.c
index 1aecebb..7c61a20 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94447.c
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94447.c
@@ -6,5 +6,5 @@ struct foo
int test (void)
{
struct foo f = {};
- return *f.v;
+ return *f.v; /* { dg-warning "dereference of NULL" } */
}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94458.c b/gcc/testsuite/gcc.dg/analyzer/pr94458.c
new file mode 100644
index 0000000..ad9bfc9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94458.c
@@ -0,0 +1,23 @@
+#include <stdlib.h>
+
+struct ret
+{
+ int **array;
+};
+
+struct ret *allocate_stuff(void)
+{
+ struct ret *ret;
+
+ ret = calloc(1, sizeof (struct ret));
+ if (!ret) {
+ abort();
+ }
+
+ ret->array = calloc (10, sizeof(int *));
+ if (!ret->array) {
+ abort();
+ }
+
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94640.c b/gcc/testsuite/gcc.dg/analyzer/pr94640.c
new file mode 100644
index 0000000..9722a17
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94640.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+int debug;
+
+int opencfgfile(const char *cfgfile, FILE **fd)
+{
+ if (cfgfile[0] != '\0') {
+
+ if ((*fd = fopen(cfgfile, "r")) != NULL) {
+ if (debug)
+ printf("Config file: --config\n");
+ }
+
+ }
+
+ return 2;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94688.c b/gcc/testsuite/gcc.dg/analyzer/pr94688.c
new file mode 100644
index 0000000..f553b8c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94688.c
@@ -0,0 +1,6 @@
+int a, b;
+void d();
+void c()
+{
+ d((void (*)()) & a + b);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94689.c b/gcc/testsuite/gcc.dg/analyzer/pr94689.c
new file mode 100644
index 0000000..09802a7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94689.c
@@ -0,0 +1,8 @@
+typedef void (*F) (void);
+void bar (F);
+
+void
+foo (void *a, int b)
+{
+ bar ((F) a + b);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94839.c b/gcc/testsuite/gcc.dg/analyzer/pr94839.c
new file mode 100644
index 0000000..46c8bb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94839.c
@@ -0,0 +1,20 @@
+struct bitmap
+{
+ int min;
+ int max;
+ int *vec;
+};
+
+int bitmap_create(struct bitmap *bm, int min, int max)
+{
+ int sz;
+
+ sz = (max / sizeof(int)) + 1;
+
+ bm->min = min;
+ bm->max = max;
+ bm->vec = __builtin_calloc(sz, sizeof(int));
+ if (!bm->vec)
+ return (-12);
+ return 0; /* { dg-bogus "leak" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-1.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-1.c
new file mode 100644
index 0000000..da79652
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-1.c
@@ -0,0 +1,47 @@
+/* { dg-additional-options "-O2" } */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+typedef struct AMARK {
+ struct AMARK *m_next;
+ char m_name;
+} AMARK;
+
+struct buf {
+ AMARK *b_amark;
+};
+
+struct buf *curbp;
+
+int pamark(void) {
+ int c;
+ AMARK *p = curbp->b_amark;
+ AMARK *last = curbp->b_amark;
+
+ c = getchar();
+
+ while (p != (AMARK *)NULL && p->m_name != (char)c) {
+ last = p;
+ p = p->m_next;
+ }
+
+ if (p != (AMARK *)NULL) {
+ printf("over writing mark %c\n", c);
+ } else {
+ if ((p = (AMARK *)malloc(sizeof(AMARK))) == (AMARK *)NULL)
+ return 0;
+
+ p->m_next = (AMARK *)NULL;
+
+ if (curbp->b_amark == (AMARK *)NULL)
+ curbp->b_amark = p;
+ else
+ last->m_next = p;
+ }
+
+ p->m_name = (char)c; /* { dg-bogus "leak of 'p'" "bogus leak" { xfail *-*-* } } */
+ // TODO(xfail): related to PR analyzer/97072 and PR analyzer/97074
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-3.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-3.c
new file mode 100644
index 0000000..0f95397
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-3.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-O1" } */
+
+struct List {
+ struct List *next;
+};
+
+void foo(struct List *p, struct List *q)
+{
+ while (p && p != q){
+ p = p->next;
+ }
+}
+
+int main()
+{
+ struct List x = {0};
+ foo(0, &x);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c b/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c
new file mode 100644
index 0000000..2a15a5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94851-4.c
@@ -0,0 +1,24 @@
+/* { dg-additional-options "-O2" } */
+
+#include <stdlib.h>
+
+struct List {
+ struct List *next;
+};
+
+void foo(struct List *p, struct List *q)
+{
+ while (p && p != q){
+ struct List *next = p->next;
+ free(p);
+ p = next;
+ }
+}
+
+int main()
+{
+ struct List x = {0};
+ foo(NULL, &x);
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94858-1.c b/gcc/testsuite/gcc.dg/analyzer/pr94858-1.c
new file mode 100644
index 0000000..f7be1c6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94858-1.c
@@ -0,0 +1,42 @@
+#include <stdlib.h>
+
+typedef short hashNx;
+
+typedef struct hashSt {
+ hashNx *hs_index;
+ int hs_used;
+ int hs_slots;
+} hashSt;
+
+void hashEmpty(hashSt *td);
+
+int hashAlloc(hashSt *td, int slots) {
+ hashNx *index;
+
+ if (slots > td->hs_slots) {
+ if (td->hs_index != NULL)
+ index = realloc(td->hs_index, (size_t)slots * sizeof(hashNx));
+ else
+ index = malloc((size_t)slots * sizeof(hashNx));
+
+ if (index == NULL)
+ return 0;
+
+ td->hs_index = index;
+ td->hs_slots = slots;
+ }
+
+ hashEmpty(td);
+
+ return 1;
+}
+
+void hashEmpty(hashSt *td) {
+ hashNx *index;
+ int slots;
+
+ for (slots = td->hs_slots, index = td->hs_index; --slots >= 0;)
+ *index++ = -1;
+
+ td->hs_used = 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94858-2.c b/gcc/testsuite/gcc.dg/analyzer/pr94858-2.c
new file mode 100644
index 0000000..874fe8b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr94858-2.c
@@ -0,0 +1,25 @@
+#include <stdlib.h>
+
+typedef short hashNx;
+
+typedef struct hashSt {
+ hashNx *hs_index;
+ int hs_used;
+ int hs_slots;
+} hashSt;
+
+int test (hashSt *td, int slots)
+{
+ hashNx *index;
+
+ index = malloc((size_t)slots * sizeof(hashNx));
+ if (index == NULL)
+ return 0;
+ td->hs_index = index;
+ td->hs_slots = slots;
+
+ for (slots = td->hs_slots, index = td->hs_index; --slots >= 0;)
+ *index++ = -1;
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95026.c b/gcc/testsuite/gcc.dg/analyzer/pr95026.c
new file mode 100644
index 0000000..1845f15
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr95026.c
@@ -0,0 +1,17 @@
+struct _IO_FILE;
+typedef struct _IO_FILE FILE;
+typedef struct _message
+{
+ FILE *fp;
+} MESSAGE;
+extern FILE *fopen (const char *__restrict __filename,
+ const char *__restrict __modes);
+FILE *f (void);
+int imap_fetch_message (int i, MESSAGE *msg, char *p)
+{
+ if ((msg->fp = i ? 0 : f ()))
+ return 0;
+ if (p)
+ msg->fp = fopen (p, "r");
+ return -1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c b/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c
new file mode 100644
index 0000000..f2a72ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c
@@ -0,0 +1,11 @@
+/* { dg-additional-options "-Wno-pointer-to-int-cast" } */
+extern void my_func (int);
+typedef struct {
+ int var;
+} info_t;
+extern void *_data_offs;
+void test()
+{
+ info_t *info = ((void *)((void *)1) + ((unsigned int)&_data_offs));
+ my_func(info->var == 0);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c b/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c
new file mode 100644
index 0000000..604b784
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c
@@ -0,0 +1,6 @@
+/* { dg-additional-options "-Wno-incompatible-pointer-types" } */
+void foo(void)
+{
+ void (*a[1]) ();
+ void (*p) () = a + 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95240.c b/gcc/testsuite/gcc.dg/analyzer/pr95240.c
new file mode 100644
index 0000000..c84c64d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr95240.c
@@ -0,0 +1,27 @@
+typedef __SIZE_TYPE__ size_t;
+
+extern void *calloc(size_t nmemb, size_t size);
+extern void free(void *ptr);
+
+static char *activeTroubleArray;
+
+int
+initActiveTroubleArray ()
+{
+ activeTroubleArray = calloc (1, 1);
+ return activeTroubleArray ? 0 : 1;
+}
+
+void
+freeActiveTroubleArray ()
+{
+ free (activeTroubleArray);
+}
+
+int main (int argc, char *argv[])
+{
+ initActiveTroubleArray ();
+ freeActiveTroubleArray ();
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96598.c b/gcc/testsuite/gcc.dg/analyzer/pr96598.c
new file mode 100644
index 0000000..b4354cd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96598.c
@@ -0,0 +1,26 @@
+/* { dg-additional-options "-O0 -fsanitize=undefined" } */
+
+extern char *foo (char *dest, const char *src)
+ __attribute__ ((__nonnull__ (1, 2)));
+
+unsigned bar(const char *str)
+ __attribute__ ((__nonnull__ ()));
+
+unsigned test(const char *str, unsigned **pv)
+ __attribute__ ((__nonnull__ ()));
+
+unsigned test(const char* str, unsigned **pv)
+{
+ char buffer[130];
+
+ *pv = 0;
+
+ foo(buffer, str);
+ if (bar(buffer))
+ {
+ const char *ptr = 0;
+ foo(buffer, str);
+ return bar(buffer);
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96611.c b/gcc/testsuite/gcc.dg/analyzer/pr96611.c
new file mode 100644
index 0000000..4f75023
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96611.c
@@ -0,0 +1,14 @@
+struct s { int a; } *ptr;
+void unknown_int_ptr (int *);
+void unknown_void (void);
+
+void test_1 ()
+{
+ unknown_int_ptr (&ptr->a);
+}
+
+void test_2 ()
+{
+ unknown_void ();
+ unknown_int_ptr (&ptr->a);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96639.c b/gcc/testsuite/gcc.dg/analyzer/pr96639.c
new file mode 100644
index 0000000..02ca3f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96639.c
@@ -0,0 +1,10 @@
+void *calloc (__SIZE_TYPE__, __SIZE_TYPE__);
+
+int
+x7 (void)
+{
+ int **md = calloc (1, 1);
+
+ return md[0][0]; /* { dg-warning "possibly-NULL" "unchecked deref" } */
+ /* { dg-warning "leak of 'md'" "leak" { target *-*-* } .-1 } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96642.c b/gcc/testsuite/gcc.dg/analyzer/pr96642.c
new file mode 100644
index 0000000..117aa04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96642.c
@@ -0,0 +1,10 @@
+void
+ut (void)
+{
+ struct {
+ char *cc;
+ } sr[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, "", "", 0, "", 0, 0, "",
+ 0, 0, "", 0, 0, "", 0, 0, "", 0, 0, "", 0, 0, 0, 0, 0,
+ };
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96644.c b/gcc/testsuite/gcc.dg/analyzer/pr96644.c
new file mode 100644
index 0000000..3953c8d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96644.c
@@ -0,0 +1,24 @@
+/* { dg-additional-options "-O1" } */
+
+int oh[1];
+int *x3;
+
+int *
+cm (char *m0)
+{
+ return oh;
+}
+
+void
+ek (void)
+{
+ for (;;)
+ {
+ char *b2 = 0;
+
+ if (*b2 != 0) /* { dg-warning "dereference of NULL" } */
+ ++b2;
+
+ x3 = cm (b2);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96646.c b/gcc/testsuite/gcc.dg/analyzer/pr96646.c
new file mode 100644
index 0000000..2ac5a03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96646.c
@@ -0,0 +1,24 @@
+/* { dg-additional-options "-O1" } */
+
+struct zx {
+ struct zx *b4, *g0;
+};
+
+struct oo {
+ void *ph;
+ struct zx el;
+};
+
+inline void
+k7 (struct zx *xj)
+{
+ xj->b4->g0 = 0; /* { dg-warning "dereference of NULL" } */
+ xj->b4 = 0;
+}
+
+void
+n8 (struct oo *yx)
+{
+ k7 (&yx->el);
+ n8 (yx);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96648.c b/gcc/testsuite/gcc.dg/analyzer/pr96648.c
new file mode 100644
index 0000000..a6b0c72
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96648.c
@@ -0,0 +1,36 @@
+/* { dg-additional-options "-O1" } */
+
+struct vd {
+ struct vd *rs;
+};
+
+struct fh {
+ struct vd cl;
+};
+
+struct i3 {
+ struct fh *h4;
+};
+
+struct fh *
+gm (void);
+
+void
+j7 (struct vd *);
+
+inline void
+mb (struct vd *e7)
+{
+ j7 (e7->rs);
+}
+
+void
+po (struct i3 *d2)
+{
+ struct i3 *s2;
+
+ d2->h4 = gm ();
+ mb (&d2->h4->cl);
+ s2 = ({ d2 - 1; });
+ po (s2);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c
new file mode 100644
index 0000000..94c7555
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-notrans.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-O2 -fno-analyzer-transitivity" } */
+
+int *wf;
+
+void
+yd (void);
+
+int
+cy (void);
+
+int *
+ee (int hp)
+{
+ if (hp != 0)
+ yd ();
+
+ return 0;
+}
+
+void
+z0 (int co)
+{
+ int l4 = sizeof (int);
+
+ aq:
+ wf = ee (l4);
+ if (l4 < co)
+ l4 = cy () + sizeof (int);
+ goto aq;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c
new file mode 100644
index 0000000..b20630b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-1-trans.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-O2 -fanalyzer-transitivity" } */
+
+int *wf;
+
+void
+yd (void);
+
+int
+cy (void);
+
+int *
+ee (int hp)
+{
+ if (hp != 0)
+ yd ();
+
+ return 0;
+}
+
+void
+z0 (int co)
+{
+ int l4 = sizeof (int);
+
+ aq:
+ wf = ee (l4);
+ if (l4 < co)
+ l4 = cy () + sizeof (int);
+ goto aq;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c
new file mode 100644
index 0000000..fc7c045
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-notrans.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-fno-analyzer-transitivity" } */
+
+#include "analyzer-decls.h"
+
+int foo (void);
+
+/* Infeasible path, requiring transitivity to find. */
+
+void test_1 (int co, int y)
+{
+ if (4 < co)
+ if (co < y)
+ if (y == 0)
+ __analyzer_dump_path (); /* { dg-message "path" } */
+}
+
+/* Infeasible path, requiring transitivity to find, with a merger. */
+
+void test_2 (int co, int y, int z)
+{
+ if (4 < co)
+ if (co < y)
+ if (y == 0)
+ {
+ while (foo ())
+ {
+ }
+ __analyzer_dump_path (); /* { dg-message "path" } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c
new file mode 100644
index 0000000..8d0c295
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96650-2-trans.c
@@ -0,0 +1,30 @@
+/* { dg-additional-options "-fanalyzer-transitivity" } */
+
+#include "analyzer-decls.h"
+
+int foo (void);
+
+/* Infeasible path, requiring transitivity to find. */
+
+void test_1 (int co, int y)
+{
+ if (4 < co)
+ if (co < y)
+ if (y == 0)
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+}
+
+/* Infeasible path, requiring transitivity to find, with a merger. */
+
+void test_2 (int co, int y, int z)
+{
+ if (4 < co)
+ if (co < y)
+ if (y == 0)
+ {
+ while (foo ())
+ {
+ }
+ __analyzer_dump_path (); /* { dg-bogus "path" } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96651-1.c b/gcc/testsuite/gcc.dg/analyzer/pr96651-1.c
new file mode 100644
index 0000000..2f3a9b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96651-1.c
@@ -0,0 +1,22 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+static int a;
+
+int main(void)
+{
+ char *src = NULL;
+ char buf[128];
+
+ /* "a" can't have been touched yet, and thus
+ is implicitly zero. */
+ switch (a) {
+ case 1:
+ strcpy(buf, src); /* { dg-bogus "NULL" } */
+ break;
+ case 0:
+ strcpy(buf, "hello");
+ }
+ printf("%s\n", buf);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96651-2.c b/gcc/testsuite/gcc.dg/analyzer/pr96651-2.c
new file mode 100644
index 0000000..249a32b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96651-2.c
@@ -0,0 +1,72 @@
+#include "analyzer-decls.h"
+
+extern void unknown_fn (void *, void *);
+
+static int a;
+static int b = 42;
+int c;
+int d = 17;
+struct { int x; int y; char rgb[3]; } s = {5, 10, {0x80, 0x40, 0x20}};
+void *e = &d;
+
+extern struct _IO_FILE *stderr;
+
+/* If we're not on a direct path from "main", we know nothing about
+ the values of globals. */
+
+void test (void)
+{
+ __analyzer_eval (a == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (b == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (c == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (d == 17); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (s.rgb[2] == 0x20); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (e == &d); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (stderr == 0); /* { dg-warning "UNKNOWN" } */
+}
+
+static void __attribute__((noinline))
+called_from_main (void)
+{
+ /* When accessed from main, the vars still have their initializer values. */
+ __analyzer_eval (a == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (b == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (d == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (s.rgb[2] == 0x20); /* { dg-warning "TRUE" } */
+ __analyzer_eval (e == &d); /* { dg-warning "TRUE" } */
+ /* ...apart from those defined in a different TU (or that were inited
+ before "main"). */
+ __analyzer_eval (stderr == 0); /* { dg-warning "UNKNOWN" } */
+}
+
+int main (void)
+{
+ /* When accessed from main, the vars still have their initializer values. */
+ __analyzer_eval (a == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (b == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (d == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (s.rgb[2] == 0x20); /* { dg-warning "TRUE" } */
+ __analyzer_eval (e == &d); /* { dg-warning "TRUE" } */
+ /* ...apart from those defined in a different TU (or that were inited
+ before "main"). */
+ __analyzer_eval (stderr == 0); /* { dg-warning "UNKNOWN" } */
+
+ called_from_main ();
+
+ unknown_fn (&a, &c);
+
+ /* "a" escaped above and so could have been written to. */
+ __analyzer_eval (a == 0); /* { dg-warning "UNKNOWN" } */
+ /* "b" doesn't escape and is static, and so must still have its
+ initial value. */
+ __analyzer_eval (b == 42); /* { dg-warning "TRUE" } */
+ /* The other globals are non-static and so have implicitly escaped,
+ and so could have been written to. */
+ __analyzer_eval (c == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (d == 17); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (s.rgb[2] == 0x20); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (e == &d); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (stderr == 0); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96653.c b/gcc/testsuite/gcc.dg/analyzer/pr96653.c
new file mode 100644
index 0000000..e5e387c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96653.c
@@ -0,0 +1,1104 @@
+/* Examples of switch statements with many cases (with default values).
+ Adapted from Linux 5.9-rc1:drivers/media/v4l2-core/v4l2-ctrls.c. */
+
+/* { dg-additional-options "-O1" } */
+
+typedef unsigned int u32;
+typedef long long s64;
+typedef unsigned long long u64;
+
+enum v4l2_ctrl_type {
+ V4L2_CTRL_TYPE_INTEGER = 1,
+ V4L2_CTRL_TYPE_BOOLEAN = 2,
+ V4L2_CTRL_TYPE_MENU = 3,
+ V4L2_CTRL_TYPE_BUTTON = 4,
+ V4L2_CTRL_TYPE_INTEGER64 = 5,
+ V4L2_CTRL_TYPE_CTRL_CLASS = 6,
+ V4L2_CTRL_TYPE_STRING = 7,
+ V4L2_CTRL_TYPE_BITMASK = 8,
+ V4L2_CTRL_TYPE_INTEGER_MENU = 9,
+
+ V4L2_CTRL_COMPOUND_TYPES = 0x0100,
+ V4L2_CTRL_TYPE_U8 = 0x0100,
+ V4L2_CTRL_TYPE_U16 = 0x0101,
+ V4L2_CTRL_TYPE_U32 = 0x0102,
+ V4L2_CTRL_TYPE_AREA = 0x0106,
+};
+
+const char *v4l2_ctrl_get_name(u32 id) {
+ switch (id) {
+ case (0x00980000 | 1):
+ return "User Controls";
+ case ((0x00980000 | 0x900) + 0):
+ return "Brightness";
+ case ((0x00980000 | 0x900) + 1):
+ return "Contrast";
+ case ((0x00980000 | 0x900) + 2):
+ return "Saturation";
+ case ((0x00980000 | 0x900) + 3):
+ return "Hue";
+ case ((0x00980000 | 0x900) + 5):
+ return "Volume";
+ case ((0x00980000 | 0x900) + 6):
+ return "Balance";
+ case ((0x00980000 | 0x900) + 7):
+ return "Bass";
+ case ((0x00980000 | 0x900) + 8):
+ return "Treble";
+ case ((0x00980000 | 0x900) + 9):
+ return "Mute";
+ case ((0x00980000 | 0x900) + 10):
+ return "Loudness";
+ case ((0x00980000 | 0x900) + 11):
+ return "Black Level";
+ case ((0x00980000 | 0x900) + 12):
+ return "White Balance, Automatic";
+ case ((0x00980000 | 0x900) + 13):
+ return "Do White Balance";
+ case ((0x00980000 | 0x900) + 14):
+ return "Red Balance";
+ case ((0x00980000 | 0x900) + 15):
+ return "Blue Balance";
+ case ((0x00980000 | 0x900) + 16):
+ return "Gamma";
+ case ((0x00980000 | 0x900) + 17):
+ return "Exposure";
+ case ((0x00980000 | 0x900) + 18):
+ return "Gain, Automatic";
+ case ((0x00980000 | 0x900) + 19):
+ return "Gain";
+ case ((0x00980000 | 0x900) + 20):
+ return "Horizontal Flip";
+ case ((0x00980000 | 0x900) + 21):
+ return "Vertical Flip";
+ case ((0x00980000 | 0x900) + 24):
+ return "Power Line Frequency";
+ case ((0x00980000 | 0x900) + 25):
+ return "Hue, Automatic";
+ case ((0x00980000 | 0x900) + 26):
+ return "White Balance Temperature";
+ case ((0x00980000 | 0x900) + 27):
+ return "Sharpness";
+ case ((0x00980000 | 0x900) + 28):
+ return "Backlight Compensation";
+ case ((0x00980000 | 0x900) + 29):
+ return "Chroma AGC";
+ case ((0x00980000 | 0x900) + 30):
+ return "Color Killer";
+ case ((0x00980000 | 0x900) + 31):
+ return "Color Effects";
+ case ((0x00980000 | 0x900) + 32):
+ return "Brightness, Automatic";
+ case ((0x00980000 | 0x900) + 33):
+ return "Band-Stop Filter";
+ case ((0x00980000 | 0x900) + 34):
+ return "Rotate";
+ case ((0x00980000 | 0x900) + 35):
+ return "Background Color";
+ case ((0x00980000 | 0x900) + 36):
+ return "Chroma Gain";
+ case ((0x00980000 | 0x900) + 37):
+ return "Illuminator 1";
+ case ((0x00980000 | 0x900) + 38):
+ return "Illuminator 2";
+ case ((0x00980000 | 0x900) + 39):
+ return "Min Number of Capture Buffers";
+ case ((0x00980000 | 0x900) + 40):
+ return "Min Number of Output Buffers";
+ case ((0x00980000 | 0x900) + 41):
+ return "Alpha Component";
+ case ((0x00980000 | 0x900) + 42):
+ return "Color Effects, CbCr";
+ case (0x00990000 | 1):
+ return "Codec Controls";
+ case ((0x00990000 | 0x900) + 0):
+ return "Stream Type";
+ case ((0x00990000 | 0x900) + 1):
+ return "Stream PMT Program ID";
+ case ((0x00990000 | 0x900) + 2):
+ return "Stream Audio Program ID";
+ case ((0x00990000 | 0x900) + 3):
+ return "Stream Video Program ID";
+ case ((0x00990000 | 0x900) + 4):
+ return "Stream PCR Program ID";
+ case ((0x00990000 | 0x900) + 5):
+ return "Stream PES Audio ID";
+ case ((0x00990000 | 0x900) + 6):
+ return "Stream PES Video ID";
+ case ((0x00990000 | 0x900) + 7):
+ return "Stream VBI Format";
+ case ((0x00990000 | 0x900) + 100):
+ return "Audio Sampling Frequency";
+ case ((0x00990000 | 0x900) + 101):
+ return "Audio Encoding";
+ case ((0x00990000 | 0x900) + 102):
+ return "Audio Layer I Bitrate";
+ case ((0x00990000 | 0x900) + 103):
+ return "Audio Layer II Bitrate";
+ case ((0x00990000 | 0x900) + 104):
+ return "Audio Layer III Bitrate";
+ case ((0x00990000 | 0x900) + 105):
+ return "Audio Stereo Mode";
+ case ((0x00990000 | 0x900) + 106):
+ return "Audio Stereo Mode Extension";
+ case ((0x00990000 | 0x900) + 107):
+ return "Audio Emphasis";
+ case ((0x00990000 | 0x900) + 108):
+ return "Audio CRC";
+ case ((0x00990000 | 0x900) + 109):
+ return "Audio Mute";
+ case ((0x00990000 | 0x900) + 110):
+ return "Audio AAC Bitrate";
+ case ((0x00990000 | 0x900) + 111):
+ return "Audio AC-3 Bitrate";
+ case ((0x00990000 | 0x900) + 112):
+ return "Audio Playback";
+ case ((0x00990000 | 0x900) + 113):
+ return "Audio Multilingual Playback";
+ case ((0x00990000 | 0x900) + 200):
+ return "Video Encoding";
+ case ((0x00990000 | 0x900) + 201):
+ return "Video Aspect";
+ case ((0x00990000 | 0x900) + 202):
+ return "Video B Frames";
+ case ((0x00990000 | 0x900) + 203):
+ return "Video GOP Size";
+ case ((0x00990000 | 0x900) + 204):
+ return "Video GOP Closure";
+ case ((0x00990000 | 0x900) + 205):
+ return "Video Pulldown";
+ case ((0x00990000 | 0x900) + 206):
+ return "Video Bitrate Mode";
+ case ((0x00990000 | 0x900) + 207):
+ return "Video Bitrate";
+ case ((0x00990000 | 0x900) + 208):
+ return "Video Peak Bitrate";
+ case ((0x00990000 | 0x900) + 209):
+ return "Video Temporal Decimation";
+ case ((0x00990000 | 0x900) + 210):
+ return "Video Mute";
+ case ((0x00990000 | 0x900) + 211):
+ return "Video Mute YUV";
+ case ((0x00990000 | 0x900) + 212):
+ return "Decoder Slice Interface";
+ case ((0x00990000 | 0x900) + 213):
+ return "MPEG4 Loop Filter Enable";
+ case ((0x00990000 | 0x900) + 214):
+ return "Number of Intra Refresh MBs";
+ case ((0x00990000 | 0x900) + 215):
+ return "Frame Level Rate Control Enable";
+ case ((0x00990000 | 0x900) + 218):
+ return "H264 MB Level Rate Control";
+ case ((0x00990000 | 0x900) + 216):
+ return "Sequence Header Mode";
+ case ((0x00990000 | 0x900) + 217):
+ return "Max Number of Reference Pics";
+ case ((0x00990000 | 0x900) + 300):
+ return "H263 I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 301):
+ return "H263 P-Frame QP Value";
+ case ((0x00990000 | 0x900) + 302):
+ return "H263 B-Frame QP Value";
+ case ((0x00990000 | 0x900) + 303):
+ return "H263 Minimum QP Value";
+ case ((0x00990000 | 0x900) + 304):
+ return "H263 Maximum QP Value";
+ case ((0x00990000 | 0x900) + 350):
+ return "H264 I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 351):
+ return "H264 P-Frame QP Value";
+ case ((0x00990000 | 0x900) + 352):
+ return "H264 B-Frame QP Value";
+ case ((0x00990000 | 0x900) + 354):
+ return "H264 Maximum QP Value";
+ case ((0x00990000 | 0x900) + 353):
+ return "H264 Minimum QP Value";
+ case ((0x00990000 | 0x900) + 355):
+ return "H264 8x8 Transform Enable";
+ case ((0x00990000 | 0x900) + 356):
+ return "H264 CPB Buffer Size";
+ case ((0x00990000 | 0x900) + 357):
+ return "H264 Entropy Mode";
+ case ((0x00990000 | 0x900) + 358):
+ return "H264 I-Frame Period";
+ case ((0x00990000 | 0x900) + 359):
+ return "H264 Level";
+ case ((0x00990000 | 0x900) + 360):
+ return "H264 Loop Filter Alpha Offset";
+ case ((0x00990000 | 0x900) + 361):
+ return "H264 Loop Filter Beta Offset";
+ case ((0x00990000 | 0x900) + 362):
+ return "H264 Loop Filter Mode";
+ case ((0x00990000 | 0x900) + 363):
+ return "H264 Profile";
+ case ((0x00990000 | 0x900) + 364):
+ return "Vertical Size of SAR";
+ case ((0x00990000 | 0x900) + 365):
+ return "Horizontal Size of SAR";
+ case ((0x00990000 | 0x900) + 366):
+ return "Aspect Ratio VUI Enable";
+ case ((0x00990000 | 0x900) + 367):
+ return "VUI Aspect Ratio IDC";
+ case ((0x00990000 | 0x900) + 368):
+ return "H264 Enable Frame Packing SEI";
+ case ((0x00990000 | 0x900) + 369):
+ return "H264 Set Curr. Frame as Frame0";
+ case ((0x00990000 | 0x900) + 370):
+ return "H264 FP Arrangement Type";
+ case ((0x00990000 | 0x900) + 371):
+ return "H264 Flexible MB Ordering";
+ case ((0x00990000 | 0x900) + 372):
+ return "H264 Map Type for FMO";
+ case ((0x00990000 | 0x900) + 373):
+ return "H264 FMO Number of Slice Groups";
+ case ((0x00990000 | 0x900) + 374):
+ return "H264 FMO Direction of Change";
+ case ((0x00990000 | 0x900) + 375):
+ return "H264 FMO Size of 1st Slice Grp";
+ case ((0x00990000 | 0x900) + 376):
+ return "H264 FMO No. of Consecutive MBs";
+ case ((0x00990000 | 0x900) + 377):
+ return "H264 Arbitrary Slice Ordering";
+ case ((0x00990000 | 0x900) + 378):
+ return "H264 ASO Slice Order";
+ case ((0x00990000 | 0x900) + 379):
+ return "Enable H264 Hierarchical Coding";
+ case ((0x00990000 | 0x900) + 380):
+ return "H264 Hierarchical Coding Type";
+ case ((0x00990000 | 0x900) + 381):
+ return "H264 Number of HC Layers";
+ case ((0x00990000 | 0x900) + 382):
+ return "H264 Set QP Value for HC Layers";
+ case ((0x00990000 | 0x900) + 383):
+ return "H264 Constrained Intra Pred";
+ case ((0x00990000 | 0x900) + 384):
+ return "H264 Chroma QP Index Offset";
+ case ((0x00990000 | 0x900) + 385):
+ return "H264 I-Frame Minimum QP Value";
+ case ((0x00990000 | 0x900) + 386):
+ return "H264 I-Frame Maximum QP Value";
+ case ((0x00990000 | 0x900) + 387):
+ return "H264 P-Frame Minimum QP Value";
+ case ((0x00990000 | 0x900) + 388):
+ return "H264 P-Frame Maximum QP Value";
+ case ((0x00990000 | 0x900) + 1000):
+ return "H264 Sequence Parameter Set";
+ case ((0x00990000 | 0x900) + 1001):
+ return "H264 Picture Parameter Set";
+ case ((0x00990000 | 0x900) + 1002):
+ return "H264 Scaling Matrix";
+ case ((0x00990000 | 0x900) + 1003):
+ return "H264 Slice Parameters";
+ case ((0x00990000 | 0x900) + 1004):
+ return "H264 Decode Parameters";
+ case ((0x00990000 | 0x900) + 1005):
+ return "H264 Decode Mode";
+ case ((0x00990000 | 0x900) + 1006):
+ return "H264 Start Code";
+ case ((0x00990000 | 0x900) + 270):
+ return "MPEG2 Level";
+ case ((0x00990000 | 0x900) + 271):
+ return "MPEG2 Profile";
+ case ((0x00990000 | 0x900) + 400):
+ return "MPEG4 I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 401):
+ return "MPEG4 P-Frame QP Value";
+ case ((0x00990000 | 0x900) + 402):
+ return "MPEG4 B-Frame QP Value";
+ case ((0x00990000 | 0x900) + 403):
+ return "MPEG4 Minimum QP Value";
+ case ((0x00990000 | 0x900) + 404):
+ return "MPEG4 Maximum QP Value";
+ case ((0x00990000 | 0x900) + 405):
+ return "MPEG4 Level";
+ case ((0x00990000 | 0x900) + 406):
+ return "MPEG4 Profile";
+ case ((0x00990000 | 0x900) + 407):
+ return "Quarter Pixel Search Enable";
+ case ((0x00990000 | 0x900) + 219):
+ return "Maximum Bytes in a Slice";
+ case ((0x00990000 | 0x900) + 220):
+ return "Number of MBs in a Slice";
+ case ((0x00990000 | 0x900) + 221):
+ return "Slice Partitioning Method";
+ case ((0x00990000 | 0x900) + 222):
+ return "VBV Buffer Size";
+ case ((0x00990000 | 0x900) + 223):
+ return "Video Decoder PTS";
+ case ((0x00990000 | 0x900) + 224):
+ return "Video Decoder Frame Count";
+ case ((0x00990000 | 0x900) + 225):
+ return "Initial Delay for VBV Control";
+ case ((0x00990000 | 0x900) + 227):
+ return "Horizontal MV Search Range";
+ case ((0x00990000 | 0x900) + 228):
+ return "Vertical MV Search Range";
+ case ((0x00990000 | 0x900) + 226):
+ return "Repeat Sequence Header";
+ case ((0x00990000 | 0x900) + 229):
+ return "Force Key Frame";
+ case ((0x00990000 | 0x900) + 250):
+ return "MPEG-2 Slice Parameters";
+ case ((0x00990000 | 0x900) + 251):
+ return "MPEG-2 Quantization Matrices";
+ case ((0x00990000 | 0x900) + 292):
+ return "FWHT Stateless Parameters";
+ case ((0x00990000 | 0x900) + 290):
+ return "FWHT I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 291):
+ return "FWHT P-Frame QP Value";
+
+ case ((0x00990000 | 0x900) + 500):
+ return "VPX Number of Partitions";
+ case ((0x00990000 | 0x900) + 501):
+ return "VPX Intra Mode Decision Disable";
+ case ((0x00990000 | 0x900) + 502):
+ return "VPX No. of Refs for P Frame";
+ case ((0x00990000 | 0x900) + 503):
+ return "VPX Loop Filter Level Range";
+ case ((0x00990000 | 0x900) + 504):
+ return "VPX Deblocking Effect Control";
+ case ((0x00990000 | 0x900) + 505):
+ return "VPX Golden Frame Refresh Period";
+ case ((0x00990000 | 0x900) + 506):
+ return "VPX Golden Frame Indicator";
+ case ((0x00990000 | 0x900) + 507):
+ return "VPX Minimum QP Value";
+ case ((0x00990000 | 0x900) + 508):
+ return "VPX Maximum QP Value";
+ case ((0x00990000 | 0x900) + 509):
+ return "VPX I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 510):
+ return "VPX P-Frame QP Value";
+ case ((0x00990000 | 0x900) + 511):
+ return "VP8 Profile";
+ case ((0x00990000 | 0x900) + 512):
+ return "VP9 Profile";
+ case ((0x00990000 | 0x900) + 2000):
+ return "VP8 Frame Header";
+
+ case ((0x00990000 | 0x900) + 602):
+ return "HEVC I-Frame QP Value";
+ case ((0x00990000 | 0x900) + 603):
+ return "HEVC P-Frame QP Value";
+ case ((0x00990000 | 0x900) + 604):
+ return "HEVC B-Frame QP Value";
+ case ((0x00990000 | 0x900) + 600):
+ return "HEVC Minimum QP Value";
+ case ((0x00990000 | 0x900) + 601):
+ return "HEVC Maximum QP Value";
+ case ((0x00990000 | 0x900) + 615):
+ return "HEVC Profile";
+ case ((0x00990000 | 0x900) + 616):
+ return "HEVC Level";
+ case ((0x00990000 | 0x900) + 618):
+ return "HEVC Tier";
+ case ((0x00990000 | 0x900) + 617):
+ return "HEVC Frame Rate Resolution";
+ case ((0x00990000 | 0x900) + 619):
+ return "HEVC Maximum Coding Unit Depth";
+ case ((0x00990000 | 0x900) + 623):
+ return "HEVC Refresh Type";
+ case ((0x00990000 | 0x900) + 626):
+ return "HEVC Constant Intra Prediction";
+ case ((0x00990000 | 0x900) + 625):
+ return "HEVC Lossless Encoding";
+ case ((0x00990000 | 0x900) + 627):
+ return "HEVC Wavefront";
+ case ((0x00990000 | 0x900) + 620):
+ return "HEVC Loop Filter";
+ case ((0x00990000 | 0x900) + 605):
+ return "HEVC QP Values";
+ case ((0x00990000 | 0x900) + 606):
+ return "HEVC Hierarchical Coding Type";
+ case ((0x00990000 | 0x900) + 607):
+ return "HEVC Hierarchical Coding Layer";
+ case ((0x00990000 | 0x900) + 608):
+ return "HEVC Hierarchical Layer 0 QP";
+ case ((0x00990000 | 0x900) + 609):
+ return "HEVC Hierarchical Layer 1 QP";
+ case ((0x00990000 | 0x900) + 610):
+ return "HEVC Hierarchical Layer 2 QP";
+ case ((0x00990000 | 0x900) + 611):
+ return "HEVC Hierarchical Layer 3 QP";
+ case ((0x00990000 | 0x900) + 612):
+ return "HEVC Hierarchical Layer 4 QP";
+ case ((0x00990000 | 0x900) + 613):
+ return "HEVC Hierarchical Layer 5 QP";
+ case ((0x00990000 | 0x900) + 614):
+ return "HEVC Hierarchical Layer 6 QP";
+ case ((0x00990000 | 0x900) + 636):
+ return "HEVC Hierarchical Lay 0 BitRate";
+ case ((0x00990000 | 0x900) + 637):
+ return "HEVC Hierarchical Lay 1 BitRate";
+ case ((0x00990000 | 0x900) + 638):
+ return "HEVC Hierarchical Lay 2 BitRate";
+ case ((0x00990000 | 0x900) + 639):
+ return "HEVC Hierarchical Lay 3 BitRate";
+ case ((0x00990000 | 0x900) + 640):
+ return "HEVC Hierarchical Lay 4 BitRate";
+ case ((0x00990000 | 0x900) + 641):
+ return "HEVC Hierarchical Lay 5 BitRate";
+ case ((0x00990000 | 0x900) + 642):
+ return "HEVC Hierarchical Lay 6 BitRate";
+ case ((0x00990000 | 0x900) + 628):
+ return "HEVC General PB";
+ case ((0x00990000 | 0x900) + 629):
+ return "HEVC Temporal ID";
+ case ((0x00990000 | 0x900) + 630):
+ return "HEVC Strong Intra Smoothing";
+ case ((0x00990000 | 0x900) + 632):
+ return "HEVC Intra PU Split";
+ case ((0x00990000 | 0x900) + 633):
+ return "HEVC TMV Prediction";
+ case ((0x00990000 | 0x900) + 631):
+ return "HEVC Max Num of Candidate MVs";
+ case ((0x00990000 | 0x900) + 634):
+ return "HEVC ENC Without Startcode";
+ case ((0x00990000 | 0x900) + 624):
+ return "HEVC Num of I-Frame b/w 2 IDR";
+ case ((0x00990000 | 0x900) + 621):
+ return "HEVC Loop Filter Beta Offset";
+ case ((0x00990000 | 0x900) + 622):
+ return "HEVC Loop Filter TC Offset";
+ case ((0x00990000 | 0x900) + 635):
+ return "HEVC Size of Length Field";
+ case ((0x00990000 | 0x900) + 643):
+ return "Reference Frames for a P-Frame";
+ case ((0x00990000 | 0x900) + 644):
+ return "Prepend SPS and PPS to IDR";
+ case ((0x00990000 | 0x900) + 1008):
+ return "HEVC Sequence Parameter Set";
+ case ((0x00990000 | 0x900) + 1009):
+ return "HEVC Picture Parameter Set";
+ case ((0x00990000 | 0x900) + 1010):
+ return "HEVC Slice Parameters";
+ case ((0x00990000 | 0x900) + 1015):
+ return "HEVC Decode Mode";
+ case ((0x00990000 | 0x900) + 1016):
+ return "HEVC Start Code";
+
+ case (0x009a0000 | 1):
+ return "Camera Controls";
+ case ((0x009a0000 | 0x900) + 1):
+ return "Auto Exposure";
+ case ((0x009a0000 | 0x900) + 2):
+ return "Exposure Time, Absolute";
+ case ((0x009a0000 | 0x900) + 3):
+ return "Exposure, Dynamic Framerate";
+ case ((0x009a0000 | 0x900) + 4):
+ return "Pan, Relative";
+ case ((0x009a0000 | 0x900) + 5):
+ return "Tilt, Relative";
+ case ((0x009a0000 | 0x900) + 6):
+ return "Pan, Reset";
+ case ((0x009a0000 | 0x900) + 7):
+ return "Tilt, Reset";
+ case ((0x009a0000 | 0x900) + 8):
+ return "Pan, Absolute";
+ case ((0x009a0000 | 0x900) + 9):
+ return "Tilt, Absolute";
+ case ((0x009a0000 | 0x900) + 10):
+ return "Focus, Absolute";
+ case ((0x009a0000 | 0x900) + 11):
+ return "Focus, Relative";
+ case ((0x009a0000 | 0x900) + 12):
+ return "Focus, Automatic Continuous";
+ case ((0x009a0000 | 0x900) + 13):
+ return "Zoom, Absolute";
+ case ((0x009a0000 | 0x900) + 14):
+ return "Zoom, Relative";
+ case ((0x009a0000 | 0x900) + 15):
+ return "Zoom, Continuous";
+ case ((0x009a0000 | 0x900) + 16):
+ return "Privacy";
+ case ((0x009a0000 | 0x900) + 17):
+ return "Iris, Absolute";
+ case ((0x009a0000 | 0x900) + 18):
+ return "Iris, Relative";
+ case ((0x009a0000 | 0x900) + 19):
+ return "Auto Exposure, Bias";
+ case ((0x009a0000 | 0x900) + 20):
+ return "White Balance, Auto & Preset";
+ case ((0x009a0000 | 0x900) + 21):
+ return "Wide Dynamic Range";
+ case ((0x009a0000 | 0x900) + 22):
+ return "Image Stabilization";
+ case ((0x009a0000 | 0x900) + 23):
+ return "ISO Sensitivity";
+ case ((0x009a0000 | 0x900) + 24):
+ return "ISO Sensitivity, Auto";
+ case ((0x009a0000 | 0x900) + 25):
+ return "Exposure, Metering Mode";
+ case ((0x009a0000 | 0x900) + 26):
+ return "Scene Mode";
+ case ((0x009a0000 | 0x900) + 27):
+ return "3A Lock";
+ case ((0x009a0000 | 0x900) + 28):
+ return "Auto Focus, Start";
+ case ((0x009a0000 | 0x900) + 29):
+ return "Auto Focus, Stop";
+ case ((0x009a0000 | 0x900) + 30):
+ return "Auto Focus, Status";
+ case ((0x009a0000 | 0x900) + 31):
+ return "Auto Focus, Range";
+ case ((0x009a0000 | 0x900) + 32):
+ return "Pan, Speed";
+ case ((0x009a0000 | 0x900) + 33):
+ return "Tilt, Speed";
+ case ((0x009e0000 | 0x900) + 8):
+ return "Unit Cell Size";
+ case ((0x009a0000 | 0x900) + 34):
+ return "Camera Orientation";
+ case ((0x009a0000 | 0x900) + 35):
+ return "Camera Sensor Rotation";
+
+ case (0x009b0000 | 1):
+ return "FM Radio Modulator Controls";
+ case ((0x009b0000 | 0x900) + 1):
+ return "RDS Signal Deviation";
+ case ((0x009b0000 | 0x900) + 2):
+ return "RDS Program ID";
+ case ((0x009b0000 | 0x900) + 3):
+ return "RDS Program Type";
+ case ((0x009b0000 | 0x900) + 5):
+ return "RDS PS Name";
+ case ((0x009b0000 | 0x900) + 6):
+ return "RDS Radio Text";
+ case ((0x009b0000 | 0x900) + 7):
+ return "RDS Stereo";
+ case ((0x009b0000 | 0x900) + 8):
+ return "RDS Artificial Head";
+ case ((0x009b0000 | 0x900) + 9):
+ return "RDS Compressed";
+ case ((0x009b0000 | 0x900) + 10):
+ return "RDS Dynamic PTY";
+ case ((0x009b0000 | 0x900) + 11):
+ return "RDS Traffic Announcement";
+ case ((0x009b0000 | 0x900) + 12):
+ return "RDS Traffic Program";
+ case ((0x009b0000 | 0x900) + 13):
+ return "RDS Music";
+ case ((0x009b0000 | 0x900) + 14):
+ return "RDS Enable Alt Frequencies";
+ case ((0x009b0000 | 0x900) + 15):
+ return "RDS Alternate Frequencies";
+ case ((0x009b0000 | 0x900) + 64):
+ return "Audio Limiter Feature Enabled";
+ case ((0x009b0000 | 0x900) + 65):
+ return "Audio Limiter Release Time";
+ case ((0x009b0000 | 0x900) + 66):
+ return "Audio Limiter Deviation";
+ case ((0x009b0000 | 0x900) + 80):
+ return "Audio Compression Enabled";
+ case ((0x009b0000 | 0x900) + 81):
+ return "Audio Compression Gain";
+ case ((0x009b0000 | 0x900) + 82):
+ return "Audio Compression Threshold";
+ case ((0x009b0000 | 0x900) + 83):
+ return "Audio Compression Attack Time";
+ case ((0x009b0000 | 0x900) + 84):
+ return "Audio Compression Release Time";
+ case ((0x009b0000 | 0x900) + 96):
+ return "Pilot Tone Feature Enabled";
+ case ((0x009b0000 | 0x900) + 97):
+ return "Pilot Tone Deviation";
+ case ((0x009b0000 | 0x900) + 98):
+ return "Pilot Tone Frequency";
+ case ((0x009b0000 | 0x900) + 112):
+ return "Pre-Emphasis";
+ case ((0x009b0000 | 0x900) + 113):
+ return "Tune Power Level";
+ case ((0x009b0000 | 0x900) + 114):
+ return "Tune Antenna Capacitor";
+
+ case (0x009c0000 | 1):
+ return "Flash Controls";
+ case ((0x009c0000 | 0x900) + 1):
+ return "LED Mode";
+ case ((0x009c0000 | 0x900) + 2):
+ return "Strobe Source";
+ case ((0x009c0000 | 0x900) + 3):
+ return "Strobe";
+ case ((0x009c0000 | 0x900) + 4):
+ return "Stop Strobe";
+ case ((0x009c0000 | 0x900) + 5):
+ return "Strobe Status";
+ case ((0x009c0000 | 0x900) + 6):
+ return "Strobe Timeout";
+ case ((0x009c0000 | 0x900) + 7):
+ return "Intensity, Flash Mode";
+ case ((0x009c0000 | 0x900) + 8):
+ return "Intensity, Torch Mode";
+ case ((0x009c0000 | 0x900) + 9):
+ return "Intensity, Indicator";
+ case ((0x009c0000 | 0x900) + 10):
+ return "Faults";
+ case ((0x009c0000 | 0x900) + 11):
+ return "Charge";
+ case ((0x009c0000 | 0x900) + 12):
+ return "Ready to Strobe";
+
+ case (0x009d0000 | 1):
+ return "JPEG Compression Controls";
+ case ((0x009d0000 | 0x900) + 1):
+ return "Chroma Subsampling";
+ case ((0x009d0000 | 0x900) + 2):
+ return "Restart Interval";
+ case ((0x009d0000 | 0x900) + 3):
+ return "Compression Quality";
+ case ((0x009d0000 | 0x900) + 4):
+ return "Active Markers";
+
+ case (0x009e0000 | 1):
+ return "Image Source Controls";
+ case ((0x009e0000 | 0x900) + 1):
+ return "Vertical Blanking";
+ case ((0x009e0000 | 0x900) + 2):
+ return "Horizontal Blanking";
+ case ((0x009e0000 | 0x900) + 3):
+ return "Analogue Gain";
+ case ((0x009e0000 | 0x900) + 4):
+ return "Red Pixel Value";
+ case ((0x009e0000 | 0x900) + 5):
+ return "Green (Red) Pixel Value";
+ case ((0x009e0000 | 0x900) + 6):
+ return "Blue Pixel Value";
+ case ((0x009e0000 | 0x900) + 7):
+ return "Green (Blue) Pixel Value";
+
+ case (0x009f0000 | 1):
+ return "Image Processing Controls";
+ case ((0x009f0000 | 0x900) + 1):
+ return "Link Frequency";
+ case ((0x009f0000 | 0x900) + 2):
+ return "Pixel Rate";
+ case ((0x009f0000 | 0x900) + 3):
+ return "Test Pattern";
+ case ((0x009f0000 | 0x900) + 4):
+ return "Deinterlacing Mode";
+ case ((0x009f0000 | 0x900) + 5):
+ return "Digital Gain";
+
+ case (0x00a00000 | 1):
+ return "Digital Video Controls";
+ case ((0x00a00000 | 0x900) + 1):
+ return "Hotplug Present";
+ case ((0x00a00000 | 0x900) + 2):
+ return "RxSense Present";
+ case ((0x00a00000 | 0x900) + 3):
+ return "EDID Present";
+ case ((0x00a00000 | 0x900) + 4):
+ return "Transmit Mode";
+ case ((0x00a00000 | 0x900) + 5):
+ return "Tx RGB Quantization Range";
+ case ((0x00a00000 | 0x900) + 6):
+ return "Tx IT Content Type";
+ case ((0x00a00000 | 0x900) + 100):
+ return "Power Present";
+ case ((0x00a00000 | 0x900) + 101):
+ return "Rx RGB Quantization Range";
+ case ((0x00a00000 | 0x900) + 102):
+ return "Rx IT Content Type";
+
+ case (0x00a10000 | 1):
+ return "FM Radio Receiver Controls";
+ case ((0x00a10000 | 0x900) + 1):
+ return "De-Emphasis";
+ case ((0x00a10000 | 0x900) + 2):
+ return "RDS Reception";
+ case (0x00a20000 | 1):
+ return "RF Tuner Controls";
+ case ((0x00a20000 | 0x900) + 32):
+ return "RF Gain";
+ case ((0x00a20000 | 0x900) + 41):
+ return "LNA Gain, Auto";
+ case ((0x00a20000 | 0x900) + 42):
+ return "LNA Gain";
+ case ((0x00a20000 | 0x900) + 51):
+ return "Mixer Gain, Auto";
+ case ((0x00a20000 | 0x900) + 52):
+ return "Mixer Gain";
+ case ((0x00a20000 | 0x900) + 61):
+ return "IF Gain, Auto";
+ case ((0x00a20000 | 0x900) + 62):
+ return "IF Gain";
+ case ((0x00a20000 | 0x900) + 11):
+ return "Bandwidth, Auto";
+ case ((0x00a20000 | 0x900) + 12):
+ return "Bandwidth";
+ case ((0x00a20000 | 0x900) + 91):
+ return "PLL Lock";
+ case ((0x00a10000 | 0x900) + 3):
+ return "RDS Program Type";
+ case ((0x00a10000 | 0x900) + 4):
+ return "RDS PS Name";
+ case ((0x00a10000 | 0x900) + 5):
+ return "RDS Radio Text";
+ case ((0x00a10000 | 0x900) + 6):
+ return "RDS Traffic Announcement";
+ case ((0x00a10000 | 0x900) + 7):
+ return "RDS Traffic Program";
+ case ((0x00a10000 | 0x900) + 8):
+ return "RDS Music";
+
+ case (0x00a30000 | 1):
+ return "Detection Controls";
+ case ((0x00a30000 | 0x900) + 1):
+ return "Motion Detection Mode";
+ case ((0x00a30000 | 0x900) + 2):
+ return "MD Global Threshold";
+ case ((0x00a30000 | 0x900) + 3):
+ return "MD Threshold Grid";
+ case ((0x00a30000 | 0x900) + 4):
+ return "MD Region Grid";
+ default:
+ return ((void *)0);
+ }
+}
+
+void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
+ s64 *min, s64 *max, u64 *step, s64 *def, u32 *flags) {
+ *name = v4l2_ctrl_get_name(id);
+ *flags = 0;
+
+ switch (id) {
+ case ((0x00980000 | 0x900) + 9):
+ case ((0x00980000 | 0x900) + 10):
+ case ((0x00980000 | 0x900) + 12):
+ case ((0x00980000 | 0x900) + 18):
+ case ((0x00980000 | 0x900) + 20):
+ case ((0x00980000 | 0x900) + 21):
+ case ((0x00980000 | 0x900) + 25):
+ case ((0x00980000 | 0x900) + 29):
+ case ((0x00980000 | 0x900) + 30):
+ case ((0x00980000 | 0x900) + 32):
+ case ((0x00990000 | 0x900) + 109):
+ case ((0x00990000 | 0x900) + 210):
+ case ((0x00990000 | 0x900) + 204):
+ case ((0x00990000 | 0x900) + 205):
+ case ((0x009a0000 | 0x900) + 3):
+ case ((0x009a0000 | 0x900) + 12):
+ case ((0x009a0000 | 0x900) + 16):
+ case ((0x009b0000 | 0x900) + 64):
+ case ((0x009b0000 | 0x900) + 80):
+ case ((0x009b0000 | 0x900) + 96):
+ case ((0x00980000 | 0x900) + 37):
+ case ((0x00980000 | 0x900) + 38):
+ case ((0x009c0000 | 0x900) + 5):
+ case ((0x009c0000 | 0x900) + 11):
+ case ((0x009c0000 | 0x900) + 12):
+ case ((0x00990000 | 0x900) + 213):
+ case ((0x00990000 | 0x900) + 212):
+ case ((0x00990000 | 0x900) + 215):
+ case ((0x00990000 | 0x900) + 218):
+ case ((0x00990000 | 0x900) + 355):
+ case ((0x00990000 | 0x900) + 366):
+ case ((0x00990000 | 0x900) + 407):
+ case ((0x00990000 | 0x900) + 226):
+ case ((0x009a0000 | 0x900) + 21):
+ case ((0x009a0000 | 0x900) + 22):
+ case ((0x00a10000 | 0x900) + 2):
+ case ((0x00a20000 | 0x900) + 41):
+ case ((0x00a20000 | 0x900) + 51):
+ case ((0x00a20000 | 0x900) + 61):
+ case ((0x00a20000 | 0x900) + 11):
+ case ((0x00a20000 | 0x900) + 91):
+ case ((0x009b0000 | 0x900) + 7):
+ case ((0x009b0000 | 0x900) + 8):
+ case ((0x009b0000 | 0x900) + 9):
+ case ((0x009b0000 | 0x900) + 10):
+ case ((0x009b0000 | 0x900) + 11):
+ case ((0x009b0000 | 0x900) + 12):
+ case ((0x009b0000 | 0x900) + 13):
+ case ((0x009b0000 | 0x900) + 14):
+ case ((0x00a10000 | 0x900) + 6):
+ case ((0x00a10000 | 0x900) + 7):
+ case ((0x00a10000 | 0x900) + 8):
+ *type = V4L2_CTRL_TYPE_BOOLEAN;
+ *min = 0;
+ *max = *step = 1;
+ break;
+ case ((0x00980000 | 0x900) + 34):
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *flags |= 0x0400;
+ break;
+ case ((0x00990000 | 0x900) + 227):
+ case ((0x00990000 | 0x900) + 228):
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+ case ((0x00990000 | 0x900) + 229):
+ case ((0x009a0000 | 0x900) + 6):
+ case ((0x009a0000 | 0x900) + 7):
+ case ((0x009c0000 | 0x900) + 3):
+ case ((0x009c0000 | 0x900) + 4):
+ case ((0x009a0000 | 0x900) + 28):
+ case ((0x009a0000 | 0x900) + 29):
+ case ((0x00980000 | 0x900) + 13):
+ *type = V4L2_CTRL_TYPE_BUTTON;
+ *flags |= 0x0040 | 0x0200;
+ *min = *max = *step = *def = 0;
+ break;
+ case ((0x00980000 | 0x900) + 24):
+ case ((0x00990000 | 0x900) + 100):
+ case ((0x00990000 | 0x900) + 101):
+ case ((0x00990000 | 0x900) + 102):
+ case ((0x00990000 | 0x900) + 103):
+ case ((0x00990000 | 0x900) + 104):
+ case ((0x00990000 | 0x900) + 111):
+ case ((0x00990000 | 0x900) + 105):
+ case ((0x00990000 | 0x900) + 106):
+ case ((0x00990000 | 0x900) + 107):
+ case ((0x00990000 | 0x900) + 108):
+ case ((0x00990000 | 0x900) + 112):
+ case ((0x00990000 | 0x900) + 113):
+ case ((0x00990000 | 0x900) + 200):
+ case ((0x00990000 | 0x900) + 201):
+ case ((0x00990000 | 0x900) + 206):
+ case ((0x00990000 | 0x900) + 0):
+ case ((0x00990000 | 0x900) + 7):
+ case ((0x009a0000 | 0x900) + 1):
+ case ((0x009a0000 | 0x900) + 31):
+ case ((0x00980000 | 0x900) + 31):
+ case ((0x009a0000 | 0x900) + 20):
+ case ((0x009b0000 | 0x900) + 112):
+ case ((0x009c0000 | 0x900) + 1):
+ case ((0x009c0000 | 0x900) + 2):
+ case ((0x00990000 | 0x900) + 216):
+ case ((0x00990000 | 0x900) + 221):
+ case ((0x00990000 | 0x900) + 357):
+ case ((0x00990000 | 0x900) + 359):
+ case ((0x00990000 | 0x900) + 362):
+ case ((0x00990000 | 0x900) + 363):
+ case ((0x00990000 | 0x900) + 367):
+ case ((0x00990000 | 0x900) + 370):
+ case ((0x00990000 | 0x900) + 372):
+ case ((0x00990000 | 0x900) + 1005):
+ case ((0x00990000 | 0x900) + 1006):
+ case ((0x00990000 | 0x900) + 270):
+ case ((0x00990000 | 0x900) + 271):
+ case ((0x00990000 | 0x900) + 405):
+ case ((0x00990000 | 0x900) + 406):
+ case ((0x009d0000 | 0x900) + 1):
+ case ((0x009a0000 | 0x900) + 24):
+ case ((0x009a0000 | 0x900) + 25):
+ case ((0x009a0000 | 0x900) + 26):
+ case ((0x00a00000 | 0x900) + 4):
+ case ((0x00a00000 | 0x900) + 5):
+ case ((0x00a00000 | 0x900) + 6):
+ case ((0x00a00000 | 0x900) + 101):
+ case ((0x00a00000 | 0x900) + 102):
+ case ((0x009f0000 | 0x900) + 3):
+ case ((0x009f0000 | 0x900) + 4):
+ case ((0x00a10000 | 0x900) + 1):
+ case ((0x00990000 | 0x900) + 506):
+ case ((0x00990000 | 0x900) + 511):
+ case ((0x00990000 | 0x900) + 512):
+ case ((0x00a30000 | 0x900) + 1):
+ case ((0x00990000 | 0x900) + 615):
+ case ((0x00990000 | 0x900) + 616):
+ case ((0x00990000 | 0x900) + 606):
+ case ((0x00990000 | 0x900) + 623):
+ case ((0x00990000 | 0x900) + 635):
+ case ((0x00990000 | 0x900) + 618):
+ case ((0x00990000 | 0x900) + 620):
+ case ((0x00990000 | 0x900) + 1015):
+ case ((0x00990000 | 0x900) + 1016):
+ case ((0x009a0000 | 0x900) + 34):
+ *type = V4L2_CTRL_TYPE_MENU;
+ break;
+ case ((0x009f0000 | 0x900) + 1):
+ *type = V4L2_CTRL_TYPE_INTEGER_MENU;
+ break;
+ case ((0x009b0000 | 0x900) + 5):
+ case ((0x009b0000 | 0x900) + 6):
+ case ((0x00a10000 | 0x900) + 4):
+ case ((0x00a10000 | 0x900) + 5):
+ *type = V4L2_CTRL_TYPE_STRING;
+ break;
+ case ((0x009a0000 | 0x900) + 23):
+ case ((0x009a0000 | 0x900) + 19):
+ case ((0x00990000 | 0x900) + 500):
+ case ((0x00990000 | 0x900) + 502):
+ *type = V4L2_CTRL_TYPE_INTEGER_MENU;
+ break;
+ case (0x00980000 | 1):
+ case (0x009a0000 | 1):
+ case (0x00990000 | 1):
+ case (0x009b0000 | 1):
+ case (0x009c0000 | 1):
+ case (0x009d0000 | 1):
+ case (0x009e0000 | 1):
+ case (0x009f0000 | 1):
+ case (0x00a00000 | 1):
+ case (0x00a10000 | 1):
+ case (0x00a20000 | 1):
+ case (0x00a30000 | 1):
+ *type = V4L2_CTRL_TYPE_CTRL_CLASS;
+
+ *flags |= 0x0004 | 0x0040;
+ *min = *max = *step = *def = 0;
+ break;
+ case ((0x00980000 | 0x900) + 35):
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *step = 1;
+ *min = 0;
+
+ *max = 0xFFFFFF;
+ break;
+ case ((0x009c0000 | 0x900) + 10):
+ case ((0x009d0000 | 0x900) + 4):
+ case ((0x009a0000 | 0x900) + 27):
+ case ((0x009a0000 | 0x900) + 30):
+ case ((0x00a00000 | 0x900) + 1):
+ case ((0x00a00000 | 0x900) + 2):
+ case ((0x00a00000 | 0x900) + 3):
+ case ((0x00a00000 | 0x900) + 100):
+ *type = V4L2_CTRL_TYPE_BITMASK;
+ break;
+ case ((0x00980000 | 0x900) + 39):
+ case ((0x00980000 | 0x900) + 40):
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ *flags |= 0x0004;
+ break;
+ case ((0x00990000 | 0x900) + 223):
+ *type = V4L2_CTRL_TYPE_INTEGER64;
+ *flags |= 0x0080 | 0x0004;
+ *min = *def = 0;
+ *max = 0x1ffffffffLL;
+ *step = 1;
+ break;
+ case ((0x00990000 | 0x900) + 224):
+ *type = V4L2_CTRL_TYPE_INTEGER64;
+ *flags |= 0x0080 | 0x0004;
+ *min = *def = 0;
+ *max = 0x7fffffffffffffffLL;
+ *step = 1;
+ break;
+ case ((0x009f0000 | 0x900) + 2):
+ *type = V4L2_CTRL_TYPE_INTEGER64;
+ *flags |= 0x0004;
+ break;
+ case ((0x00a30000 | 0x900) + 4):
+ *type = V4L2_CTRL_TYPE_U8;
+ break;
+ case ((0x00a30000 | 0x900) + 3):
+ *type = V4L2_CTRL_TYPE_U16;
+ break;
+ case ((0x009b0000 | 0x900) + 15):
+ *type = V4L2_CTRL_TYPE_U32;
+ break;
+ case ((0x00990000 | 0x900) + 250):
+ *type = 0x0103;
+ break;
+ case ((0x00990000 | 0x900) + 251):
+ *type = 0x0104;
+ break;
+ case ((0x00990000 | 0x900) + 292):
+ *type = 0x0105;
+ break;
+ case ((0x00990000 | 0x900) + 1000):
+ *type = 0x0110;
+ break;
+ case ((0x00990000 | 0x900) + 1001):
+ *type = 0x0111;
+ break;
+ case ((0x00990000 | 0x900) + 1002):
+ *type = 0x0112;
+ break;
+ case ((0x00990000 | 0x900) + 1003):
+ *type = 0x0113;
+ break;
+ case ((0x00990000 | 0x900) + 1004):
+ *type = 0x0114;
+ break;
+ case ((0x00990000 | 0x900) + 2000):
+ *type = 0x301;
+ break;
+ case ((0x00990000 | 0x900) + 1008):
+ *type = 0x0120;
+ break;
+ case ((0x00990000 | 0x900) + 1009):
+ *type = 0x0121;
+ break;
+ case ((0x00990000 | 0x900) + 1010):
+ *type = 0x0122;
+ break;
+ case ((0x009e0000 | 0x900) + 8):
+ *type = V4L2_CTRL_TYPE_AREA;
+ *flags |= 0x0004;
+ break;
+ default:
+ *type = V4L2_CTRL_TYPE_INTEGER;
+ break;
+ }
+ switch (id) {
+ case ((0x00990000 | 0x900) + 101):
+ case ((0x00990000 | 0x900) + 105):
+ case ((0x00990000 | 0x900) + 206):
+ case ((0x00990000 | 0x900) + 202):
+ case ((0x00990000 | 0x900) + 0):
+ *flags |= 0x0008;
+ break;
+ case ((0x00980000 | 0x900) + 5):
+ case ((0x00980000 | 0x900) + 6):
+ case ((0x00980000 | 0x900) + 7):
+ case ((0x00980000 | 0x900) + 8):
+ case ((0x00980000 | 0x900) + 0):
+ case ((0x00980000 | 0x900) + 1):
+ case ((0x00980000 | 0x900) + 2):
+ case ((0x00980000 | 0x900) + 3):
+ case ((0x00980000 | 0x900) + 14):
+ case ((0x00980000 | 0x900) + 15):
+ case ((0x00980000 | 0x900) + 16):
+ case ((0x00980000 | 0x900) + 27):
+ case ((0x00980000 | 0x900) + 36):
+ case ((0x009b0000 | 0x900) + 1):
+ case ((0x009b0000 | 0x900) + 65):
+ case ((0x009b0000 | 0x900) + 66):
+ case ((0x009b0000 | 0x900) + 81):
+ case ((0x009b0000 | 0x900) + 82):
+ case ((0x009b0000 | 0x900) + 83):
+ case ((0x009b0000 | 0x900) + 84):
+ case ((0x009b0000 | 0x900) + 97):
+ case ((0x009b0000 | 0x900) + 98):
+ case ((0x009b0000 | 0x900) + 113):
+ case ((0x009b0000 | 0x900) + 114):
+ case ((0x00a20000 | 0x900) + 32):
+ case ((0x00a20000 | 0x900) + 42):
+ case ((0x00a20000 | 0x900) + 52):
+ case ((0x00a20000 | 0x900) + 62):
+ case ((0x00a20000 | 0x900) + 12):
+ case ((0x00a30000 | 0x900) + 2):
+ *flags |= 0x0020;
+ break;
+ case ((0x009a0000 | 0x900) + 4):
+ case ((0x009a0000 | 0x900) + 5):
+ case ((0x009a0000 | 0x900) + 11):
+ case ((0x009a0000 | 0x900) + 18):
+ case ((0x009a0000 | 0x900) + 14):
+ *flags |= 0x0040 | 0x0200;
+ break;
+ case ((0x009c0000 | 0x900) + 5):
+ case ((0x009a0000 | 0x900) + 30):
+ case ((0x009c0000 | 0x900) + 12):
+ case ((0x00a00000 | 0x900) + 1):
+ case ((0x00a00000 | 0x900) + 2):
+ case ((0x00a00000 | 0x900) + 3):
+ case ((0x00a00000 | 0x900) + 100):
+ case ((0x00a00000 | 0x900) + 102):
+ case ((0x00a10000 | 0x900) + 3):
+ case ((0x00a10000 | 0x900) + 4):
+ case ((0x00a10000 | 0x900) + 5):
+ case ((0x00a10000 | 0x900) + 6):
+ case ((0x00a10000 | 0x900) + 7):
+ case ((0x00a10000 | 0x900) + 8):
+ case ((0x009a0000 | 0x900) + 34):
+ case ((0x009a0000 | 0x900) + 35):
+ *flags |= 0x0004;
+ break;
+ case ((0x00a20000 | 0x900) + 91):
+ *flags |= 0x0080;
+ break;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96699.c b/gcc/testsuite/gcc.dg/analyzer/pr96699.c
new file mode 100644
index 0000000..c68e45a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96699.c
@@ -0,0 +1,13 @@
+struct qi {
+ union {
+ int hj;
+ float sl;
+ };
+};
+
+void
+i2 (struct qi *la)
+{
+ if (la->hj == 0)
+ la->sl = 0.0f;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96705.c b/gcc/testsuite/gcc.dg/analyzer/pr96705.c
new file mode 100644
index 0000000..d7856d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96705.c
@@ -0,0 +1,9 @@
+int __attribute__ ((vector_size (8))) v;
+int i;
+
+void
+test (void)
+{
+ v &= 0;
+ v *= i;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96713.c b/gcc/testsuite/gcc.dg/analyzer/pr96713.c
new file mode 100644
index 0000000..fe9cafd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96713.c
@@ -0,0 +1,8 @@
+typedef int __attribute__ ((vector_size (8))) V;
+
+void
+foo (V d, V e)
+{
+ d <= e;
+ foo ((V){}, (V){});
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96764.c b/gcc/testsuite/gcc.dg/analyzer/pr96764.c
new file mode 100644
index 0000000..70b25d3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96764.c
@@ -0,0 +1,6 @@
+void
+ar (int *hd)
+{
+ int **zv = &hd;
+ *(double *) zv = 0.0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96777.c b/gcc/testsuite/gcc.dg/analyzer/pr96777.c
new file mode 100644
index 0000000..2bb2a4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96777.c
@@ -0,0 +1,12 @@
+struct ge {
+ char au;
+ char pz[];
+};
+
+struct ge tr = { 'X', 'X', };
+
+int
+main (void)
+{
+ return tr.pz[0] == 'X';
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96792.c b/gcc/testsuite/gcc.dg/analyzer/pr96792.c
new file mode 100644
index 0000000..7757645
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96792.c
@@ -0,0 +1,39 @@
+#define NULL (void *)0
+
+struct block
+{
+ void *function;
+ const struct block *superblock;
+};
+
+struct global_block
+{
+ struct block block;
+ void *compunit_symtab;
+};
+
+extern const struct block *block_global_block (const struct block *block);
+
+void *
+block_objfile (const struct block *block)
+{
+ const struct global_block *global_block;
+
+ if (block->function != NULL)
+ return block->function;
+
+ global_block = (struct global_block *) block_global_block (block);
+ return global_block->compunit_symtab;
+}
+
+const struct block *
+block_global_block (const struct block *block)
+{
+ if (block == NULL)
+ return NULL;
+
+ while (block->superblock != NULL)
+ block = block->superblock;
+
+ return block;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c b/gcc/testsuite/gcc.dg/analyzer/pr96841.c
new file mode 100644
index 0000000..d9d35f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96841.c
@@ -0,0 +1,23 @@
+/* { dg-additional-options "-O1 -Wno-builtin-declaration-mismatch" } */
+
+int
+l8 (void);
+
+__SIZE_TYPE__
+malloc (__SIZE_TYPE__);
+
+void
+th (int *);
+
+void
+bv (__SIZE_TYPE__ ny)
+{
+ int ***mf;
+
+ while (l8 ())
+ {
+ *mf = 0;
+ (*mf)[ny] = (int *) malloc (sizeof (int));
+ th ((*mf)[ny]); /* { dg-warning "leak" } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c b/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c
new file mode 100644
index 0000000..8f298ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96860-1.c
@@ -0,0 +1,9 @@
+/* { dg-require-effective-target int128 } */
+/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+
+void x7 (void)
+{
+ __int128 z5[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1,
+ };
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c b/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c
new file mode 100644
index 0000000..90a818c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr96860-2.c
@@ -0,0 +1,8 @@
+/* { dg-additional-options "--param analyzer-max-svalue-depth=0" } */
+
+void x7 (void)
+{
+ long z5[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1,
+ };
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97029.c b/gcc/testsuite/gcc.dg/analyzer/pr97029.c
new file mode 100644
index 0000000..ff83ad4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97029.c
@@ -0,0 +1,7 @@
+struct vj {};
+
+void
+setjmp (struct vj pl)
+{
+ setjmp (pl);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97130.c b/gcc/testsuite/gcc.dg/analyzer/pr97130.c
new file mode 100644
index 0000000..f437b76
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97130.c
@@ -0,0 +1,10 @@
+/* { dg-additional-options "-Wno-builtin-declaration-mismatch" } */
+
+void *
+memset (int, int, __SIZE_TYPE__);
+
+void
+mp (int xl)
+{
+ memset (xl, 0, sizeof xl);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97233.c b/gcc/testsuite/gcc.dg/analyzer/pr97233.c
new file mode 100644
index 0000000..86930aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/pr97233.c
@@ -0,0 +1,8 @@
+void
+longjmp (__SIZE_TYPE__, int);
+
+void
+e7 (__SIZE_TYPE__ gr)
+{
+ longjmp (gr, 1);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c b/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c
new file mode 100644
index 0000000..4eb3a3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/refcounting-1.c
@@ -0,0 +1,31 @@
+#include "analyzer-decls.h"
+
+typedef struct obj {
+ int ob_refcnt;
+} PyObject;
+
+extern void Py_Dealloc (PyObject *op);
+
+#define Py_INCREF(op) \
+ do { \
+ ((PyObject*)(op))->ob_refcnt++; \
+ } while (0)
+
+#define Py_DECREF(op) \
+ do { \
+ if (--((PyObject*)(op))->ob_refcnt == 0) \
+ { \
+ /*Py_Dealloc((PyObject *)(op));*/ \
+ } \
+ } while (0)
+
+void test_1 (PyObject *obj)
+{
+ int orig_refcnt = obj->ob_refcnt;
+ Py_INCREF (obj);
+ Py_INCREF (obj);
+ Py_DECREF (obj);
+ Py_INCREF (obj);
+ __analyzer_eval (obj->ob_refcnt == orig_refcnt + 2); /* { dg-warning "TRUE" } */
+}
+/* TODO: uncomment the Py_Dealloc, which leads to two paths. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/rhbz1878600.c b/gcc/testsuite/gcc.dg/analyzer/rhbz1878600.c
new file mode 100644
index 0000000..9f6ccb6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/rhbz1878600.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+
+#define INI_MAX_LINE 200
+
+typedef char* (*ini_reader)(char* str, int num, void* stream);
+
+int ini_parse(const char* filename);
+
+static int ini_parse_stream(ini_reader reader, void* stream)
+{
+ char line[INI_MAX_LINE];
+ int max_line = INI_MAX_LINE;
+ while (reader(line, max_line, stream) != NULL)
+ ;
+ return 0;
+}
+
+static int ini_parse_file(FILE* file)
+{
+ return ini_parse_stream((ini_reader)fgets, file);
+}
+
+int ini_parse(const char* filename)
+{
+ FILE* file;
+ int error;
+
+ file = fopen(filename, "r");
+ if (!file)
+ return -1;
+ error = ini_parse_file(file);
+ fclose(file);
+ return error;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-1.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-1.c
index c9827fb..72da6c4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-1.c
@@ -1 +1,2 @@
+/* { dg-require-effective-target indirect_jumps } */
#include "../pr26983.c"
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c
index beaf436..f5d9c53 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-2.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include <stddef.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
index 5c1d406..3e4f870 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-3.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include <stddef.h>
#include "test-setjmp.h"
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-4.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-4.c
index f216a45..b6f7d0e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-4.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include "analyzer-decls.h"
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
index 3ee0298..bf5b9bf 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-5.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include <stddef.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-6.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-6.c
index 0e0f12f..3aa6b23 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-6.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target indirect_jumps } */
+
#include "test-setjmp.h"
#include <stddef.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-7.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-7.c
index 6cf9824..6a519b7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-7.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-7.c
@@ -1,3 +1,5 @@
+/* { dg-require-effective-target indirect_jumps } */
+
#include "test-setjmp.h"
#include <stddef.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-7a.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-7a.c
index 87d35bc..220f95e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-7a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-7a.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-8.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-8.c
index abbee2d..79614d1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-8.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-8.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include <stddef.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c
index cf75d3a..c2b00e3 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-9.c
@@ -1,5 +1,6 @@
/* { dg-additional-options "-fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target indirect_jumps } */
#include "test-setjmp.h"
#include <stddef.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/setjmp-pr93378.c b/gcc/testsuite/gcc.dg/analyzer/setjmp-pr93378.c
index 73b94d4..6e2468e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/setjmp-pr93378.c
+++ b/gcc/testsuite/gcc.dg/analyzer/setjmp-pr93378.c
@@ -1,4 +1,5 @@
/* { dg-additional-options "-O1 -g" } */
+/* { dg-require-effective-target indirect_jumps } */
#include <setjmp.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-1.c b/gcc/testsuite/gcc.dg/analyzer/signal-1.c
index 4dcbcc0..43f911b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-1.c
@@ -1,6 +1,7 @@
/* Example of a bad call within a signal handler.
'handler' calls 'custom_logger' which calls 'fprintf', and 'fprintf' is
not allowed from a signal handler. */
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-2.c b/gcc/testsuite/gcc.dg/analyzer/signal-2.c
index a56acb0..d047c67 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-2.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-2.c
@@ -1,6 +1,7 @@
/* Example of a bad call within a signal handler.
'handler' calls 'custom_logger' which calls 'fprintf', and 'fprintf' is
not allowed from a signal handler. */
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-3.c b/gcc/testsuite/gcc.dg/analyzer/signal-3.c
index 5b30888..f5072b5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-3.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-3.c
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-4a.c b/gcc/testsuite/gcc.dg/analyzer/signal-4a.c
index 4b68b6d..4ee6f0e 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-4a.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-4a.c
@@ -2,6 +2,7 @@
/* { dg-options "-fanalyzer -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-4b.c b/gcc/testsuite/gcc.dg/analyzer/signal-4b.c
index 38d4024..cb1e7e4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-4b.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-4b.c
@@ -2,6 +2,7 @@
/* { dg-options "-fanalyzer -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
/* { dg-enable-nn-line-numbers "" } */
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-5.c b/gcc/testsuite/gcc.dg/analyzer/signal-5.c
index 4e464ff..81ac812 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-5.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-5.c
@@ -1,4 +1,5 @@
/* Example of other bad calls within a signal handler. */
+/* { dg-require-effective-target signal } */
#include <stdlib.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-6.c b/gcc/testsuite/gcc.dg/analyzer/signal-6.c
index f518451..ea2290c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-6.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-6.c
@@ -1,3 +1,4 @@
+/* { dg-require-effective-target signal } */
#include <stdio.h>
#include <signal.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-exit.c b/gcc/testsuite/gcc.dg/analyzer/signal-exit.c
index a567124..41a819b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/signal-exit.c
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-exit.c
@@ -1,6 +1,7 @@
/* Example of a bad call within a signal handler with replacement
alternative. 'handler' calls 'exit', and 'exit' is not allowed
from a signal handler. But '_exit' is allowed. */
+/* { dg-require-effective-target signal } */
#include <signal.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c b/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c
new file mode 100644
index 0000000..4bac126
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/signal-registration-loc.c
@@ -0,0 +1,23 @@
+/* Ensure we use the correct location when reporting where the
+ signal handler was registered (PR analyzer/95188). */
+
+/* { dg-require-effective-target signal } */
+
+#include <stdio.h>
+#include <signal.h>
+
+int g;
+extern int foo (void);
+
+static void
+handler (int n)
+{
+ fprintf (stderr, "got here: %i\n", g); /* { dg-warning "call to 'fprintf' from within signal handler" } */
+}
+
+int main (int argc, char *argv[])
+{
+ g = foo (); /* { dg-bogus "registering" } */
+ signal (SIGSEGV, handler); /* { dg-message "registering 'handler' as signal handler" } */
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/single-field.c b/gcc/testsuite/gcc.dg/analyzer/single-field.c
new file mode 100644
index 0000000..d54cfb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/single-field.c
@@ -0,0 +1,37 @@
+#include <stdlib.h>
+#include "analyzer-decls.h"
+
+struct foo
+{
+ char *ptr;
+};
+
+void test_1 (struct foo f)
+{
+ __analyzer_describe (0, f.ptr); /* { dg-warning "svalue: 'INIT_VAL\\(f.ptr\\)'" } */
+}
+
+static void called_by_test_2 (struct foo f_inner)
+{
+ free (f_inner.ptr);
+ free (f_inner.ptr); /* { dg-warning "double-'free' of 'f_outer.ptr'" } */
+}
+void test_2 (struct foo f_outer)
+{
+ called_by_test_2 (f_outer);
+}
+
+struct nested
+{
+ struct foo f;
+};
+
+static void called_by_test_3 (struct nested n_inner)
+{
+ free (n_inner.f.ptr);
+ free (n_inner.f.ptr); /* { dg-warning "double-'free' of 'n_outer.f.ptr'" } */
+}
+void test_3 (struct nested n_outer)
+{
+ called_by_test_3 (n_outer);
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c b/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c
new file mode 100644
index 0000000..0422147
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/stale-frame-1.c
@@ -0,0 +1,15 @@
+
+int *global_ptr;
+
+static void __attribute__((noinline))
+called_by_test_1 (void)
+{
+ int i = 42;
+ global_ptr = &i;
+}
+
+int test_1 (void)
+{
+ called_by_test_1 ();
+ return *global_ptr; /* { dg-warning "dereferencing pointer 'global_ptr' to within stale stack frame" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/strcpy-1.c b/gcc/testsuite/gcc.dg/analyzer/strcpy-1.c
new file mode 100644
index 0000000..ed5bab9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/strcpy-1.c
@@ -0,0 +1,18 @@
+#include <string.h>
+#include "analyzer-decls.h"
+
+char *
+test_1 (char *dst, char *src)
+{
+ char *result = strcpy (dst, src);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
+
+char *
+test_1a (char *dst, char *src)
+{
+ char *result = __strcpy_chk (dst, src, -1);
+ __analyzer_eval (result == dst); /* { dg-warning "TRUE" } */
+ return result;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/strdup-1.c b/gcc/testsuite/gcc.dg/analyzer/strdup-1.c
new file mode 100644
index 0000000..6b950ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/strdup-1.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+
+extern void requires_nonnull (void *ptr)
+ __attribute__((nonnull));
+
+void test_1 (const char *s)
+{
+ char *p = strdup (s); /* { dg-message "allocated here" } */
+} /* { dg-warning "leak of 'p'" } */
+
+void test_2 (const char *s)
+{
+ char *p = strdup (s);
+ free (p);
+}
+void test_3 (const char *s)
+{
+ char *p = strdup (s); /* { dg-message "this call could return NULL" } */
+ requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/strndup-1.c b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
new file mode 100644
index 0000000..23d9b60
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/strndup-1.c
@@ -0,0 +1,21 @@
+#include <string.h>
+#include <stdlib.h>
+
+extern void requires_nonnull (void *ptr)
+ __attribute__((nonnull));
+
+void test_1 (const char *s)
+{
+ char *p = strndup (s, 42); /* { dg-message "allocated here" } */
+} /* { dg-warning "leak of 'p'" } */
+
+void test_2 (const char *s)
+{
+ char *p = strndup (s, 42);
+ free (p);
+}
+void test_3 (const char *s)
+{
+ char *p = strndup (s, 42); /* { dg-message "this call could return NULL" } */
+ requires_nonnull (p); /* { dg-warning "use of possibly-NULL 'p'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
new file mode 100644
index 0000000..9d228e6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-1.c
@@ -0,0 +1,43 @@
+#include "analyzer-decls.h"
+
+/* The example from store2.h */
+
+void test_1 (char a, char b, char c, char d, char e, char f,
+ int i, int j)
+{
+ char arr[1024];
+ arr[2] = a; /* (1) */
+ arr[3] = b; /* (2) */
+
+ __analyzer_eval (arr[2] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[3] == b); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ // TODO: report uninit
+
+ /* Replace one concrete binding's value with a different value. */
+ arr[3] = c; /* (3) */
+ __analyzer_eval (arr[2] == a); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[3] == c); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[3] == b); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ // TODO: report uninit
+
+ /* Symbolic binding. */
+ arr[i] = d; /* (4) */
+ __analyzer_eval (arr[i] == d); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[2] == a); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[3] == c); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ /* Don't report uninit. */
+
+ /* Replace symbolic binding with a different one. */
+ arr[j] = e; /* (5) */
+ __analyzer_eval (arr[j] == e); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[i] == d); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ /* Don't report uninit. */
+
+ /* Add a concrete binding. */
+ arr[3] = f; /* (6) */
+ __analyzer_eval (arr[3] == f); /* { dg-warning "TRUE" } */
+ __analyzer_eval (arr[j] == e); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (arr[4]); /* { dg-warning "UNKNOWN" } */ /* Don't report uninit. */
+}
+
+// TODO: as above, but with int rather than char so there's a cast
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-2.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-2.c
new file mode 100644
index 0000000..70c00ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-2.c
@@ -0,0 +1,32 @@
+#include "analyzer-decls.h"
+
+struct foo
+{
+ int ival;
+ int iarr[10];
+};
+
+void test_1 (int i, int j)
+{
+ struct foo fooarr[4];
+ fooarr[1].ival = 42;
+ fooarr[1].iarr[3] = 27;
+ fooarr[2].iarr[1] = 17;
+ __analyzer_eval (fooarr[1].ival == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fooarr[1].iarr[3] == 27); /* { dg-warning "TRUE" } */
+ __analyzer_eval (fooarr[2].iarr[1] == 17); /* { dg-warning "TRUE" } */
+
+ /* Symbolic binding. */
+ fooarr[2].iarr[i] = j;
+ __analyzer_eval (fooarr[2].iarr[i] == j); /* { dg-warning "TRUE" } */
+
+ /* We should have lost our knowledge about fooarr[2].
+ It's not clear to me if we should also lose our knowledge about
+ fooarr[1] (for the case where i is negative). For now, we do. */
+ __analyzer_eval (fooarr[1].ival == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (fooarr[1].iarr[3] == 27); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (fooarr[2].iarr[1] == 17); /* { dg-warning "UNKNOWN" } */
+ /* Should also be safe to read from fooarr[2];
+ it isn't known to be uninit anymore. */
+ __analyzer_eval (fooarr[2].iarr[10] == 17); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-3.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-3.c
new file mode 100644
index 0000000..da4cdbb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-3.c
@@ -0,0 +1,12 @@
+#include "analyzer-decls.h"
+
+int iarr[16];
+
+void test_1 (int i, int j)
+{
+ int init_el_8 = iarr[8];
+ __analyzer_eval (init_el_8 == iarr[8]); /* { dg-warning "TRUE" } */
+
+ iarr[i] = j;
+ __analyzer_eval (init_el_8 == iarr[8]); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-4.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-4.c
new file mode 100644
index 0000000..a466f91
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-4.c
@@ -0,0 +1,20 @@
+#include <string.h>
+#include "analyzer-decls.h"
+
+void test_1 (int i, int j, int k)
+{
+ int iarr[16];
+ iarr[i] = j;
+ __analyzer_eval (iarr[i] == j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (iarr[k] == j); /* { dg-warning "UNKNOWN" } */
+
+ memset (iarr, 0, sizeof (iarr));
+ __analyzer_eval (iarr[0] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (iarr[i] == 0); /* { dg-warning "TRUE" } */
+ __analyzer_eval (iarr[i] == j); /* { dg-warning "UNKNOWN" } */
+
+ iarr[i] = j;
+ __analyzer_eval (iarr[i] == j); /* { dg-warning "TRUE" } */
+ __analyzer_eval (iarr[0] == 0); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (iarr[i] == 0); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-5.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-5.c
new file mode 100644
index 0000000..3f69650
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-5.c
@@ -0,0 +1,29 @@
+#include "analyzer-decls.h"
+
+int a[1024];
+int b[1024];
+
+extern void escape (void *ptr);
+
+void test_1 (int *p)
+{
+ int c, d;
+ escape (&c);
+ a[16] = 42;
+ b[16] = 17;
+ c = 33;
+ d = 44;
+ __analyzer_eval (a[16] == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (b[16] == 17); /* { dg-warning "TRUE" } */
+ __analyzer_eval (c == 33); /* { dg-warning "TRUE" } */
+ __analyzer_eval (d == 44); /* { dg-warning "TRUE" } */
+
+ /* Write through an externally-provided pointer. */
+ *p = 100;
+ /* It could clobber our writes to the global arrays... */
+ __analyzer_eval (a[16] == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (b[16] == 17); /* { dg-warning "UNKNOWN" } */
+ /* ...but can't clobber locals, even ones like "c" that have escaped. */
+ __analyzer_eval (c == 33); /* { dg-warning "TRUE" } */
+ __analyzer_eval (d == 44); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-6.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-6.c
new file mode 100644
index 0000000..10d4e97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/symbolic-6.c
@@ -0,0 +1,24 @@
+#include "analyzer-decls.h"
+
+int a[1024];
+int b[1024];
+
+extern void escape (void *ptr);
+
+void test_1 (int *p)
+{
+ int c, d;
+ escape (&c);
+
+ *p = 42;
+ __analyzer_eval (*p == 42); /* { dg-warning "TRUE" } */
+
+ /* These writes shouldn't affect *p. */
+ c = 33;
+ d = 44;
+ __analyzer_eval (*p == 42); /* { dg-warning "TRUE" } */
+
+ /* This write could affect *p. */
+ a[16] = 55;
+ __analyzer_eval (*p == 42); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/taint-1.c b/gcc/testsuite/gcc.dg/analyzer/taint-1.c
index 549e266..cd46dd5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/taint-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/taint-1.c
@@ -14,14 +14,14 @@ char test_1(FILE *f)
{
struct foo tmp;
- if (1 == fread(&tmp, sizeof(tmp), 1, f)) { /* { dg-message "\\(1\\) 'tmp' gets an unchecked value here" "event 1" } */
- /* { dg-message "\\(2\\) following 'true' branch\\.\\.\\." "event 2" { target *-*-* } .-1 } */
+ if (1 == fread(&tmp, sizeof(tmp), 1, f)) { /* { dg-message "\\(\[0-9\]+\\) 'tmp' gets an unchecked value here" "event: tmp gets unchecked value" { xfail *-*-* } } */
+ /* { dg-message "\\(\[0-9\]+\\) following 'true' branch\\.\\.\\." "event: following true branch" { target *-*-* } .-1 } */
/* BUG: the following array lookup trusts that the input data's index is
in the range 0 <= i < 256; otherwise it's accessing the stack */
return tmp.buf[tmp.i]; // { dg-warning "use of tainted value 'tmp.i' in array lookup without bounds checking" "warning" } */
- /* { dg-message "23: \\(3\\) \\.\\.\\.to here" "event 3" { target *-*-* } .-1 } */
- /* { dg-message "23: \\(4\\) 'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event 4" { target *-*-* } .-2 } */
- /* { dg-message "\\(5\\) use of tainted value 'tmp.i' in array lookup without bounds checking" "event 5" { target *-*-* } .-3 } */
+ /* { dg-message "23: \\(\[0-9\]+\\) \\.\\.\\.to here" "event: to here" { target *-*-* } .-1 } */
+ /* { dg-message "23: \\(\[0-9\]+\\) 'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event: tmp.i has an unchecked value" { xfail *-*-* } .-2 } */
+ /* { dg-message "\\(\[0-9\]+\\) use of tainted value 'tmp.i' in array lookup without bounds checking" "final event" { target *-*-* } .-3 } */
// TOOD: better messages for state changes
}
@@ -52,9 +52,9 @@ char test_4(FILE *f)
struct foo tmp;
if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
- if (tmp.i >= 0) { /* { dg-message "'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "warning" } */
- /* { dg-message "'tmp.i' has its lower bound checked here" "event" { target *-*-* } .-1 } */
- return tmp.buf[tmp.i]; /* { dg-warning "use of tainted value 'tmp.i' in array lookup without upper-bounds checking" } */
+ if (tmp.i >= 0) { /* { dg-message "'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event: tmp.i has an unchecked value" { xfail *-*-* } } */
+ /* { dg-message "'tmp.i' has its lower bound checked here" "event: lower bound checked" { target *-*-* } .-1 } */
+ return tmp.buf[tmp.i]; /* { dg-warning "use of tainted value 'tmp.i' in array lookup without upper-bounds checking" "warning" } */
}
}
return 0;
@@ -65,9 +65,9 @@ char test_5(FILE *f)
struct foo tmp;
if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
- if (tmp.i < 256) { /* { dg-message "'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "warning" } */
- /* { dg-message "'tmp.i' has its upper bound checked here" "event" { target *-*-* } .-1 } */
- return tmp.buf[tmp.i]; /* { dg-warning "use of tainted value 'tmp.i' in array lookup without lower-bounds checking" } */
+ if (tmp.i < 256) { /* { dg-message "'tmp.i' has an unchecked value here \\(from 'tmp'\\)" "event: tmp.i has an unchecked value" { xfail *-*-* } } */
+ /* { dg-message "'tmp.i' has its upper bound checked here" "event: upper bound checked" { target *-*-* } .-1 } */
+ return tmp.buf[tmp.i]; /* { dg-warning "use of tainted value 'tmp.i' in array lookup without lower-bounds checking" "warning" } */
}
}
return 0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-1.c b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-1.c
new file mode 100644
index 0000000..afb2718
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-1.c
@@ -0,0 +1,15 @@
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+
+#include "../analyzer-decls.h"
+
+void test (int *p)
+{
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ while (*p)
+ {
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enode" } */
+ p++;
+ }
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-2.c b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-2.c
new file mode 100644
index 0000000..d5b10ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-2.c
@@ -0,0 +1,17 @@
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+
+#include "../analyzer-decls.h"
+
+void test (int *p, int val, int count)
+{
+ int n = count;
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ while (n--)
+ {
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */
+ *p++ = val;
+ }
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-3.c b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-3.c
new file mode 100644
index 0000000..c3a1e11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/torture/loop-inc-ptr-3.c
@@ -0,0 +1,18 @@
+/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
+
+#include "../analyzer-decls.h"
+
+void test (int *p, int a, int b, int count)
+{
+ int n = count;
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+
+ while (n--)
+ {
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "2|3 processed enodes" } */
+ *p++ = a;
+ *p++ = b;
+ }
+
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/unknown-fns-2.c b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-2.c
new file mode 100644
index 0000000..1c4bdd6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-2.c
@@ -0,0 +1,238 @@
+/* Tests for data model handling of unknown fns. */
+
+#include <stddef.h>
+#include "analyzer-decls.h"
+
+void unknown_fn (void *);
+
+void test_1 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ unknown_fn (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ unknown_fn (&i);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Even though we're not passing &i to unknown_fn, it escaped
+ above, so unknown_fn could write to it. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
+
+/* As test_1, but with an unknown fn_ptr. */
+
+void test_1a (void (*fn_ptr) (void *))
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ fn_ptr (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ fn_ptr (&i);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Even though we're not passing &i to unknown_fn, it escaped
+ above, so fn_ptr (NULL) could write to it. */
+ fn_ptr (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
+
+int *global_for_test_2;
+
+void test_2 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ global_for_test_2 = &i;
+ unknown_fn (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+
+ global_for_test_2 = NULL;
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Even though the global no longer points to i, it escaped
+ above, so unknown_fn could write to it. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
+
+struct used_by_test_3
+{
+ int *int_ptr;
+};
+
+void test_3 (void)
+{
+ int i;
+
+ struct used_by_test_3 s;
+ s.int_ptr = &i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ unknown_fn (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+ __analyzer_eval (s.int_ptr == &i); /* { dg-warning "TRUE" } */
+
+ /* i should escape here. */
+ unknown_fn (&s);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+ __analyzer_eval (s.int_ptr == &i); /* { dg-warning "UNKNOWN" } */
+
+ s.int_ptr = NULL;
+ __analyzer_eval (s.int_ptr == NULL); /* { dg-warning "TRUE" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Even though nothing we know about points to i, it escaped
+ above, so unknown_fn could write to it. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
+
+struct used_by_test_4
+{
+ int *int_ptr;
+};
+
+void test_4 (struct used_by_test_4 *st4_ptr)
+{
+ /* Something unknown called "test_4", and hence *st4_ptr has
+ effectively already escaped. */
+
+ int i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ unknown_fn (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ /* Given that *st4_ptr has effectively already escaped, calling
+ an unknown fn should invalidate our knowledge of i". */
+ st4_ptr->int_ptr = &i;
+ unknown_fn (NULL);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+
+ /* ...and "&i" should now be treated as having escaped. */
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+ st4_ptr->int_ptr = NULL;
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
+
+static void __attribute__((noinline))
+known_fn (void *ptr)
+{
+ /* Empty. */
+}
+
+void test_5 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ known_fn (&i);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Ensure that we don't consider &i to have escaped. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+}
+
+extern int __attribute__ ((__pure__))
+unknown_pure_fn (void *);
+
+void test_6 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ unknown_pure_fn (&i);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Ensure that we don't consider &i to have escaped. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+}
+
+extern void unknown_const_fn (const void *);
+
+void test_7 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ /* &i is passed as a const void *, so i shouldn't be clobbered by
+ the call. */
+ unknown_const_fn (&i);
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* Ensure that we don't consider &i to have escaped. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+}
+
+struct used_by_test_8
+{
+ int *int_ptr;
+};
+
+void test_8 (void)
+{
+ int i;
+
+ i = 42;
+ __analyzer_eval (i == 42); /* { dg-warning "TRUE" } */
+
+ struct used_by_test_8 st8;
+ st8.int_ptr = &i;
+
+ /* Although unknown_const_fn takes a const void *, the
+ int_ptr is a non-const int *, and so &i should be considered
+ writable. */
+ unknown_const_fn (&st8);
+ __analyzer_eval (i == 42); /* { dg-warning "UNKNOWN" } */
+
+ i = 17;
+ __analyzer_eval (i == 17); /* { dg-warning "TRUE" } */
+
+ /* &i should be considered to have escaped. */
+ unknown_fn (NULL);
+ __analyzer_eval (i == 17); /* { dg-warning "UNKNOWN" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/unknown-fns-3.c b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-3.c
new file mode 100644
index 0000000..095df5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-3.c
@@ -0,0 +1,67 @@
+/* Tests for handling constraints on results of unknown fns. */
+
+#include <stddef.h>
+#include "analyzer-decls.h"
+
+void unknown_fn (void *);
+
+void test_1 (void)
+{
+ int i;
+ unknown_fn (&i);
+ if (i)
+ __analyzer_eval (i); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (i); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+struct foo
+{
+ int i;
+ int j;
+};
+
+void test_2 (void)
+{
+ struct foo f;
+ unknown_fn (&f);
+ if (f.j)
+ __analyzer_eval (f.j); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (f.j); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+void test_3 (int flag)
+{
+ int i;
+ unknown_fn (&i);
+ if (i)
+ {
+ __analyzer_eval (i); /* { dg-warning "TRUE" } */
+ if (flag)
+ __analyzer_eval (flag); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (flag); /* { dg-warning "FALSE" } */
+ }
+ else
+ __analyzer_eval (i); /* { dg-warning "FALSE" } */
+ if (flag)
+ __analyzer_eval (flag); /* { dg-warning "TRUE" } */
+ else
+ __analyzer_eval (flag); /* { dg-warning "FALSE" } */
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
+
+void test_4 (int y)
+{
+ int x;
+ unknown_fn (&x);
+ if (x)
+ {
+ __analyzer_eval (x); /* { dg-warning "TRUE" } */
+ x = 0;
+ }
+ __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/unknown-fns-4.c b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-4.c
new file mode 100644
index 0000000..3d8f82e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/unknown-fns-4.c
@@ -0,0 +1,15 @@
+#include "analyzer-decls.h"
+
+int get(void);
+void test (void)
+{
+ int got = 0;
+ while (1)
+ {
+ if (get ())
+ got = 1;
+ else
+ if (got)
+ __analyzer_dump_path (); /* { dg-message "path" "" { xfail *-*-* } } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/unknown-fns.c b/gcc/testsuite/gcc.dg/analyzer/unknown-fns.c
index 355c8b3..fd1ecbb 100644
--- a/gcc/testsuite/gcc.dg/analyzer/unknown-fns.c
+++ b/gcc/testsuite/gcc.dg/analyzer/unknown-fns.c
@@ -76,10 +76,10 @@ void test_4a (void)
node_b.ptr = malloc (sizeof (int));
global_ptr = &node_a;
*node_b.ptr = 42; /* { dg-warning "possibly-NULL" "possibly-NULL" } */
- /* { dg-warning "leak" "leak" { target *-*-* } .-1 } */
- /* FIXME: the above leak report is correct, but is reported at the wrong
- location. */
-} /* { dg-warning "leak" } */
+ /* Although there's a chain of pointers to the allocation, pointed to
+ by global_ptr, the chain goes through the stack frame and thus
+ there's a leak when it is popped. */
+} /* { dg-warning "leak of 'node_b.ptr'" } */
/* With a call to an unknown function. */
diff --git a/gcc/testsuite/gcc.dg/analyzer/use-after-free.c b/gcc/testsuite/gcc.dg/analyzer/use-after-free.c
new file mode 100644
index 0000000..d7e4bc2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/use-after-free.c
@@ -0,0 +1,12 @@
+#include <stdlib.h>
+#include "analyzer-decls.h"
+
+struct link { struct link *next; };
+
+int free_a_list_badly (struct link *n)
+{
+ while (n) {
+ free(n); /* { dg-message "freed here" } */
+ n = n->next; /* { dg-warning "use after 'free' of 'n'" } */
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/vla-1.c b/gcc/testsuite/gcc.dg/analyzer/vla-1.c
new file mode 100644
index 0000000..e5971c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/vla-1.c
@@ -0,0 +1,14 @@
+/* { dg-require-effective-target alloca } */
+#include "analyzer-decls.h"
+
+void test_1 (int n)
+{
+ struct
+ {
+ char a[n], b;
+ } s;
+ s.a[0] = 42;
+ __analyzer_eval (s.a[0] == 42); /* { dg-warning "TRUE" } */
+ s.b = 17;
+ __analyzer_eval (s.b == 17); /* { dg-warning "TRUE" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c b/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c
new file mode 100644
index 0000000..dc724e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c
@@ -0,0 +1,29 @@
+/* PR middle-end/90404 */
+
+const int c1 = 20; /* { dg-message "declared here" } */
+int test_1 (void)
+{
+ *((int*) &c1) = 10; /* { dg-warning "write to 'const' object 'c1'" } */
+ return c1;
+}
+
+/* Example of writing to a subregion (an element within a const array). */
+
+const int c2[10]; /* { dg-message "declared here" } */
+int test_2 (void)
+{
+ ((int*) &c2)[5] = 10; /* { dg-warning "write to 'const' object 'c2'" } */
+ return c2[5];
+}
+
+const char s3[] = "012.45"; /* { dg-message "declared here" } */
+int test_3 (void)
+{
+ char *p = __builtin_strchr (s3, '.');
+ *p = 0; /* { dg-warning "write to 'const' object 's3'" } */
+
+ if (__builtin_strlen (p) != 3)
+ __builtin_abort ();
+
+ return s3[3] == 0;
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
new file mode 100644
index 0000000..092500e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
@@ -0,0 +1,58 @@
+#include <string.h>
+
+/* PR analyzer/95007. */
+
+void test_1 (void)
+{
+ char *s = "foo";
+ s[0] = 'g'; /* { dg-warning "write to string literal" } */
+}
+
+/* PR c/83347. */
+
+void test_2 (void)
+{
+ memcpy ("abc", "def", 3); /* { dg-warning "write to string literal" } */
+}
+
+static char * __attribute__((noinline))
+called_by_test_3 (void)
+{
+ return (char *)"foo";
+}
+
+void test_3 (void)
+{
+ char *s = called_by_test_3 ();
+ s[1] = 'a'; /* { dg-warning "write to string literal" } */
+}
+
+static char * __attribute__((noinline))
+called_by_test_4 (int flag)
+{
+ if (flag)
+ return (char *)"foo";
+ else
+ return (char *)"bar";
+}
+
+void test_4 (void)
+{
+ char *s = called_by_test_4 (0);
+ s[1] = 'z'; /* { dg-warning "write to string literal" } */
+}
+
+static char * __attribute__((noinline))
+called_by_test_5 (int flag)
+{
+ if (flag)
+ return (char *)"foo";
+ else
+ return (char *)"bar";
+}
+
+void test_5 (int flag)
+{
+ char *s = called_by_test_5 (flag);
+ s[1] = 'z'; /* We miss this one, unless we disable state merging. */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/zlib-4.c b/gcc/testsuite/gcc.dg/analyzer/zlib-4.c
index 0826144..ae2f6c9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/zlib-4.c
+++ b/gcc/testsuite/gcc.dg/analyzer/zlib-4.c
@@ -7,14 +7,18 @@ typedef unsigned long uLong;
#define Z_NULL 0
-void test ()
+int test ()
{
uLong comprLen = 10000*sizeof(int);
uLong uncomprLen = comprLen;
Byte *compr = (Byte*)calloc((uInt)comprLen, 1);
Byte *uncompr = (Byte*)calloc((uInt)uncomprLen, 1);
if (compr == Z_NULL || uncompr == Z_NULL)
- exit (1);
+ {
+ return 1; /* { dg-warning "leak of 'uncompr'" "uncompr leak" } */
+ /* { dg-warning "leak of 'compr'" "compr leak" { target *-*-* } .-1 } */
+ }
strcpy((char*)uncompr, "garbage");
- exit (0);
+ return 0; /* { dg-warning "leak of 'uncompr'" "uncompr leak" } */
+ /* { dg-warning "leak of 'compr'" "compr leak" { target *-*-* } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/asan/pr97294.c b/gcc/testsuite/gcc.dg/asan/pr97294.c
new file mode 100644
index 0000000..6de6c3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr97294.c
@@ -0,0 +1,41 @@
+/* PR sanitizer/97294 */
+/* { dg-do compile { target fopenmp } } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+/* { dg-options "-O0 -fsanitize=address -fopenmp" } */
+/* { dg-final { scan-assembler "foo._omp_fn.\[0-9]\[1-9]*:.*call\[ \t]\*__*asan_allocas_unpoison.*\.size\[ \t]\*foo._omp_fn.\[0-9]\[1-9]*," { target x86_64-*-linux* i?86-*-linux* } } } */
+
+__attribute__((noipa)) void
+foo (int *p, int n)
+{
+ int i;
+ #pragma omp parallel for num_threads(2) reduction(+:p[:n])
+ for (i = 0; i < 10; i++)
+ {
+ p[0]++;
+ p[n - 1] += 2;
+ }
+}
+
+__attribute__((noipa)) void
+bar (void)
+{
+ unsigned char buf[1024];
+ int i;
+ asm volatile ("" : : "r" (&buf[0]) : "memory");
+ for (i = 0; i < 1024; i++)
+ buf[i] = i;
+ asm volatile ("" : : "r" (&buf[0]) : "memory");
+}
+
+int
+main ()
+{
+ int p[50], i;
+ for (i = 0; i < 50; i++)
+ p[i] = 0;
+ foo (p, 50);
+ bar ();
+ if (p[0] != 10 || p[49] != 20)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c b/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c
index f43fa49..cdfb701 100644
--- a/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c
+++ b/gcc/testsuite/gcc.dg/atomic/stdatomic-vm.c
@@ -2,6 +2,7 @@
with side effects. */
/* { dg-do run } */
/* { dg-options "-std=c11 -pedantic-errors" } */
+/* { dg-require-effective-target alloca } */
#include <stdatomic.h>
diff --git a/gcc/testsuite/gcc.dg/attr-access-2.c b/gcc/testsuite/gcc.dg/attr-access-2.c
new file mode 100644
index 0000000..76baddf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-access-2.c
@@ -0,0 +1,122 @@
+/* PR 50584 - No warning for passing small array to C99 static array declarator
+ Exercise interaction between explicit attribute access and VLA parameters.
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+
+
+void f1 (int n, int[n], int); // { dg-message "designating the bound of variable length array argument 2" "note" }
+
+// Verify that a redundant attribute access doesn't trigger a warning.
+RW (2, 1) void f1 (int n, int[n], int);
+
+RW (2, 3) void f1 (int n, int[n], int); // { dg-warning "attribute 'access\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 1" }
+
+
+/* Verify that applying the attribute to a VLA with an unspecified bound
+ doesn't trigger any warnings, both with and without a size operand. */
+ void f2 (int, int[*], int);
+RW (2) void f2 (int, int[*], int);
+RW (2, 3) void f2 (int, int[*], int);
+
+/* Designating a parameter that comes before the VLA is the same as
+ using the standard VLA int[n] syntax. It might be worth issuing
+ a portability warning suggesting to prefer the standard syntax. */
+ void f3 (int, int[*], int);
+RW (2, 1) void f3 (int, int[*], int);
+
+/* Designating a parameter that comes after the VLA cannot be expressed
+ using the standard VLA int[n] syntax. Verify it doesn't trigger
+ a warning. */
+ void f4 (int, int[*], int);
+RW (2, 3) void f4 (int, int[*], int);
+
+/* Also verify the same on the same declaration. */
+ void f5 (int[*], int) RW (1, 2);
+RW (1, 2) void f5 (int[*], int);
+RW (1, 2) void f5 (int[*], int) RW (1, 2);
+
+
+/* Verify that designating a VLA parameter with an explicit bound without
+ also designating the same bound parameter triggers a warning (it has
+ a different meaning). */
+ void f7 (int n, int[n]); // { dg-message "21:note: designating the bound of variable length array argument 2" "note" }
+RW (2) void f7 (int n, int[n]); // { dg-warning "attribute 'access\\\(read_write, 2\\\)' missing positional argument 2 provided in previous designation by argument 1" }
+
+ void f8 (int n, int[n]);
+RW (2, 1) void f8 (int n, int[n]);
+
+
+ void f9 (int, char[]); // { dg-message "25:note: previously declared as an ordinary array 'char\\\[]'" note" }
+RW (2) void f9 (int n, char a[n]) // { dg-warning "argument 2 of type 'char\\\[n]' declared as a variable length array" }
+ // { dg-warning "attribute 'access *\\\(read_write, 2\\\)' positional argument 2 missing in previous designation" "" { target *-*-* } .-1 }
+ // { dg-message "24:note: designating the bound of variable length array argument 2" "note" { target *-*-* } .-2 }
+{ (void)&n; (void)&a; }
+
+
+ void f10 (int, char[]); // { dg-message "26:note: previously declared as an ordinary array 'char\\\[]'" "note" }
+RW (2, 1) void f10 (int n, char a[n]) // { dg-warning "attribute 'access *\\\(read_write, 2, 1\\\)' positional argument 2 missing in previous designation" "pr????" { xfail *-*-* } }
+ // { dg-warning "argument 2 of type 'char\\\[n]' declared as a variable length array" "" { target *-*-* } .-1 }
+{ (void)&n; (void)&a; }
+
+
+/* The following is diagnosed to point out declarations with the T[*]
+ form in headers where specifying the bound is just as important as
+ in the definition (to detect bugs). */
+ void f11 (int, char[*]); // { dg-warning "argument 2 of type 'char\\\[\\\*\\\]' declared with 1 unspecified variable bound" }
+ void f11 (int m, char a[m]); // { dg-message "subsequently declared as 'char\\\[m]' with 0 unspecified variable bounds" "note" }
+RW (2, 1) void f11 (int n, char arr[n]) // { dg-message "subsequently declared as 'char\\\[n]' with 0 unspecified variable bounds" "note" }
+{ (void)&n; (void)&arr; }
+
+
+/* Verify that redeclaring a function with attribute access applying
+ to an array parameter of any form is not diagnosed. */
+ void f12__ (int, int[]) RW (2, 1);
+RW (2, 1) void f12__ (int, int[]);
+
+ void f12_3 (int, int[3]) RW (2, 1);
+RW (2, 1) void f12_3 (int, int[3]);
+
+ void f12_n (int n, int[n]) RW (2, 1);
+RW (2, 1) void f12_n (int n, int[n]);
+
+ void f12_x (int, int[*]) RW (2, 1);
+RW (2, 1) void f12_x (int, int[*]);
+
+ void f13__ (int, int[]);
+RW (2, 1) void f13__ (int, int[]);
+
+ void f13_5 (int, int[5]);
+RW (2, 1) void f13_5 (int, int[5]);
+
+ void f13_n (int n, int[n]);
+RW (2, 1) void f13_n (int n, int[n]);
+
+ void f13_x (int, int[*]);
+RW (2, 1) void f13_x (int, int[*]);
+
+RW (2, 1) void f14__ (int, int[]);
+ void f14__ (int, int[]);
+
+RW (2, 1) void f14_7 (int, int[7]);
+ void f14_7 (int, int[7]);
+
+RW (2, 1) void f14_n (int n, int[n]);
+ void f14_n (int n, int[n]);
+
+RW (2, 1) void f14_x (int, int[*]);
+ void f14_x (int, int[*]);
+
+typedef void G1 (int n, int[n], int);
+
+G1 g1;
+
+/* The warning is about the attribute positional argument 2 which refers
+ to the last function argument. Ideally, the caret would be under
+ the corresponding function argument, i.e., the last one here) but
+ that location isn't available yet. Verify that the caret doesn't
+ point to function argument 1 which is the VLA bound (that's what
+ the caret in the note points to). */
+RW (2, 3) void g1 (int n, int[n], int); // { dg-warning "16: attribute 'access *\\\(read_write, 2, 3\\\)' positional argument 2 conflicts with previous designation by argument 3" }
+// { dg-message "24:designating the bound of variable length array argument 2" "note" { target *-*-* } .-1 }
diff --git a/gcc/testsuite/gcc.dg/attr-access-none.c b/gcc/testsuite/gcc.dg/attr-access-none.c
index d983f2f..dc06d05 100644
--- a/gcc/testsuite/gcc.dg/attr-access-none.c
+++ b/gcc/testsuite/gcc.dg/attr-access-none.c
@@ -23,7 +23,7 @@ void nowarn_fnone_pcv1 (void)
int __attribute__ ((access (none, 1, 2)))
-fnone_pcv1_2 (const void*, int); // { dg-message "in a call to function 'fnone_pcv1_2' declared with attribute 'none \\\(1, 2\\\)'" }
+fnone_pcv1_2 (const void*, int); // { dg-message "in a call to function 'fnone_pcv1_2' declared with attribute 'access \\\(none, 1, 2\\\)'" "note" }
void nowarn_fnone_pcv1_2 (void)
{
diff --git a/gcc/testsuite/gcc.dg/attr-access-read-write-2.c b/gcc/testsuite/gcc.dg/attr-access-read-write-2.c
index c2ac6c3..deeee73 100644
--- a/gcc/testsuite/gcc.dg/attr-access-read-write-2.c
+++ b/gcc/testsuite/gcc.dg/attr-access-read-write-2.c
@@ -22,12 +22,12 @@ int RW (1) grdwr1_wr1 (void*, void*); // { dg-message "previous declar
int WO (1) grdwr1_wr1 (void*, void*); // { dg-warning "attribute 'access\\(write_only, 1\\)' mismatch with mode 'read_write'" }
-int RW (1) RW (1, 2) frdwr1_rdwr1_1 (void*, int); // { dg-warning "attribute 'access\\(read_write, 1, 2\\)' positional argument 2 conflicts with previous designation" }
+int RW (1) RW (1, 2) frdwr1_rdwr1_1 (void*, int); // { dg-warning "attribute 'access\\(read_write, 1, 2\\)' positional argument 2 missing in previous designation" }
int RW (1, 2) RW (1) frdwr1_1_rdwr1 (void*, int); // { dg-warning "attribute 'access\\(read_write, 1\\)' missing positional argument 2 provided in previous designation" }
int RW (1) grdwr1_rdwr1_1 (void*, int); // { dg-message "previous declaration here" }
-int RW (1, 2) grdwr1_rdwr1_1 (void*, int); // { dg-warning "attribute 'access\\(read_write, 1, 2\\)' positional argument 2 conflicts with previous designation" }
+int RW (1, 2) grdwr1_rdwr1_1 (void*, int); // { dg-warning "attribute 'access\\(read_write, 1, 2\\)' positional argument 2 missing in previous designation" }
typedef int *P;
diff --git a/gcc/testsuite/gcc.dg/attr-alloc_align-5.c b/gcc/testsuite/gcc.dg/attr-alloc_align-5.c
new file mode 100644
index 0000000..d6f2bc1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-alloc_align-5.c
@@ -0,0 +1,23 @@
+/* PR c/78666 - conflicting attribute alloc_size accepted
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define A(pos) __attribute__ ((alloc_align (pos)))
+
+A (1) char* f2_1 (int, int);
+A (1) char* f2_1 (int, int); // { dg-message "previous declaration here" }
+
+A (2) char* f2_1 (int, int); // { dg-warning "ignoring attribute 'alloc_align \\\(2\\\)' because it conflicts with previous 'alloc_align \\\(1\\\)'" }
+
+
+A (2) char* f2_2 (int, int);
+A (2) char* f2_2 (int, int); // { dg-message "previous declaration here" }
+
+A (1) char* f2_2 (int, int); // { dg-warning "ignoring attribute 'alloc_align \\\(1\\\)' because it conflicts with previous 'alloc_align \\\(2\\\)'" }
+
+
+A (1) char* f3_1 (int, int, int);
+A (1) char* f3_1 (int, int, int); // { dg-message "previous declaration here" }
+
+A (2) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_align \\\(2\\\)' because it conflicts with previous 'alloc_align \\\(1\\\)'" }
+A (3) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_align \\\(3\\\)' because it conflicts with previous 'alloc_align \\\(1\\\)'" }
diff --git a/gcc/testsuite/gcc.dg/attr-alloc_size-13.c b/gcc/testsuite/gcc.dg/attr-alloc_size-13.c
new file mode 100644
index 0000000..df44f47
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-alloc_size-13.c
@@ -0,0 +1,34 @@
+/* PR c/78666 - conflicting attribute alloc_size accepted
+ { dg-do compile }
+ { dg-options "-Wall" } */
+
+#define A(...) __attribute__ ((alloc_size (__VA_ARGS__)))
+
+A (1) char* f2_1 (int, int);
+A (1) A (1) char* f2_1 (int, int);
+
+A (1) char* f2_1 (int, int); // { dg-message "previous declaration here" }
+
+A (2) char* f2_1 (int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(2\\\)' because it conflicts with previous 'alloc_size \\\(1\\\)'" }
+
+
+A (2) char* f2_2 (int, int);
+A (2) char* f2_2 (int, int); // { dg-message "previous declaration here" }
+
+A (1) char* f2_2 (int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(1\\\)' because it conflicts with previous 'alloc_size \\\(2\\\)'" }
+
+
+A (1) char* f3_1 (int, int, int);
+A (1) char* f3_1 (int, int, int); // { dg-message "previous declaration here" }
+
+A (2) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(2\\\)' because it conflicts with previous 'alloc_size \\\(1\\\)'" }
+A (3) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(3\\\)' because it conflicts with previous 'alloc_size \\\(1\\\)'" }
+A (1, 2) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(1, 2\\\)' because it conflicts with previous 'alloc_size \\\(1\\\)'" }
+A (1, 3) char* f3_1 (int, int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(1, 3\\\)' because it conflicts with previous 'alloc_size \\\(1\\\)'" }
+
+
+typedef A (2, 3) char* F3_2_3 (int, int, int);
+typedef A (2, 3) char* F3_2_3 (int, int, int);
+typedef A (2, 3) A (2, 3) char* F3_2_3 (int, int, int);
+
+typedef A (1) char* F3_2_3 (int, int, int); // { dg-warning "ignoring attribute 'alloc_size \\\(1\\\)' because it conflicts with previous 'alloc_size \\\(2, 3\\\)'" }
diff --git a/gcc/testsuite/gcc.dg/attr-copy-4.c b/gcc/testsuite/gcc.dg/attr-copy-4.c
index 1350a35..01fae3f 100644
--- a/gcc/testsuite/gcc.dg/attr-copy-4.c
+++ b/gcc/testsuite/gcc.dg/attr-copy-4.c
@@ -21,7 +21,8 @@ Assert (__alignof (struct PackedA) == __alignof (struct PackedB));
struct PackedMember
{
char c;
- ATTR ((copy ((struct PackedB*)0))) double packed_mem;
+ ATTR ((copy ((struct PackedB*)0))) double packed_mem;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
};
Assert (__alignof (struct PackedMember) == 1);
@@ -31,6 +32,7 @@ extern const struct PackedA packed;
struct Unpacked { int i; char c; };
Assert (__alignof (struct Unpacked) > 1);
+/* { dg-error "size of array .* is negative" "" { target default_packed } .-1 } */
/* Verify that copying the packed attribute to the declaration
of an object is ignored with a warning. (There should be
diff --git a/gcc/testsuite/gcc.dg/attr-copy-6.c b/gcc/testsuite/gcc.dg/attr-copy-6.c
index d1a2865..cf578bd 100644
--- a/gcc/testsuite/gcc.dg/attr-copy-6.c
+++ b/gcc/testsuite/gcc.dg/attr-copy-6.c
@@ -2,6 +2,7 @@
{ dg-do compile }
{ dg-skip-if "Attributes not supported" { { hppa*-*-hpux* } && { ! lp64 } } }
{ dg-options "-O2 -Wall" }
+ { dg-require-visibility "hidden" }
{ dg-require-alias "" }
{ dg-require-weak "" } */
diff --git a/gcc/testsuite/gcc.dg/attr-copy-8.c b/gcc/testsuite/gcc.dg/attr-copy-8.c
index c75d9e5..7195f6b 100644
--- a/gcc/testsuite/gcc.dg/attr-copy-8.c
+++ b/gcc/testsuite/gcc.dg/attr-copy-8.c
@@ -21,41 +21,66 @@ extern B *pb;
typedef struct C
{
ATTR (copy ((struct A *)0)) short m_pa_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy ((struct A *)(1, 0))) int m_pa_1_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy ((struct A *)(0, 1))) long m_pa_0_1;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*(struct A *)0)) short m_xpa_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*(struct A *)(1, 0))) int m_xpa_1_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*(struct A *)(0, 1))) long m_xpa_0_1;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (((struct A *)0)[0])) short m_arpa_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (((struct A *)(1, 0))[0])) int m_arpa_1_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (((struct A *)(0, 1))[0])) long m_arpa_0_1;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
/* Also exercise COMPONENT_REF, ARRAY_REF, and INDIRECT_REF. */
ATTR (copy (a)) short m_ra;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (b.a)) int m_rb_a;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (b.pa)) long m_rb_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (&a)) short m_ara;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (&b.a)) int m_arb_a;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*b.pa)) long m_xb_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (b.pa[0])) long m_arb_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*pa)) short m_xpa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (pa[0])) short m_arpa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (ab[0].a)) int m_arab_a;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (ab[1].pa)) long m_arab_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*ab[2].pa)) int m_xarab_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (ab[3].pa->bf)) unsigned int m_arab_pa_bf: 1;
ATTR (copy (pb->a)) int m_pb_a;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (pb->pa)) long m_pb_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (*pb->pa)) int m_xpb_pa;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
ATTR (copy (pb->pa->bf)) unsigned int m_pb_pa_bf: 1;
ATTR (aligned (4), copy ((struct A *)(0))) short m_a4_pa_0;
+ /* { dg-warning "attribute ignored" "" { target default_packed } .-1 } */
} C;
diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-2.c b/gcc/testsuite/gcc.dg/attr-nonstring-2.c
index ef2144d..ba4757d 100644
--- a/gcc/testsuite/gcc.dg/attr-nonstring-2.c
+++ b/gcc/testsuite/gcc.dg/attr-nonstring-2.c
@@ -26,8 +26,8 @@ void test_strnlen_array_cst (void)
T (strnlen (ns3, 1));
T (strnlen (ns3, 2));
T (strnlen (ns3, 3));
- T (strnlen (ns3, 4)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 4" } */
- T (strnlen (ns3, DIFF_MAX)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \[0-9\]+" } */
+ T (strnlen (ns3, 4)); /* { dg-warning "specified bound 4 exceeds source size 3" } */
+ T (strnlen (ns3, DIFF_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds source size" } */
T (strnlen (ns3, SIZE_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
NONSTRING char ns5[5];
@@ -37,8 +37,8 @@ void test_strnlen_array_cst (void)
T (strnlen (ns5, 1));
T (strnlen (ns5, 2));
T (strnlen (ns5, 3));
- T (strnlen (ns5, 6)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 6" } */
- T (strnlen (ns5, DIFF_MAX)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \[0-9\]+" } */
+ T (strnlen (ns5, 6)); /* { dg-warning "specified bound 6 exceeds source size 5" } */
+ T (strnlen (ns5, DIFF_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds source size 5" } */
T (strnlen (ns5, SIZE_MAX)); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
}
@@ -52,8 +52,8 @@ void test_strnlen_array_range (void)
T (strnlen (ns3, UR (0, 9)));
T (strnlen (ns3, UR (3, 4)));
T (strnlen (ns3, UR (3, DIFF_MAX)));
- T (strnlen (ns3, UR (4, 5))); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[4, 5]" } */
- T (strnlen (ns3, UR (DIFF_MAX, SIZE_MAX))); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller " } */
+ T (strnlen (ns3, UR (4, 5))); /* { dg-warning "specified bound \\\[4, 5] exceeds source size 3" } */
+ T (strnlen (ns3, UR (DIFF_MAX, SIZE_MAX))); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 3 " } */
}
@@ -73,8 +73,8 @@ void test_strnlen_string_cst (void)
T (3, "12", 3, 1);
T (3, "12", 3, 9);
T (3, "123", 3, 1);
- T (3, "123", 3, 4); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 4" } */
- T (3, "123", 3, 9); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 9" } */
+ T (3, "123", 3, 4); /* { dg-warning "specified bound 4 exceeds source size 3" } */
+ T (3, "123", 3, 9); /* { dg-warning "specified bound 9 exceeds source size 3" } */
T (5, "1", 2, 1);
T (5, "1", 2, 2);
@@ -84,7 +84,7 @@ void test_strnlen_string_cst (void)
T (5, "12", 3, 9);
T (5, "123", 3, 1);
T (5, "123", 3, 5);
- T (5, "123", 3, 6); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound 6" } */
+ T (5, "123", 3, 6); /* { dg-warning "specified bound 6 exceeds source size 5" } */
/* Strnlen shouldn't trigger a warning for arrays of unknown size
(except for accesses to uninitialized elements when those are
@@ -110,6 +110,6 @@ void test_strnlen_string_range (void)
{
T (3, "1", 2, UR (0, 1));
T (3, "1", 2, UR (3, 9));
- T (3, "123", 3, UR (4, 5)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[4, 5]" } */
- T (3, "123", 3, UR (5, 9)); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound \\\[5, 9]" } */
+ T (3, "123", 3, UR (4, 5)); /* { dg-warning "specified bound \\\[4, 5] exceeds source size 3" } */
+ T (3, "123", 3, UR (5, 9)); /* { dg-warning "specified bound \\\[5, 9] exceeds source size 3" } */
}
diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-3.c b/gcc/testsuite/gcc.dg/attr-nonstring-3.c
index 4a10450..34f31fb 100644
--- a/gcc/testsuite/gcc.dg/attr-nonstring-3.c
+++ b/gcc/testsuite/gcc.dg/attr-nonstring-3.c
@@ -37,15 +37,21 @@ void strncmp_cst (void)
T (STR, /* [] */, STR, /* [] */, n);
T (STR, /* [] */, STR, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
+ T (STR, 1, STR, /* [] */, 1);
T (STR, 1, STR, /* [] */, n);
T (STR, 2, STR, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
+ T (STR, /* [] */, STR, 3, 3);
T (STR, /* [] */, STR, 3, n);
T (STR, /* [] */, STR, 4, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
+ T (STR, /* [] */, NS, /* [] */, 3);
T (STR, /* [] */, NS, /* [] */, n);
T (STR, /* [] */, NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
+ T (STR, 5, NS, /* [] */, 4);
+ T (STR, 5, NS, /* [] */, 5);
+ T (STR, 5, NS, /* [] */, 6);
T (STR, 5, NS, /* [] */, n);
T (STR, 6, NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
@@ -56,19 +62,22 @@ void strncmp_cst (void)
T (NS, /* [] */, STR, /* [] */, n);
T (NS, /* [] */, STR, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
- T (NS, 9, STR, /* [] */, n); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (NS, 9, STR, /* [] */, n); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \[0-9\]+" } */
T (NS, 10, STR, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
+ T (NS, /* [] */, STR, 11, 11);
T (NS, /* [] */, STR, 11, n);
T (NS, /* [] */, STR, 12, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
T (NS, /* [] */, NS, /* [] */, n);
T (NS, /* [] */, NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
- T (NS, 13, NS, /* [] */, n); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (NS, 13, NS, /* [] */, 13);
+ T (NS, 13, NS, /* [] */, n); /* { dg-warning "argument 1 declared attribute 'nonstring' is smaller than the specified bound \[0-9\]+" } */
T (NS, 14, NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
- T (NS, /* [] */, NS, 15, n); /* { dg-warning "argument 2 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (NS, /* [] */, NS, 15, 15);
+ T (NS, /* [] */, NS, 15, 16); /* { dg-warning "argument 2 declared attribute 'nonstring' is smaller than the specified bound 16" } */
T (NS, /* [] */, NS, 16, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
}
@@ -81,6 +90,7 @@ void strncmp_range (void)
T (STR, /* [] */, STR, /* [] */, n);
T (STR, /* [] */, STR, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
+ T (STR, 1, STR, /* [] */, 1);
T (STR, 1, STR, /* [] */, n);
T (STR, 2, STR, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
@@ -93,7 +103,7 @@ void strncmp_range (void)
T (STR, 5, NS, /* [] */, n);
T (STR, 6, NS, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
- T (STR, /* [] */, NS, 7, n); /* { dg-warning "argument 2 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (STR, /* [] */, NS, 7, n); /* { dg-warning "argument 2 declared attribute 'nonstring' is smaller than the specified bound \\\[\[0-9\]+, \[0-9\]+]" } */
T (STR, /* [] */, NS, 8, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
diff --git a/gcc/testsuite/gcc.dg/attr-nonstring-4.c b/gcc/testsuite/gcc.dg/attr-nonstring-4.c
index 7daff97..f2416c1 100644
--- a/gcc/testsuite/gcc.dg/attr-nonstring-4.c
+++ b/gcc/testsuite/gcc.dg/attr-nonstring-4.c
@@ -40,7 +40,7 @@ void strnlen_cst (void)
T (NS, /* [] */, n);
T (NS, /* [] */, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
- T (NS, 9, n); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (NS, 9, n); /* { dg-warning "specified bound \[0-9\]+ exceeds source size 9" } */
T (NS, 10, n + 1); /* { dg-warning "specified bound \[0-9\]+ exceeds maximum object size \[0-9\]+" } */
}
@@ -53,12 +53,12 @@ void strnlen_range (void)
T (STR, /* [] */, n);
T (STR, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
- T (STR, 1, n);
+ T (STR, 1, n); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 1" } */
T (STR, 2, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
T (NS, /* [] */, n);
T (NS, /* [] */, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
- T (NS, 9, n); /* { dg-warning "argument 1 declared attribute .nonstring. is smaller than the specified bound" } */
+ T (NS, 9, n); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds source size 9" } */
T (NS, 10, n + 1); /* { dg-warning "specified bound \\\[\[0-9\]+, \[0-9\]+] exceeds maximum object size \[0-9\]+" } */
}
diff --git a/gcc/testsuite/gcc.dg/attr-nonstring.c b/gcc/testsuite/gcc.dg/attr-nonstring.c
index 46f5c0d..d93e93c 100644
--- a/gcc/testsuite/gcc.dg/attr-nonstring.c
+++ b/gcc/testsuite/gcc.dg/attr-nonstring.c
@@ -44,80 +44,80 @@ int strcmp_nonstring_1 (NONSTRING const char *a, const char *b)
no good on its own. Use dg-regexp instead to verify that just
one instance of the warning is issued. See gcc.dg/pr64223-1
for a different approach. */
- return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcmp" } */
+ return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strcmp" } */
}
int strcmp_nonstring_2 (const char *a, NONSTRING const char *b)
{
- return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcmp" } */
+ return strcmp (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strcmp. argument 2 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strcmp" } */
}
int strncmp_nonstring_1 (const char *s)
{
- return strncmp (s, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncmp" } */
+ return strncmp (s, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overread\[^\n\r\]*" "strncmp" } */
}
int strncmp_nonstring_2 (const char *s)
{
- return strncmp (ns5, s, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 1 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncmp" } */
+ return strncmp (ns5, s, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncmp. argument 1 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overread\[^\n\r\]*" "strncmp" } */
}
char* stpcpy_nonstring (char *d, NONSTRING const char *s)
{
- return stpcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .stpcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "stpcpy" } */
+ return stpcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .stpcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "stpcpy" } */
}
char* stpncpy_nonstring (char *d)
{
- return stpncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .stpncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "stpncpy" } */
+ return stpncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .stpncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overread\[^\n\r\]*" "stpncpy" } */
}
char* strchr_nonstring (NONSTRING const char *s, int c)
{
- return strchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strchr" } */
+ return strchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strchr" } */
}
char* strrchr_nonstring (NONSTRING const char *s, int c)
{
- return strrchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strrchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strrchr" } */
+ return strrchr (s, c); /* { dg-regexp "\[^\n\r\]+: warning: .strrchr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strrchr" } */
}
char* strcpy_nonstring (char *d, NONSTRING const char *s)
{
- return strcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .strcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strcpy" } */
+ return strcpy (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .strcpy. argument 2 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strcpy" } */
}
char* strncpy_nonstring (char *d)
{
- return strncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overflow=]" "strncpy" } */
+ return strncpy (d, ns5, sizeof ns5 + 1); /* { dg-regexp "\[^\n\r\]+: warning: .strncpy. argument 2 declared attribute .nonstring. \[^\n\r\]+ \\\[-Wstringop-overread\[^\n\r\]*" "strncpy" } */
}
char* strstr_nonstring_1 (NONSTRING const char *a, const char *b)
{
- return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strstr" } */
+ return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strstr" } */
}
char* strstr_nonstring_2 (const char *a, NONSTRING const char *b)
{
- return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strstr" } */
+ return strstr (a, b); /* { dg-regexp "\[^\n\r\]+: warning: .strstr. argument 2 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strstr" } */
}
char* stdup_nonstring (NONSTRING const char *s)
{
- return strdup (s); /* { dg-regexp "\[^\n\r\]+: warning: .strdup. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strdup" } */
+ return strdup (s); /* { dg-regexp "\[^\n\r\]+: warning: .strdup. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strdup" } */
}
size_t strlen_nonstring (NONSTRING const char *s)
{
- return strlen (s); /* { dg-regexp "\[^\n\r\]+: warning: .strlen. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "strlen" } */
+ return strlen (s); /* { dg-regexp "\[^\n\r\]+: warning: .strlen. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "strlen" } */
}
int printf_nonstring (NONSTRING const char *s)
{
- return printf (s); /* { dg-regexp "\[^\n\r\]+: warning: .printf. argument 1 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "printf" } */
+ return printf (s); /* { dg-regexp "\[^\n\r\]+: warning: .printf. argument 1 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "printf" } */
}
int sprintf_nonstring_2 (char *d, NONSTRING const char *s)
{
- return sprintf (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .sprintf. argument 2 declared attribute .nonstring. \\\[-Wstringop-overflow=]" "sprintf" } */
+ return sprintf (d, s); /* { dg-regexp "\[^\n\r\]+: warning: .sprintf. argument 2 declared attribute .nonstring. \\\[-Wstringop-overread\[^\n\r\]*" "sprintf" } */
}
diff --git a/gcc/testsuite/gcc.dg/attr-section.c b/gcc/testsuite/gcc.dg/attr-section.c
new file mode 100644
index 0000000..0062b54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/attr-section.c
@@ -0,0 +1,13 @@
+/* PR c/96126 - conflicting attribute section accepted on redeclaration
+ { dg-do compile }
+ { dg-options "-Wall" }
+ { dg-require-named-sections "" } */
+
+__attribute__ ((section ("s1"))) void f1 (void);
+__attribute__ ((section ("s2"))) void f1 (void); // { dg-warning "ignoring attribute 'section \\\(\"s2\"\\\)' because it conflicts with previous 'section \\\(\"s1\"\\\)'" }
+
+__attribute__ ((section ("s3"), section ("s4")))
+void f2 (void); // { dg-error "conflicts" }
+
+__attribute__ ((section ("s5"))) __attribute ((section ("s6")))
+void f3 (void); // { dg-error "conflicts" }
diff --git a/gcc/testsuite/gcc.dg/bad-binary-ops.c b/gcc/testsuite/gcc.dg/bad-binary-ops.c
index 46c158e..45668be 100644
--- a/gcc/testsuite/gcc.dg/bad-binary-ops.c
+++ b/gcc/testsuite/gcc.dg/bad-binary-ops.c
@@ -35,10 +35,10 @@ int test_2 (void)
~~~~~~~~~~~~~~~~
|
struct s
- + some_other_function ());
- ^ ~~~~~~~~~~~~~~~~~~~~~~
- |
- struct t
+ + some_other_function ());
+ ^ ~~~~~~~~~~~~~~~~~~~~~~
+ |
+ struct t
{ dg-end-multiline-output "" } */
}
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index 06ef24e..9049af5 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
/* { dg-require-effective-target untyped_assembly } */
/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { "avr-*-* nds32*-*-* amdgcn-*-*" } } */
-/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "riscv*-*-* or1k*-*-* msp430-*-* pru-*-*" } } */
+/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs." { "csky*-*-* riscv*-*-* or1k*-*-* msp430-*-* pru-*-*" } } */
/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm*-*-* && arm_hf_eabi } } */
/* PR target/12503 */
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-21.c b/gcc/testsuite/gcc.dg/builtin-object-size-21.c
index 1c42374..7e0f85f 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-21.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-21.c
@@ -1,7 +1,8 @@
/* PR middle-end/92815 - spurious -Wstringop-overflow writing into
a flexible array of an extern struct
{ dg-do compile }
- { dg-options "-Wall -fdump-tree-optimized" } */
+ { dg-options "-Wall -fdump-tree-optimized" }
+ { dg-require-effective-target large_initializer } */
#define PTRDIFF_MAX __PTRDIFF_MAX__
diff --git a/gcc/testsuite/gcc.dg/builtin-object-size-4.c b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
index c22654d..9f159e3 100644
--- a/gcc/testsuite/gcc.dg/builtin-object-size-4.c
+++ b/gcc/testsuite/gcc.dg/builtin-object-size-4.c
@@ -170,6 +170,9 @@ test1 (void *q, int x)
r = (char *) L"abcd\0efg";
if (__builtin_object_size (r + 2, 3) != sizeof (L"abcd\0efg") - 2)
abort ();
+ /* Prevent DSE from removing calls that prevent bad combining of
+ addresses and offsets. */
+ asm volatile ("" : : "g" (&a));
}
size_t l1 = 1;
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c
index b07629d..7d5b03b 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-5.c
@@ -87,7 +87,7 @@ void test_memop_warn_local (const void *src)
memset (&b->d, 0, offsetfrom (struct B, b, d) + 1); /* { dg-warning "writing 6 bytes into a region of size 5" } */
escape (b);
- /* Same as above but clearing just elements of the second element
+ /* Same as above but clearing just members of the second element
of the array. */
memset (&b[1].a.b, 0, offsetfrom (struct B, b[1], a.b) + 1); /* { dg-warning "writing 4 bytes into a region of size 3" } */
escape (b);
diff --git a/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c b/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c
index 12d2491..f2e9c48 100644
--- a/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c
+++ b/gcc/testsuite/gcc.dg/builtin-stringop-chk-8.c
@@ -1,6 +1,6 @@
-/* Test exercising -Wstringop-overflow warnings for reading past the end. */
+/* Test exercising -Wstringop-overread warnings for reading past the end. */
/* { dg-do compile } */
-/* { dg-options "-O2 -Wstringop-overflow=1 -ftrack-macro-expansion=0" } */
+/* { dg-options "-O2 -Wstringop-overread -ftrack-macro-expansion=0" } */
#define PTRDIFF_MAX __PTRDIFF_MAX__
#define SIZE_MAX __SIZE_MAX__
@@ -73,22 +73,22 @@ void test_memop_warn_local (void *p, const void *q)
/* Verify memchr/memcmp. */
int i = R (0, 255);
- memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
- memchr ("", i, 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
- memchr ("123", i, 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
- memchr (a, i, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+ memchr ("", i, 2); /* { dg-warning "specified bound 2 exceeds source size 1" "memchr" } */
+ memchr ("", i, 2); /* { dg-warning "specified bound 2 exceeds source size 1" "memchr" } */
+ memchr ("123", i, 5); /* { dg-warning "specified bound 5 exceeds source size 4" "memchr" } */
+ memchr (a, i, sizeof a + 1); /* { dg-warning "specified bound 5 exceeds source size 4" "memchr" } */
- memcmp (p, "", 2); /* { dg-warning "reading 2 bytes from a region of size 1" } */
- memcmp (p, "123", 5); /* { dg-warning "reading 5 bytes from a region of size 4" } */
- memcmp (p, a, sizeof a + 1); /* { dg-warning "reading 5 bytes from a region of size 4" } */
+ memcmp (p, "", 2); /* { dg-warning "specified bound 2 exceeds source size 1" "memcmp" } */
+ memcmp (p, "123", 5); /* { dg-warning "specified bound 5 exceeds source size 4" "memcmp" } */
+ memcmp (p, a, sizeof a + 1); /* { dg-warning "specified bound 5 exceeds source size 4" "memcmp" } */
size_t n = PTRDIFF_MAX + (size_t)1;
- memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
- memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
+ memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" "memchr" } */
+ memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" "memcmp" } */
n = SIZE_MAX;
- memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" } */
- memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" } */
+ memchr (p, 1, n); /* { dg-warning "exceeds maximum object size" "memchr" } */
+ memcmp (p, q, n); /* { dg-warning "exceeds maximum object size" "memcmp" } */
}
/* Verify that reading beyond the end of a dynamically allocated array
@@ -117,8 +117,8 @@ void test_memop_warn_alloc (void *p)
/* Verify memchr/memcmp. */
n = sizeof *b * 2 + 1;
- memchr (b, 1, n); /* { dg-warning "reading 9 bytes from a region of size 8" "memcmp from allocated" } */
- memcmp (p, b, n); /* { dg-warning "reading 9 bytes from a region of size 8" "memcmp from allocated" } */
+ memchr (b, 1, n); /* { dg-warning "specified bound 9 exceeds source size 8" "memchr from allocated" } */
+ memcmp (p, b, n); /* { dg-warning "specified bound 9 exceeds source size 8" "memcmp from allocated" } */
}
diff --git a/gcc/testsuite/gcc.dg/c11-align-9.c b/gcc/testsuite/gcc.dg/c11-align-9.c
index 3c9cf55..6a0d424 100644
--- a/gcc/testsuite/gcc.dg/c11-align-9.c
+++ b/gcc/testsuite/gcc.dg/c11-align-9.c
@@ -2,8 +2,8 @@
are at least some alignment constraints), case of compound literals. */
/* { dg-do compile } */
/* { dg-options "-std=c11 -pedantic-errors" } */
-/* { dg-skip-if "no alignment constraints" { "avr-*-*" } } */
#include <stddef.h>
-max_align_t *p = &(_Alignas (_Alignof (char)) max_align_t) { 1 }; /* { dg-error "reduce alignment" } */
+max_align_t *p = &(_Alignas (_Alignof (char)) max_align_t) { 1 };
+/* { dg-error "reduce alignment" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/cdce3.c b/gcc/testsuite/gcc.dg/cdce3.c
index 7e85d8a..601ddf0 100644
--- a/gcc/testsuite/gcc.dg/cdce3.c
+++ b/gcc/testsuite/gcc.dg/cdce3.c
@@ -1,8 +1,9 @@
/* { dg-do compile } */
/* { dg-require-effective-target hard_float } */
/* { dg-options "-O2 -fmath-errno -fdump-tree-cdce-details -fdump-tree-optimized" } */
-/* { dg-final { scan-tree-dump "cdce3.c:10: \[^\n\r]* function call is shrink-wrapped into error conditions\." "cdce" } } */
+/* { dg-final { scan-tree-dump "cdce3.c:11: \[^\n\r]* function call is shrink-wrapped into error conditions\." "cdce" } } */
/* { dg-final { scan-tree-dump "sqrtf \\(\[^\n\r]*\\); \\\[tail call\\\]" "optimized" } } */
+/* { dg-skip-if "doesn't have a sqrtf insn" { mmix-*-* } } */
float sqrtf (float);
float foo (float x)
diff --git a/gcc/testsuite/gcc.dg/const-uniq-1.c b/gcc/testsuite/gcc.dg/const-uniq-1.c
index 0e0718b..ba7021b 100644
--- a/gcc/testsuite/gcc.dg/const-uniq-1.c
+++ b/gcc/testsuite/gcc.dg/const-uniq-1.c
@@ -20,4 +20,4 @@ int lookup2 (int i)
return a[i+1];
}
-/* { dg-final { scan-tree-dump-times "\[lL\]\\\$?C\\\.*0" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "\[lL\]\\\$?C\[.:\]*0" 2 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/darwin-sections.c b/gcc/testsuite/gcc.dg/darwin-sections.c
index 276ffa3..dbe3702 100644
--- a/gcc/testsuite/gcc.dg/darwin-sections.c
+++ b/gcc/testsuite/gcc.dg/darwin-sections.c
@@ -13,45 +13,41 @@ e_s ea;
/* { dg-final { scan-assembler ".comm\[\t \]_ub,1" } } */
/* { dg-final { scan-assembler ".comm\[\t \]_ea,1" } } */
-/* These should go into .data */
+/* These should go into __DATA,__common */
char a = 0;
short b = 0;
-/* { dg-final { scan-assembler ".globl _a.*.data.*.space\[\t \]1" } } */
-/* { dg-final { scan-assembler ".globl _b.*.data.*.space\[\t \]2" } } */
-
-/* These should go into __pu_bssN */
long long d = 0;
float e = 0;
double f = 0;
long double g = 0.L;
long long al_256 __attribute__((aligned (256))) = 0;
-/* { dg-final { scan-assembler ".zerofill __DATA,__pu_bss3,_d,8,3" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__pu_bss2,_e,4,2" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__pu_bss3,_f,8,3" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__pu_bss4,_g,16,4" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__pu_bss8,_al_256,8,8" } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_a,1,0} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_b,2,1} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_d,8,3} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_e,4,2} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_f,8,3} } } */
+/* long double can be 64 or 128 bits depending on the Darwin subtarget. */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_g,(16,4|8,3)} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__common,_al_256,8,8} } } */
-/* This should go into __zo_bss0 */
+/* These should go into __DATA,__bss */
static e_s sea;
-/* { dg-final { scan-assembler ".zerofill __DATA,__zo_bss0,_sea,1" } } */
-
-/* These should go into .static_data */
static char sa ;
static short sb ;
-/* { dg-final { scan-assembler ".static_data.*_sa:.*.space\[\t \]1" } } */
-/* { dg-final { scan-assembler ".static_data.*_sb:.*.space\[\t \]2" } } */
-
-/* These should go into _bssN */
static long long sd;
static float se ;
static double sf ;
static long double sg;
static long long sal_256 __attribute__((aligned (2048)));
-/* { dg-final { scan-assembler ".zerofill __DATA,__bss3,_sd,8,3" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__bss2,_se,4,2" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__bss3,_sf,8,3" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__bss4,_sg,16,4" } } */
-/* { dg-final { scan-assembler ".zerofill __DATA,__bss11,_sal_256,8,11" } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sea,1,0} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sa,1,0} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sb,2,1} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sd,8,3} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_se,4,2} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sf,8,3} } } */
+/* long double can be 64 or 128 bits depending on the Darwin subtarget. */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sg,(16,4|8,3)} } } */
+/* { dg-final { scan-assembler {.zerofill __DATA,__bss,_sal_256,8,11} } } */
long long foo (int x)
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-1.c
index a004042..8802bd1 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-1.c
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
int __attribute__((__aligned__(64))) i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-2.c
index 439a7da..0de960e 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-2.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
typedef int __attribute__((__aligned__(64))) i_t;
i_t i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-3.c
index 01c19cd..94db588 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-3.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
typedef int int_t;
typedef int_t __attribute__((__aligned__(64))) i_t;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-4.c
index 8418274..bc3c516 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-4.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-4.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 2 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 2 } }
struct tt {
int __attribute__((__aligned__(64))) i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-5.c
index 322ac50..86cd3a9 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-5.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
struct tt {
int i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-6.c
index 784f213..bb1895f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-6.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
struct tt {
int i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/align-as-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/align-as-1.c
index 5ef02c3..0b23580 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/align-as-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/align-as-1.c
@@ -1,6 +1,6 @@
// { dg-do compile }
// { dg-options "-O -g -dA -gno-strict-dwarf" }
// { dg-additional-options "-fno-common" { target hppa*-*-hpux* } }
-// { dg-final { scan-assembler-times " DW_AT_alignment" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times " DW_AT_alignment" 1 } }
int _Alignas(64) i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
index 24b598e..fd61296 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
@@ -1,7 +1,7 @@
/* Test to make sure the mcaro info includes a start file command for the main source */
/* { dg-do compile } */
/* { dg-options "-g3 -gdwarf -dA -fverbose-asm" } */
-/* { dg-final { scan-assembler "Start new file" { xfail { powerpc-ibm-aix* } } } } */
+/* { dg-final { scan-assembler "Start new file" } } */
#define ADD(x) (M + x)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro2.c
index 5204342..3dfa290 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro2.c
@@ -1,7 +1,7 @@
/* Test to make sure the macro info includes the predefined macros with line number 0. */
/* { dg-do compile } */
/* { dg-options "-g3 -gdwarf -dA -fverbose-asm" } */
-/* { dg-final { scan-assembler "At line number 0" { xfail { powerpc-ibm-aix* } } } } */
+/* { dg-final { scan-assembler "At line number 0" } } */
#define FOO 1
int i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
index 7e019a6..9c36450 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
@@ -14,7 +14,9 @@
properly nested DW_TAG_inlined_subroutine DIEs for third, second and first.
*/
-/* { dg-options "-O -g3 -gdwarf -dA -fgnu89-inline" } */
+/* Explicitly use dwarf-2 because dwarf-5 might use DW_FORM_implicit_const
+ which is hard to scan for. */
+/* { dg-options "-O -g3 -gdwarf-2 -dA -fgnu89-inline" } */
/* { dg-do compile } */
/* There are 6 inlined subroutines:
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c
index 7587a28..bd34f0d 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline5.c
@@ -9,7 +9,7 @@
/* We do not know which is output first so look for both invalid abstract
origins on the lexical blocks (knowing that the abstract instance has
no attribute following the DW_TAG_lexical_block. */
-/* { dg-final { scan-assembler-not "\\(DIE \\(0x(\[0-9a-f\]*)\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +\[^(\].*DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x\\1\[^#/!@;\\|\]*\[#/!@;\\|\] +DW_AT_abstract_origin" { xfail { *-*-solaris2.* && { ! gas } } } } } */
+/* { dg-final { scan-assembler-not "\\(DIE \\(0x(\[0-9a-f\]*)\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +\[^(\].*DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x\\1\[^#/!@;\\|\]*\[#/!@;\\|\] +DW_AT_abstract_origin" { xfail { { *-*-aix* || *-*-solaris2.* } && { ! gas } } } } } */
/* { dg-final { scan-assembler-not "DW_TAG_lexical_block\\)\[^#/!@;\\|x\]*x(\[0-9a-f\]*)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +DW_AT_abstract_origin.*\\(DIE \\(0x\\1\\) DW_TAG_lexical_block\\)\[^#/!@;\\|\]*\[#/!@;\\|\]+ +DW_AT" } } */
int foo (int i)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c
new file mode 100644
index 0000000..03013f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline6.c
@@ -0,0 +1,69 @@
+/* DWARF5 variant of inline2.
+ Origin: PR debug/37801
+
+ Abstract instances (DW_TAG_subroutines having the DW_AT_inline attribute)
+ of second and first were having a DW_TAG_lexical_block DIE wrongly
+ representing the inlined calls to third (in second) and to
+ second (in first). At the same time, main didn't have children
+ DW_TAG_inlined_subroutine DIEs representing the inlined calls to
+ first, second and third.
+
+ The ideal goal here is to test that we have no superfluous
+ DW_TAG_lexical_block DIE anymore, that abstract instances DIEs have
+ no descendant DIE with a DW_AT_abstract_origin attribute, and that main has
+ properly nested DW_TAG_inlined_subroutine DIEs for third, second and first.
+*/
+
+/* Explicitly use dwarf-5 which uses DW_FORM_implicit_const. */
+/* { dg-options "-O -g3 -gdwarf-5 -dA -fgnu89-inline" } */
+/* { dg-do compile } */
+
+/* There are 6 inlined subroutines:
+ - One for each subroutine inlined into main, that's 3.
+ - One for earch subroutine inline into the out of line instances
+ of third, second and first. */
+/* { dg-final { scan-assembler-times "\\(DIE \\(\[^\n\]*\\) DW_TAG_inlined_subroutine" 6 } } */
+
+/* We should have no DW_TAG_lexical_block DIEs, all inline instances
+ should have the first subblock elided to match the abstract instance
+ layout. */
+/* { dg-final { scan-assembler-times "\\(DIE \\(\[^\n\]*\\) DW_TAG_lexical_block" 0 } } */
+
+
+/* There are 3 DW_AT_inline attributes: one per abstract inline instance.
+ The value of the attribute must be 0x3, meaning the function was
+ actually inlined. */
+/* { dg-final { scan-assembler-times " DW_AT_inline \\(0x3\\)" 3 } } */
+
+volatile int *a;
+
+inline void
+third (int arg3)
+{
+ int var3 = arg3;
+ a[0] = var3;
+}
+
+inline void
+second (int arg2)
+{
+ int var2 = arg2;
+ third (var2+1);
+}
+
+inline void
+first (int arg1)
+{
+ int var1 = arg1;
+ second (var1+1);
+}
+
+int
+main ()
+{
+ int some_int = 1;
+ first (some_int);
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
index b6b4a89..6292cf8 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/lang-c89.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O -std=c89 -g -dA" } */
/* DW_LANG_C89 = 0x0001 */
-/* { dg-final { scan-assembler "0x1.*DW_AT_language" { xfail { powerpc-ibm-aix* } } } } */
+/* { dg-final { scan-assembler "0x1.*DW_AT_language" } } */
int version;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-attribute.c b/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-attribute.c
index bc2cfa5..7c8924a6 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-attribute.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-attribute.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -std=c99 -g -dA -gno-strict-dwarf" }
// Expect DW_AT_noreturn once in .debug_info and once in .debug_abbrev
-// { dg-final { scan-assembler-times "DW_AT_noreturn" 2 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times "DW_AT_noreturn" 2 } }
void __attribute__ ((noreturn))
baz (void)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-keyword.c b/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-keyword.c
index 0105e6c..ced96d1 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-keyword.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/noreturn-function-keyword.c
@@ -1,7 +1,7 @@
// { dg-do compile }
// { dg-options "-O -std=c11 -g -dA -gno-strict-dwarf" }
// Expect DW_AT_noreturn once in .debug_info and once in .debug_abbrev
-// { dg-final { scan-assembler-times "DW_AT_noreturn" 2 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times "DW_AT_noreturn" 2 } }
_Noreturn void exit (int);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
index d646f59..80300ec 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
@@ -2,7 +2,7 @@
/* Test that token after multi-line function-like macro use
gets correct locus even when preprocessing separately. */
/* { dg-do compile } */
-/* { dg-options "-save-temps -gdwarf -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-save-temps -gdwarf-2 -O0 -dA -fno-merge-debug-strings" } */
#define A(x) vari x
#define vari(x)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
index 340cb38..fbf0337 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
@@ -1,6 +1,6 @@
/* PR preprocessor/41445 */
/* { dg-do compile } */
-/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf-2 -O0 -dA -fno-merge-debug-strings" } */
#include "pr41445-5.c"
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-7.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-7.c
new file mode 100644
index 0000000..0e0de82
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-7.c
@@ -0,0 +1,16 @@
+/* PR preprocessor/41445 DWARF5 variant */
+/* Test that token after multi-line function-like macro use
+ gets correct locus even when preprocessing separately. */
+/* { dg-do compile } */
+/* { dg-options "-save-temps -gdwarf-5 -O0 -dA -fno-merge-debug-strings" } */
+
+#define A(x) vari x
+#define vari(x)
+#define B , varj
+int A(B) ;
+
+/* We want to check that both vari and varj have the same line
+ number. */
+
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^\\r\\n\]*DW_AT_decl_line \\((0xa|10)\\)" } } */
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^\\r\\n\]*DW_AT_decl_line \\((0xa|10)\\)" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-8.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-8.c
new file mode 100644
index 0000000..3a6eeb5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-8.c
@@ -0,0 +1,11 @@
+/* PR preprocessor/41445 DWARF5 variant*/
+/* { dg-do compile } */
+/* { dg-options "-gdwarf-5 -O0 -dA -fno-merge-debug-strings" } */
+
+#include "pr41445-5.c"
+
+/* We want to check that both vari and varj have the same line
+ number. */
+
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"vari\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^\\r\\n\]*DW_AT_decl_line \\((0xa|10)\\)" } } */
+/* { dg-final { scan-assembler "DW_TAG_variable\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\"varj\[^\\r\\n\]*DW_AT_name(\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*DW_AT_)*\[^\\r\\n\]*\[\\r\\n\]+\[^\\r\\n\]*\[^\\r\\n\]*DW_AT_decl_line \\((0xa|10)\\)" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c
index 3842dbc..4fd8b74 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr71855.c
@@ -8,4 +8,4 @@ foo (const char *format, ...)
{
}
-// { dg-final { scan-assembler-times "DIE.*DW_TAG_unspecified_parameters" 1 { xfail { powerpc-ibm-aix* } } } }
+// { dg-final { scan-assembler-times "DIE.*DW_TAG_unspecified_parameters" 1 } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c
new file mode 100644
index 0000000..a9c0efb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-g -gdwarf -dA" } */
+
+extern void foo (int);
+extern void unusedbar (int);
+
+int main()
+{
+ foo (1);
+}
+
+/* We want subprogram DIEs for both foo and main and a DIE for
+ the formal parameter of foo. We do not want a DIE for
+ unusedbar. */
+/* { dg-final { scan-assembler-times "DW_TAG_subprogram" 4 } } */
+/* { dg-final { scan-assembler-times "DW_TAG_formal_parameter" 2 } } */
+/* { dg-final { scan-assembler-not "unusedbar" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c
new file mode 100644
index 0000000..c3a710e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr96383-2.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-g -O2 -gdwarf -dA" } */
+
+extern void foo (int);
+extern void unusedbar (int);
+
+int main()
+{
+ foo (1);
+}
+
+/* We want subprogram DIEs for both foo and main and a DIE for
+ the formal parameter of foo. We do not want a DIE for
+ unusedbar. */
+/* { dg-final { scan-assembler-times "DW_TAG_subprogram" 4 } } */
+/* { dg-final { scan-assembler-times "DW_TAG_formal_parameter" 2 } } */
+/* { dg-final { scan-assembler-not "unusedbar" } } */
diff --git a/gcc/testsuite/gcc.dg/dfp/composite-type.c b/gcc/testsuite/gcc.dg/dfp/composite-type.c
index 6d461c7..ce7d5c1 100644
--- a/gcc/testsuite/gcc.dg/dfp/composite-type.c
+++ b/gcc/testsuite/gcc.dg/dfp/composite-type.c
@@ -53,3 +53,6 @@ int main()
return 0;
}
+
+/* The invalid function redeclarations might also trigger:
+ { dg-prune-output "-Warray-parameter" } */
diff --git a/gcc/testsuite/gcc.dg/fold-parity-1.c b/gcc/testsuite/gcc.dg/fold-parity-1.c
new file mode 100644
index 0000000..3ba56c7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-parity-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_popcount(x) & 1;
+}
+
+int fool(unsigned long x)
+{
+ return __builtin_popcountl(x) & 1;
+}
+
+int fooll(unsigned long long x)
+{
+ return __builtin_popcountll(x) & 1;
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_popcount" 0 "original" } } */
+/* { dg-final { scan-tree-dump-times "__builtin_parity" 3 "original" } } */
+
diff --git a/gcc/testsuite/gcc.dg/fold-parity-2.c b/gcc/testsuite/gcc.dg/fold-parity-2.c
new file mode 100644
index 0000000..8c7acbf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-parity-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_parity(~x);
+}
+
+int fool(unsigned long x)
+{
+ return __builtin_parityl(~x);
+}
+
+int fooll(unsigned long long x)
+{
+ return __builtin_parityll(~x);
+}
+
+/* { dg-final { scan-tree-dump-times "~" 0 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/fold-parity-3.c b/gcc/testsuite/gcc.dg/fold-parity-3.c
new file mode 100644
index 0000000..e0355cc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-parity-3.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x)
+{
+ return __builtin_parity(x&1);
+}
+
+int fool(unsigned long x)
+{
+ return __builtin_parityl(x&1);
+}
+
+int fooll(unsigned long long x)
+{
+ return __builtin_parityll(x&1);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_parity" 0 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/fold-parity-4.c b/gcc/testsuite/gcc.dg/fold-parity-4.c
new file mode 100644
index 0000000..5dfedab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-parity-4.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int foo(unsigned int x, unsigned int y)
+{
+ return __builtin_parity(x) ^ __builtin_parity(y);
+}
+
+int fool(unsigned long x, unsigned long y)
+{
+ return __builtin_parityl(x) ^ __builtin_parityl(y);
+}
+
+int fooll(unsigned long long x, unsigned long long y)
+{
+ return __builtin_parityll(x) ^ __builtin_parityll(y);
+}
+
+/* { dg-final { scan-tree-dump-times "__builtin_parity" 3 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/fold-parity-5.c b/gcc/testsuite/gcc.dg/fold-parity-5.c
new file mode 100644
index 0000000..69d3a6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-parity-5.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int test_and4(unsigned int a)
+{
+ return __builtin_parity(a&4);
+}
+
+int test_and4l(unsigned long b)
+{
+ return __builtin_parityl(b&4);
+}
+
+int test_and4ll(unsigned long long c)
+{
+ return __builtin_parityll(c&4);
+}
+
+int test_shift(unsigned int d)
+{
+ int bits = 8*sizeof(unsigned int)-1;
+ return __builtin_parity(d<<31);
+}
+
+int test_shiftl(unsigned long e)
+{
+ int bits = 8*sizeof(unsigned long)-1;
+ return __builtin_parityl(e<<bits);
+}
+
+int test_shiftll(unsigned long long f)
+{
+ int bits = 8*sizeof(unsigned long long)-1;
+ return __builtin_parityll(f<<bits);
+}
+
+/* { dg-final { scan-tree-dump-times "parity" 0 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/fold-popcount-5.c b/gcc/testsuite/gcc.dg/fold-popcount-5.c
new file mode 100644
index 0000000..943726f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-popcount-5.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int test_and4(unsigned int a)
+{
+ return __builtin_popcount(a&4);
+}
+
+int test_and4l(unsigned long b)
+{
+ return __builtin_popcountl(b&4);
+}
+
+int test_and4ll(unsigned long long c)
+{
+ return __builtin_popcountll(c&4);
+}
+
+int test_shift(unsigned int d)
+{
+ int bits = 8*sizeof(unsigned int)-1;
+ return __builtin_popcount(d<<31);
+}
+
+int test_shiftl(unsigned long e)
+{
+ int bits = 8*sizeof(unsigned long)-1;
+ return __builtin_popcountl(e<<bits);
+}
+
+int test_shiftll(unsigned long long f)
+{
+ int bits = 8*sizeof(unsigned long long)-1;
+ return __builtin_popcountll(f<<bits);
+}
+
+/* { dg-final { scan-tree-dump-times "popcount" 0 "optimized" } } */
+
diff --git a/gcc/testsuite/gcc.dg/format/branch-1.c b/gcc/testsuite/gcc.dg/format/branch-1.c
index 1782064..4ea39b5 100644
--- a/gcc/testsuite/gcc.dg/format/branch-1.c
+++ b/gcc/testsuite/gcc.dg/format/branch-1.c
@@ -10,7 +10,7 @@ foo (long l, int nfoo)
{
printf ((nfoo > 1) ? "%d foos" : "%d foo", nfoo);
printf ((l > 1) ? "%d foos" /* { dg-warning "23:int" "wrong type in conditional expr" } */
- : "%d foo", l); /* { dg-warning "16:int" "wrong type in conditional expr" } */
+ : "%d foo", l); /* { dg-warning "23:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%ld foos" : "%d foo", l); /* { dg-warning "36:int" "wrong type in conditional expr" } */
printf ((l > 1) ? "%d foos" : "%ld foo", l); /* { dg-warning "23:int" "wrong type in conditional expr" } */
/* Should allow one case to have extra arguments. */
diff --git a/gcc/testsuite/gcc.dg/format/pr79210.c b/gcc/testsuite/gcc.dg/format/pr79210.c
index 71f5dd6..6bdabdf 100644
--- a/gcc/testsuite/gcc.dg/format/pr79210.c
+++ b/gcc/testsuite/gcc.dg/format/pr79210.c
@@ -20,4 +20,4 @@ LPFC_VPORT_ATTR_R(peer_port_login,
"Allow peer ports on the same physical port to login to each "
"other.");
-/* { dg-warning "6: format .%d. expects argument of type .int., but argument 4 has type .unsigned int. " "" { target *-*-* } .-12 } */
+/* { dg-warning "20: format .%d. expects argument of type .int., but argument 4 has type .unsigned int. " "" { target *-*-* } .-12 } */
diff --git a/gcc/testsuite/gcc.dg/format/pr96935.c b/gcc/testsuite/gcc.dg/format/pr96935.c
new file mode 100644
index 0000000..c311097
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/format/pr96935.c
@@ -0,0 +1,9 @@
+/* PR preprocessor/96935 */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+void
+foo (char const *name)
+{
+ /* xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx */ __builtin_printf ("%s", name);
+}
diff --git a/gcc/testsuite/gcc.dg/gimplefe-44.c b/gcc/testsuite/gcc.dg/gimplefe-44.c
index a9a92b1..3c83d49 100644
--- a/gcc/testsuite/gcc.dg/gimplefe-44.c
+++ b/gcc/testsuite/gcc.dg/gimplefe-44.c
@@ -1,5 +1,7 @@
/* { dg-do compile } */
+/* { dg-require-effective-target exceptions } */
/* { dg-options "-fexceptions -fgimple -fdump-tree-eh-eh" } */
+/* { dg-require-effective-target nonlocal_goto } */
void __GIMPLE foo()
{
diff --git a/gcc/testsuite/gcc.dg/gomp/block-7.c b/gcc/testsuite/gcc.dg/gomp/block-7.c
index 6219e7e..3e87464 100644
--- a/gcc/testsuite/gcc.dg/gomp/block-7.c
+++ b/gcc/testsuite/gcc.dg/gomp/block-7.c
@@ -6,15 +6,15 @@ void foo()
for (i = 0; i < 10; ++i)
{
#pragma omp for
- for (j = ({ continue; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
- j < ({ continue; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
- j += ({ continue; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
+ for (j = ({ continue; 0; }); // { dg-error "invalid exit from OpenMP structured block" }
+ j < ({ continue; 10; }); // { dg-error "invalid exit from OpenMP structured block" }
+ j += ({ continue; 1; })) // { dg-error "invalid exit from OpenMP structured block" }
continue;
#pragma omp for
- for (j = ({ break; 0; }); // { dg-error "invalid branch to/from OpenMP structured block" }
- j < ({ break; 10; }); // { dg-error "invalid branch to/from OpenMP structured block" }
- j += ({ break; 1; })) // { dg-error "invalid branch to/from OpenMP structured block" }
+ for (j = ({ break; 0; }); // { dg-error "invalid exit from OpenMP structured block" }
+ j < ({ break; 10; }); // { dg-error "invalid exit from OpenMP structured block" }
+ j += ({ break; 1; })) // { dg-error "invalid exit from OpenMP structured block" }
break; // { dg-error "break" }
}
}
diff --git a/gcc/testsuite/gcc.dg/gomp/gomp.exp b/gcc/testsuite/gcc.dg/gomp/gomp.exp
index 2414c22..8a7f18e 100644
--- a/gcc/testsuite/gcc.dg/gomp/gomp.exp
+++ b/gcc/testsuite/gcc.dg/gomp/gomp.exp
@@ -31,7 +31,7 @@ dg-init
# Main loop.
dg-runtest [lsort [concat \
[find $srcdir/$subdir *.c] \
- [find $srcdir/c-c++-common/gomp *.c]]] "" "-fopenmp -Wno-hsa"
+ [find $srcdir/c-c++-common/gomp *.c]]] "" "-fopenmp"
# All done.
dg-finish
diff --git a/gcc/testsuite/gcc.dg/gomp/simd-2.c b/gcc/testsuite/gcc.dg/gomp/simd-2.c
new file mode 100644
index 0000000..7ac3eb4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/simd-2.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[1-9]\[0-9]* loops in function" 5 "vect" } } */
+
+int a[10000][128];
+
+void
+foo (void)
+{
+ #pragma omp for simd schedule (simd: dynamic, 32) collapse(2)
+ for (int i = 0; i < 10000; i++)
+ for (int j = 0; j < 128; j++)
+ a[i][j] += 3;
+}
+
+void
+bar (void)
+{
+ #pragma omp parallel for simd schedule (simd: dynamic, 32) collapse(2)
+ for (int i = 0; i < 10000; i++)
+ for (int j = 0; j < 128; j++)
+ a[i][j] += 3;
+}
+
+void
+baz (void)
+{
+ #pragma omp distribute parallel for simd schedule (simd: dynamic, 32) collapse(2)
+ for (int i = 0; i < 10000; i++)
+ for (int j = 0; j < 128; j++)
+ a[i][j] += 3;
+}
+
+void
+qux (void)
+{
+ #pragma omp distribute simd dist_schedule (static, 128) collapse(2)
+ for (int i = 0; i < 10000; i++)
+ for (int j = 0; j < 128; j++)
+ a[i][j] += 3;
+}
+
+void
+corge (void)
+{
+ #pragma omp taskloop simd collapse(2)
+ for (int i = 0; i < 10000; i++)
+ for (int j = 0; j < 128; j++)
+ a[i][j] += 3;
+}
diff --git a/gcc/testsuite/gcc.dg/gomp/simd-3.c b/gcc/testsuite/gcc.dg/gomp/simd-3.c
new file mode 100644
index 0000000..13e1346
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gomp/simd-3.c
@@ -0,0 +1,51 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -fdump-tree-vect-details" } */
+/* { dg-additional-options "-mavx" { target avx } } */
+/* { dg-final { scan-tree-dump-times "vectorized \[1-9]\[0-9]* loops in function" 5 "vect" } } */
+
+int a[1024][1024];
+
+void
+foo (void)
+{
+ #pragma omp for simd collapse(2)
+ for (int i = 0; i < 1024; i++)
+ for (int j = 0; j < i; j++)
+ a[i][j] += 3;
+}
+
+void
+bar (void)
+{
+ #pragma omp parallel for simd collapse(2)
+ for (int i = 0; i < 1024; i++)
+ for (int j = 0; j < i; j++)
+ a[i][j] += 3;
+}
+
+void
+baz (void)
+{
+ #pragma omp distribute parallel for simd collapse(2)
+ for (int i = 0; i < 1024; i++)
+ for (int j = 0; j < i; j++)
+ a[i][j] += 3;
+}
+
+void
+qux (void)
+{
+ #pragma omp distribute simd collapse(2)
+ for (int i = 0; i < 1024; i++)
+ for (int j = 0; j < i; j++)
+ a[i][j] += 3;
+}
+
+void
+corge (void)
+{
+ #pragma omp taskloop simd collapse(2)
+ for (int i = 0; i < 1024; i++)
+ for (int j = 0; j < i; j++)
+ a[i][j] += 3;
+}
diff --git a/gcc/testsuite/gcc.dg/ia64-sync-5.c b/gcc/testsuite/gcc.dg/ia64-sync-5.c
new file mode 100644
index 0000000..a3923b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ia64-sync-5.c
@@ -0,0 +1,83 @@
+/* { dg-do run } */
+/* { dg-require-effective-target sync_char_short } */
+/* { dg-options } */
+/* { dg-options "-march=i486" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
+/* { dg-options "-mcpu=v9" { target sparc*-*-* } } */
+
+/* Test basic functionality of the intrinsics. */
+
+/* This is a copy of gcc.dg/ia64-sync-3.c, for 8-bit and 16-bit. */
+
+__extension__ typedef __SIZE_TYPE__ size_t;
+
+extern void abort (void);
+extern void *memcpy (void *, const void *, size_t);
+extern int memcmp (const void *, const void *, size_t);
+
+static signed char AC[4];
+static signed char init_qi[4] = { -30,-30,-50,-50 };
+static signed char test_qi[4] = { -115,-115,25,25 };
+
+static void
+do_qi (void)
+{
+ if (__sync_val_compare_and_swap(AC+0, -30, -115) != -30)
+ abort ();
+ if (__sync_val_compare_and_swap(AC+0, -30, -115) != -115)
+ abort ();
+ if (__sync_bool_compare_and_swap(AC+1, -30, -115) != 1)
+ abort ();
+ if (__sync_bool_compare_and_swap(AC+1, -30, -115) != 0)
+ abort ();
+
+ if (__sync_val_compare_and_swap(AC+2, AC[2], 25) != -50)
+ abort ();
+ if (__sync_val_compare_and_swap(AC+2, AC[2], 25) != 25)
+ abort ();
+ if (__sync_bool_compare_and_swap(AC+3, AC[3], 25) != 1)
+ abort ();
+ if (__sync_bool_compare_and_swap(AC+3, AC[3], 25) != 1)
+ abort ();
+}
+
+static short AS[4];
+static short init_hi[4] = { -30,-30,-50,-50 };
+static short test_hi[4] = { -115,-115,25,25 };
+
+static void
+do_hi (void)
+{
+ if (__sync_val_compare_and_swap(AS+0, -30, -115) != -30)
+ abort ();
+ if (__sync_val_compare_and_swap(AS+0, -30, -115) != -115)
+ abort ();
+ if (__sync_bool_compare_and_swap(AS+1, -30, -115) != 1)
+ abort ();
+ if (__sync_bool_compare_and_swap(AS+1, -30, -115) != 0)
+ abort ();
+
+ if (__sync_val_compare_and_swap(AS+2, AS[2], 25) != -50)
+ abort ();
+ if (__sync_val_compare_and_swap(AS+2, AS[2], 25) != 25)
+ abort ();
+ if (__sync_bool_compare_and_swap(AS+3, AS[3], 25) != 1)
+ abort ();
+ if (__sync_bool_compare_and_swap(AS+3, AS[3], 25) != 1)
+ abort ();
+}
+
+int main()
+{
+ memcpy(AC, init_qi, sizeof(init_qi));
+ memcpy(AS, init_hi, sizeof(init_hi));
+
+ do_qi ();
+ do_hi ();
+
+ if (memcmp (AC, test_qi, sizeof(test_qi)))
+ abort ();
+ if (memcmp (AS, test_hi, sizeof(test_hi)))
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ifcvt-3.c b/gcc/testsuite/gcc.dg/ifcvt-3.c
index b250bc1..56fdd75 100644
--- a/gcc/testsuite/gcc.dg/ifcvt-3.c
+++ b/gcc/testsuite/gcc.dg/ifcvt-3.c
@@ -11,7 +11,7 @@ foo (s64 a, s64 b, s64 c)
if (d == 0)
return a + c;
else
- return b + d + c;
+ return b + c + d;
}
/* This test can be reduced to just return a + c; */
diff --git a/gcc/testsuite/gcc.dg/independent-cloneids-1.c b/gcc/testsuite/gcc.dg/independent-cloneids-1.c
index 61c1203..efbc1c5 100644
--- a/gcc/testsuite/gcc.dg/independent-cloneids-1.c
+++ b/gcc/testsuite/gcc.dg/independent-cloneids-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fipa-cp -fipa-cp-clone" } */
+/* { dg-options "-O3 -fipa-cp -fipa-cp-clone -fdump-rtl-final" } */
+/* { dg-skip-if "Odd label definition syntax" { mmix-*-* } } */
extern int printf (const char *, ...);
@@ -28,11 +29,11 @@ baz (int arg)
return foo (8);
}
-/* { dg-final { scan-assembler-times {(?n)^_*bar[.$_]constprop[.$_]0:} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^_*bar[.$_]constprop[.$_]1:} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^_*bar[.$_]constprop[.$_]2:} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^_*foo[.$_]constprop[.$_]0:} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^_*foo[.$_]constprop[.$_]1:} 1 } } */
-/* { dg-final { scan-assembler-times {(?n)^_*foo[.$_]constprop[.$_]2:} 1 } } */
-/* { dg-final { scan-assembler-not {(?n)^_*foo[.$_]constprop[.$_]3:} } } */
-/* { dg-final { scan-assembler-not {(?n)^_*foo[.$_]constprop[.$_]4:} } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function bar.constprop \(bar[.$_]constprop[.$_]0,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function bar.constprop \(bar[.$_]constprop[.$_]1,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function bar.constprop \(bar[.$_]constprop[.$_]2,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function foo.constprop \(foo[.$_]constprop[.$_]0,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function foo.constprop \(foo[.$_]constprop[.$_]1,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function foo.constprop \(foo[.$_]constprop[.$_]2,} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function foo.constprop \(foo[.$_]constprop[.$_]3,} 0 "final" } } */
+/* { dg-final { scan-rtl-dump-times {(?n)^;; Function foo.constprop \(foo[.$_]constprop[.$_]4,} 0 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c
index d513020..53ae25a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-clone-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-ipa-cp-details -fno-early-inlining --param ipa-cp-max-recursive-depth=8" } */
+/* { dg-options "-O3 -fdump-ipa-cp-details -fno-early-inlining --param ipa-cp-max-recursive-depth=8 --param=ipa-cp-eval-threshold=400" } */
int fn();
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
index 93dd871..e7bf6d4 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-13.c
@@ -1,5 +1,5 @@
/* { dg-do link } */
-/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details -fdump-tree-fre3 -fno-ipa-icf" } */
+/* { dg-options "-O2 -fipa-pta -fdump-ipa-pta2-details -fdump-tree-fre3 -fno-ipa-icf -fno-ipa-modref" } */
static int x, y;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
index 4a22e39..df7e356 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-1.c
@@ -24,7 +24,7 @@ ox (struct bovid cow)
}
int
-main (int argc, char *argv[])
+main (int argc, char **argv)
{
struct bovid cow;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c
index 4d9057e..0cc76bd 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-12.c
@@ -34,7 +34,7 @@ bar (struct S s)
}
int
-main (int argc, char *argv[])
+main (int argc, char **argv)
{
struct S s;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c
index 4d4ed74..e8751da 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-13.c
@@ -33,7 +33,7 @@ bar (struct S *s)
}
int
-main (int argc, char *argv[])
+main (int argc, char **argv)
{
struct S s;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c
index 3ca302c..75619c6 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-14.c
@@ -43,7 +43,7 @@ bar (struct S s)
}
int
-main (int argc, char *argv[])
+main (int argc, char **argv)
{
struct S s;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c b/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c
index 6c57c7b..aa13a94 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-sra-15.c
@@ -45,7 +45,7 @@ bar (struct S *s, int rec)
volatile int g;
int
-main (int argc, char *argv[])
+main (int argc, char **argv)
{
struct S s;
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-loophint-1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-loophint-1.c
new file mode 100644
index 0000000..6d049af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-loophint-1.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+extern int *o, *p, *q, *r;
+
+#define FUNCTIONS fa(), fb(), fc(), fd(), fe(), ff(), fg()
+
+extern void FUNCTIONS;
+
+void foo (int c)
+{
+ FUNCTIONS;
+ FUNCTIONS;
+ for (int i = 0; i < 100; i++)
+ {
+ for (int j = 0; j < c; j++)
+ o[i] = p[i] + q[i] * r[i];
+ }
+ FUNCTIONS;
+ FUNCTIONS;
+}
+
+void bar()
+{
+ foo (8);
+ p[4]++;
+}
+
+/* { dg-final { scan-ipa-dump {with known iterations:[1-9]} "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr96482-2.c b/gcc/testsuite/gcc.dg/ipa/pr96482-2.c
new file mode 100644
index 0000000..54b71ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr96482-2.c
@@ -0,0 +1,33 @@
+/* PR ipa/96482 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+int i2c_transfer();
+void _dev_err();
+
+struct i2c_msg {
+ char bufaddr;
+ int adapterdev;
+} wdt87xx_i2c_xfer_client;
+
+int wdt87xx_i2c_xfer_client_0, wdt87xx_i2c_xfer_rxdata, wdt87xx_get_string_str_idx;
+
+void
+static wdt87xx_i2c_xfer(void *txdata, unsigned rxlen) {
+ struct i2c_msg msgs[] = {wdt87xx_i2c_xfer_client_0, rxlen,
+ wdt87xx_i2c_xfer_rxdata};
+ int error = i2c_transfer(wdt87xx_i2c_xfer_client, msgs);
+ _dev_err("", __func__, error);
+}
+static void wdt87xx_get_string(unsigned len) {
+ char tx_buf[] = {wdt87xx_get_string_str_idx, 3};
+ int rx_len = len + 2;
+ wdt87xx_i2c_xfer(tx_buf, rx_len);
+}
+
+void
+wdt87xx_ts_probe_tx_buf() {
+ wdt87xx_get_string(34);
+ wdt87xx_get_string(8);
+ wdt87xx_i2c_xfer(wdt87xx_ts_probe_tx_buf, 2);
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr96482.c b/gcc/testsuite/gcc.dg/ipa/pr96482.c
new file mode 100644
index 0000000..68ead79
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr96482.c
@@ -0,0 +1,44 @@
+/* PR ipa/96482 */
+/* { dg-do run } */
+/* { dg-options "-O2 -flto" } */
+/* { dg-require-effective-target lto } */
+
+int
+__attribute__((noinline))
+foo(int arg)
+{
+ if (arg == 3)
+ return 1;
+ if (arg == 4)
+ return 123;
+
+ __builtin_unreachable ();
+}
+
+int
+__attribute__((noinline))
+baz(int x)
+{
+ if (x != 0)
+ return foo(3); /* called */
+
+ return 1;
+}
+
+int
+__attribute__((noinline))
+bar(int x)
+{
+ if (x == 0)
+ return foo(5); /* not executed */
+
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ if (bar(argc) != baz(argc))
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/remref-2a.c b/gcc/testsuite/gcc.dg/ipa/remref-2a.c
index 34a6188..c2f3eac 100644
--- a/gcc/testsuite/gcc.dg/ipa/remref-2a.c
+++ b/gcc/testsuite/gcc.dg/ipa/remref-2a.c
@@ -1,7 +1,7 @@
/* Verify that indirect inlining can also remove references of the functions it
discovers calls for. */
/* { dg-do compile } */
-/* { dg-options "-O3 -fno-early-inlining -fno-ipa-cp -fdump-ipa-inline -fdump-tree-optimized -fno-ipa-icf" } */
+/* { dg-options "-O3 -fno-early-inlining -fno-ipa-cp -fdump-ipa-inline -fdump-tree-optimized -fno-ipa-icf -fno-ipa-modref" } */
int global;
diff --git a/gcc/testsuite/gcc.dg/ipa/symver1.c b/gcc/testsuite/gcc.dg/ipa/symver1.c
new file mode 100644
index 0000000..2cd0258
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/symver1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-skip-if "only works for ELF targets" { *-*-darwin* *-*-aix* } } */
+
+__attribute__ ((__symver__ ("foo@VER_2")))
+__attribute__ ((__symver__ ("foo@VER_3")))
+int foo()
+{
+ return 2;
+}
+
+/* { dg-final { scan-assembler ".symver.*foo, foo@VER_2" } } */
+/* { dg-final { scan-assembler ".symver.*foo, foo@VER_3" } } */
diff --git a/gcc/testsuite/gcc.dg/loop-8.c b/gcc/testsuite/gcc.dg/loop-8.c
index 1eefccc..af317d8 100644
--- a/gcc/testsuite/gcc.dg/loop-8.c
+++ b/gcc/testsuite/gcc.dg/loop-8.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-rtl-loop2_invariant" } */
-/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-*" } } */
+/* { dg-skip-if "unexpected IV" { "hppa*-*-* mips*-*-* visium-*-* powerpc*-*-* riscv*-*-* mmix-*-*" } } */
/* Load immediate on condition is available from z13 on and prevents moving
the load out of the loop, so always run this test with -march=zEC12 that
does not have load immediate on condition. */
diff --git a/gcc/testsuite/gcc.dg/lto/modref-1_0.c b/gcc/testsuite/gcc.dg/lto/modref-1_0.c
new file mode 100644
index 0000000..8fcb9ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-1_0.c
@@ -0,0 +1,14 @@
+/* { dg-lto-do run } */
+/* { dg-lto-options {"-O2 -flto-partition=max -flto"} } */
+extern void recursive (int *a, int *b, int *c, int level);
+int
+main()
+{
+ int x = 123, y=124, z=125;
+ recursive (&x,&y,&z,1);
+ if (y)
+ __builtin_abort ();
+ if (!__builtin_constant_p (z))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/modref-1_1.c b/gcc/testsuite/gcc.dg/lto/modref-1_1.c
new file mode 100644
index 0000000..c7c0eae
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/modref-1_1.c
@@ -0,0 +1,13 @@
+short aa;
+void
+__attribute__ ((noinline, noclone))
+recursive (int *a, int *b, int *c, int level)
+{
+ if (level && c)
+ {
+ recursive (b,a,c,0);
+ aa++;
+ }
+ else
+ *a=0;
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291.h b/gcc/testsuite/gcc.dg/lto/pr96291.h
new file mode 100644
index 0000000..70eb3cb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291.h
@@ -0,0 +1,4 @@
+void e(void);
+void f(void);
+void a(void *, void *);
+void c(int);
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_0.c b/gcc/testsuite/gcc.dg/lto/pr96291_0.c
new file mode 100644
index 0000000..07e6303
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_0.c
@@ -0,0 +1,11 @@
+/* { dg-lto-do link } */
+
+#include "pr96291.h"
+
+static void * b;
+void c(int d) {
+ f();
+ a(b, b);
+}
+
+void e(void) { c(0); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_1.c b/gcc/testsuite/gcc.dg/lto/pr96291_1.c
new file mode 100644
index 0000000..44744a9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_1.c
@@ -0,0 +1,3 @@
+#include "pr96291.h"
+
+void f(void) { c(0); }
diff --git a/gcc/testsuite/gcc.dg/lto/pr96291_2.c b/gcc/testsuite/gcc.dg/lto/pr96291_2.c
new file mode 100644
index 0000000..5febffb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr96291_2.c
@@ -0,0 +1,7 @@
+/* { dg-options {-O0} } */
+
+#include "pr96291.h"
+
+void a(void * a1, void * a2) { e(); }
+
+int main(){}
diff --git a/gcc/testsuite/gcc.dg/memchr-2.c b/gcc/testsuite/gcc.dg/memchr-2.c
new file mode 100644
index 0000000..61357f9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memchr-2.c
@@ -0,0 +1,41 @@
+/* PR tree-optimization/96670 - ICE on memchr with an empty initializer
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+struct {
+ int i, j;
+} const s = { };
+
+void memchr_success_unused (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ __builtin_memchr (p, '\0', n);
+}
+
+void memchr_success_used (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ if (&s != __builtin_memchr (p, '\0', n))
+ __builtin_abort ();
+}
+
+void memchr_fail_unused (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ __builtin_memchr (p, '\5', n);
+}
+
+void memchr_fail_used (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ if (__builtin_memchr (p, '\5', n))
+ __builtin_abort ();
+}
+
+/* { dg-prune-output "\\\[-Wunused-value" }
+ { dg-final { scan-tree-dump-not "abort" "optimized" } }
+ { dg-final { scan-tree-dump-not "memcmp \\(" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memchr.c b/gcc/testsuite/gcc.dg/memchr.c
new file mode 100644
index 0000000..fb21d58
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memchr.c
@@ -0,0 +1,94 @@
+/* PR middle-end/78257 - missing memcmp optimization with constant arrays
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern void* memchr (const void*, int, size_t);
+
+/* Verify that initializers for flexible array members are handled
+ correctly. */
+
+struct SX
+{
+ /* offset */
+ /* 0 */ int32_t n;
+ /* 4 */ int8_t: 1;
+ /* 6 */ int16_t a[];
+};
+
+_Static_assert (__builtin_offsetof (struct SX, a) == 6);
+
+const struct SX sx =
+ {
+ 0x11121314, { 0x2122, 0x3132, 0x4142, 0x5152 }
+ };
+
+const char sx_rep[] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ 0x11, 0x12, 0x13, 0x14, 0, 0, 0x21, 0x22, 0x31, 0x32, 0x41, 0x42, 0x51, 0x52
+#else
+ 0x14, 0x13, 0x12, 0x11, 0, 0, 0x22, 0x21, 0x32, 0x31, 0x42, 0x41, 0x52, 0x51
+#endif
+ };
+
+
+void test_find (void)
+{
+ int n = 0, nb = (const char*)&sx.a[4] - (const char*)&sx;
+ const char *p = (const char*)&sx, *q = sx_rep;
+
+ if (nb != sizeof sx_rep)
+ __builtin_abort ();
+
+ n += p == memchr (p, q[ 0], nb);
+ n += p + 1 == memchr (p, q[ 1], nb);
+ n += p + 2 == memchr (p, q[ 2], nb);
+ n += p + 3 == memchr (p, q[ 3], nb);
+ n += p + 4 == memchr (p, q[ 4], nb);
+ n += p + 4 == memchr (p, q[ 5], nb);
+ n += p + 6 == memchr (p, q[ 6], nb);
+ n += p + 7 == memchr (p, q[ 7], nb);
+ n += p + 8 == memchr (p, q[ 8], nb);
+ n += p + 9 == memchr (p, q[ 9], nb);
+ n += p + 10 == memchr (p, q[10], nb);
+ n += p + 11 == memchr (p, q[11], nb);
+ n += p + 12 == memchr (p, q[12], nb);
+ n += p + 13 == memchr (p, q[13], nb);
+
+ if (n != 14)
+ __builtin_abort ();
+}
+
+void test_not_find (void)
+{
+ int n = 0, nb = (const char*)&sx.a[4] - (const char*)&sx;
+ const char *p = (const char*)&sx, *q = sx_rep;
+
+ if (nb != sizeof sx_rep)
+ __builtin_abort ();
+
+ n += 0 == memchr (p, 0xff, nb);
+ n += 0 == memchr (p + 1, q[ 0], nb - 1);
+ n += 0 == memchr (p + 2, q[ 1], nb - 2);
+ n += 0 == memchr (p + 3, q[ 2], nb - 3);
+ n += 0 == memchr (p + 4, q[ 3], nb - 4);
+ n += 0 == memchr (p + 6, q[ 4], nb - 6);
+ n += 0 == memchr (p + 7, q[ 6], nb - 7);
+ n += 0 == memchr (p + 8, q[ 7], nb - 8);
+ n += 0 == memchr (p + 9, q[ 8], nb - 9);
+ n += 0 == memchr (p + 10, q[ 9], nb - 10);
+ n += 0 == memchr (p + 11, q[10], nb - 11);
+ n += 0 == memchr (p + 12, q[11], nb - 12);
+ n += 0 == memchr (p + 13, q[12], nb - 13);
+ n += 0 == memchr (p + 14, q[13], nb - 14);
+
+ if (n != 14)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memcmp-2.c b/gcc/testsuite/gcc.dg/memcmp-2.c
new file mode 100644
index 0000000..ff99c12
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-2.c
@@ -0,0 +1,183 @@
+/* PR middle-end/78257 - missing memcmp optimization with constant arrays
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+#define assert(e) ((e) ? (void)0 : __builtin_abort ())
+
+typedef __INT32_TYPE__ int32_t;
+
+extern int memcmp (const void*, const void*, __SIZE_TYPE__);
+
+const int32_t i_0 = 0;
+const int32_t j_0 = 0;
+
+void eq_i0_j0 (void)
+{
+ const char *pi = (char*)&i_0, *pj = (char*)&j_0;
+ int n = 0;
+
+ n += 0 == memcmp (pi, pj, sizeof (int32_t));
+ n += 0 == memcmp (pi + 1, pj + 1, sizeof (int32_t) - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, sizeof (int32_t) - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, sizeof (int32_t) - 3);
+ n += 0 == memcmp (pi + 4, pj + 4, sizeof (int32_t) - 4);
+
+ assert (n == 5);
+}
+
+
+const int32_t i1234 = 1234;
+const int32_t j1234 = 1234;
+
+void eq_i1234_j1245 (void)
+{
+ const char *pi = (char*)&i1234, *pj = (char*)&j1234;
+ int n = 0;
+
+ n += 0 == memcmp (pi, pj, sizeof (int32_t));
+ n += 0 == memcmp (pi + 1, pj + 1, sizeof (int32_t) - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, sizeof (int32_t) - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, sizeof (int32_t) - 3);
+ n += 0 == memcmp (pi + 4, pj + 4, sizeof (int32_t) - 4);
+
+ assert (n == 5);
+}
+
+
+const int32_t a1[2] = { 1234 };
+const int32_t b1[2] = { 1234 };
+
+void eq_a1_b1 (void)
+{
+ const char *pi = (char*)&a1, *pj = (char*)&b1;
+ int n = 0, nb = sizeof a1;
+
+ n += 0 == memcmp (pi, pj, nb);
+ n += 0 == memcmp (pi + 1, pj + 1, nb - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, nb - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, nb - 3);
+ n += 0 == memcmp (pi + 4, pj + 4, nb - 4);
+ n += 0 == memcmp (pi + 5, pj + 5, nb - 5);
+ n += 0 == memcmp (pi + 6, pj + 6, nb - 6);
+ n += 0 == memcmp (pi + 7, pj + 7, nb - 7);
+ n += 0 == memcmp (pi + 8, pj + 8, nb - 8);
+
+ assert (n == 9);
+}
+
+const int32_t a2[2] = { 1234 };
+const int32_t b2[2] = { 1234, 0 };
+
+void eq_a2_b2 (void)
+{
+ const char *pi = (char*)&a2, *pj = (char*)&b2;
+ int n = 0, nb = sizeof a2;
+
+ n += 0 == memcmp (pi, pj, nb);
+ n += 0 == memcmp (pi + 1, pj + 1, nb - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, nb - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, nb - 3);
+ n += 0 == memcmp (pi + 4, pj + 4, nb - 4);
+ n += 0 == memcmp (pi + 5, pj + 5, nb - 5);
+ n += 0 == memcmp (pi + 6, pj + 6, nb - 6);
+ n += 0 == memcmp (pi + 7, pj + 7, nb - 7);
+ n += 0 == memcmp (pi + 8, pj + 8, nb - 8);
+
+ assert (n == 9);
+}
+
+
+const int32_t a5[5] = { [3] = 1234, [1] = 0 };
+const int32_t b5[5] = { 0, 0, 0, 1234 };
+
+void eq_a5_b5 (void)
+{
+ int n = 0, b = sizeof a5;
+ const char *pi = (char*)a5, *pj = (char*)b5;
+
+ n += 0 == memcmp (pi, pj, b);
+ n += 0 == memcmp (pi + 1, pj + 1, b - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, b - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, b - 3);
+
+ n += 0 == memcmp (pi + 4, pj + 4, b - 4);
+ n += 0 == memcmp (pi + 5, pj + 5, b - 5);
+ n += 0 == memcmp (pi + 6, pj + 6, b - 6);
+ n += 0 == memcmp (pi + 7, pj + 7, b - 7);
+
+ n += 0 == memcmp (pi + 8, pj + 8, b - 8);
+ n += 0 == memcmp (pi + 9, pj + 9, b - 9);
+ n += 0 == memcmp (pi + 10, pj + 10, b - 10);
+ n += 0 == memcmp (pi + 11, pj + 11, b - 11);
+
+ n += 0 == memcmp (pi + 12, pj + 12, b - 12);
+ n += 0 == memcmp (pi + 13, pj + 13, b - 13);
+ n += 0 == memcmp (pi + 14, pj + 14, b - 14);
+ n += 0 == memcmp (pi + 15, pj + 15, b - 15);
+
+ n += 0 == memcmp (pi + 16, pj + 16, b - 16);
+ n += 0 == memcmp (pi + 17, pj + 17, b - 17);
+ n += 0 == memcmp (pi + 18, pj + 18, b - 18);
+ n += 0 == memcmp (pi + 19, pj + 19, b - 19);
+
+ assert (n == 20);
+}
+
+
+const int32_t a19[19] = { [13] = 13, [8] = 8, [4] = 4, [1] = 1 };
+const int32_t b19[19] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
+
+void eq_a19_b19 (void)
+{
+ int n = 0, b = sizeof a19;
+ const char *pi = (char*)a19, *pj = (char*)b19;
+
+ n += 0 == memcmp (pi, pj, b);
+ n += 0 == memcmp (pi + 1, pj + 1, b - 1);
+ n += 0 == memcmp (pi + 2, pj + 2, b - 2);
+ n += 0 == memcmp (pi + 3, pj + 3, b - 3);
+
+ n += 0 == memcmp (pi + 14, pj + 14, b - 14);
+ n += 0 == memcmp (pi + 15, pj + 15, b - 15);
+ n += 0 == memcmp (pi + 16, pj + 16, b - 16);
+ n += 0 == memcmp (pi + 17, pj + 17, b - 17);
+
+ n += 0 == memcmp (pi + 28, pj + 28, b - 28);
+ n += 0 == memcmp (pi + 29, pj + 29, b - 29);
+ n += 0 == memcmp (pi + 30, pj + 30, b - 30);
+ n += 0 == memcmp (pi + 31, pj + 31, b - 31);
+
+ n += 0 == memcmp (pi + 42, pj + 42, b - 42);
+ n += 0 == memcmp (pi + 43, pj + 43, b - 43);
+ n += 0 == memcmp (pi + 44, pj + 44, b - 44);
+ n += 0 == memcmp (pi + 45, pj + 45, b - 45);
+
+ n += 0 == memcmp (pi + 56, pj + 56, b - 56);
+ n += 0 == memcmp (pi + 57, pj + 57, b - 57);
+ n += 0 == memcmp (pi + 58, pj + 58, b - 58);
+ n += 0 == memcmp (pi + 59, pj + 59, b - 59);
+
+ assert (n == 20);
+}
+
+
+const int32_t A20[20] = { [13] = 14, [8] = 8, [4] = 4, [1] = 1 };
+const int32_t b20[20] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
+
+void gt_A20_b20 (void)
+{
+ int n = memcmp (A20, b20, sizeof A20) > 0;
+ assert (n == 1);
+}
+
+const int32_t a21[21] = { [13] = 12, [8] = 8, [4] = 4, [1] = 1 };
+const int32_t B21[21] = { 0, 1, 0, 0, 4, 0, 0, 0, 8, 0, 0, 0, 0, 13 };
+
+void lt_a21_B21 (void)
+{
+ int n = memcmp (a21, B21, sizeof a21) < 0;
+ assert (n == 1);
+}
+
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memcmp-3.c b/gcc/testsuite/gcc.dg/memcmp-3.c
new file mode 100644
index 0000000..b5b8ac1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-3.c
@@ -0,0 +1,349 @@
+/* PR middle-end/78257 - missing memcmp optimization with constant arrays
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" }
+ { dg-skip-if "missing data representation" { "pdp11-*-*" } } */
+
+#define offsetof(T, m) __builtin_offsetof (T, m)
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern int memcmp (const void*, const void*, size_t);
+
+const int32_t ia4[4] = { 0x11121314, 0x21222324, 0x31323334, 0x41424344 };
+const int32_t ia4_des[4] =
+ { [2] = 0x31323334, [0] = 0x11121314, 0x21222324, [3] = 0x41424344 };
+const char ia4_rep[] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ "\x11\x12\x13\x14" "\x21\x22\x23\x24"
+ "\x31\x32\x33\x34" "\x41\x42\x43\x44"
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ "\x14\x13\x12\x11" "\x24\x23\x22\x21"
+ "\x34\x33\x32\x31" "\x44\x43\x42\x41"
+#endif
+ };
+
+void eq_ia4 (void)
+{
+ int n = 0, b = sizeof ia4;
+ const char *p = (const char*)ia4, *q = ia4_rep;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+
+ p = (const char*)ia4_des;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+const float fa4[4] = { 1.0, 2.0, 3.0, 4.0 };
+const float fa4_des[4] = { [0] = fa4[0], [1] = 2.0, [2] = fa4[2], [3] = 4.0 };
+
+void eq_fa4 (void)
+{
+ int n = 0, b = sizeof fa4;
+ const char *p = (const char*)fa4, *q = (const char*)fa4_des;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+/* Verify "greater than" comparison with the difference in the last byte. */
+const char ia4_xrep_16[sizeof ia4] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24,
+ 0x31, 0x32, 0x33, 0x34, 0x41, 0x42, 0x43
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ 0x14, 0x13, 0x12, 0x11, 0x24, 0x23, 0x22, 0x21,
+ 0x34, 0x33, 0x32, 0x31, 0x44, 0x43, 0x42
+#endif
+ };
+
+void gt_ia4 (void)
+{
+ int n = 0, b = sizeof ia4;
+ const char *p = (const char*)ia4, *q = ia4_xrep_16;
+
+ n += 0 < memcmp (p, q, b);
+ n += 0 < memcmp (p + 1, q + 1, b - 1);
+ n += 0 < memcmp (p + 2, q + 2, b - 2);
+ n += 0 < memcmp (p + 3, q + 3, b - 3);
+ n += 0 < memcmp (p + 4, q + 4, b - 4);
+ n += 0 < memcmp (p + 5, q + 5, b - 5);
+ n += 0 < memcmp (p + 6, q + 6, b - 6);
+ n += 0 < memcmp (p + 7, q + 7, b - 7);
+ n += 0 < memcmp (p + 8, q + 8, b - 8);
+ n += 0 < memcmp (p + 9, q + 9, b - 9);
+ n += 0 < memcmp (p + 10, q + 10, b - 10);
+ n += 0 < memcmp (p + 11, q + 11, b - 11);
+ n += 0 < memcmp (p + 12, q + 12, b - 12);
+ n += 0 < memcmp (p + 13, q + 13, b - 13);
+ n += 0 < memcmp (p + 14, q + 14, b - 14);
+ n += 0 < memcmp (p + 15, q + 15, b - 15);
+
+ if (n != 16)
+ __builtin_abort ();
+}
+
+struct S8_16_32
+{
+ int8_t i8;
+ int16_t i16;
+ int32_t i32;
+};
+
+_Static_assert (sizeof (struct S8_16_32) == 8);
+
+const struct S8_16_32 s8_16_32 = { 1, 0x2122, 0x31323334 };
+const struct S8_16_32 s8_16_32_des =
+ { .i8 = 1, .i16 = 0x2122, .i32 = 0x31323334 };
+
+const char s8_16_32_rep[] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ 1, 0, 0x21, 0x22, 0x31, 0x32, 0x33, 0x34
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ 1, 0, 0x22, 0x21, 0x34, 0x33, 0x32, 0x31
+#endif
+ };
+
+void eq_s8_16_32 (void)
+{
+ int n = 0, b = sizeof s8_16_32;
+ const char *p = (char*)&s8_16_32, *q = s8_16_32_rep;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+
+ p = (char*)&s8_16_32_des;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+
+struct S8_16_32_64
+{
+ /* 0 */ int8_t i8;
+ /* 1 */ int8_t: 1;
+ /* 2 */ int16_t i16;
+ /* 4 */ int32_t: 1;
+ /* 8 */ int32_t i32;
+ /* 12 */ int32_t: 1;
+ /* 16 */ int64_t i64;
+ /* 24 */ int8_t: 0;
+};
+
+_Static_assert (offsetof (struct S8_16_32_64, i16) == 2);
+_Static_assert (offsetof (struct S8_16_32_64, i32) == 8);
+_Static_assert (offsetof (struct S8_16_32_64, i64) == 16);
+_Static_assert (sizeof (struct S8_16_32_64) == 24);
+
+const struct S8_16_32_64 s8_16_32_64 =
+ { 1, 0x2122, 0x31323334, 0x4142434445464748LLU };
+
+const char s8_16_32_64_rep[sizeof s8_16_32_64] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ "\x01" "\x00" "\x21\x22" "\x00\x00\x00\x00" "\x31\x32\x33\x34"
+ "\x00\x00\x00\x00" "\x41\x42\x43\x44\x45\x46\x47\x48"
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ "\x01" "\x00" "\x22\x21" "\x00\x00\x00\x00" "\x34\x33\x32\x31"
+ "\x00\x00\x00\x00" "\x48\x47\x46\x45\x44\x43\x42\x41"
+#endif
+ };
+
+const struct S8_16_32_64 s8_16_32_64_des =
+ { .i64 = 0x4142434445464748LLU, .i16 = 0x2122, .i32 = 0x31323334, .i8 = 1 };
+
+
+void eq_8_16_32_64 (void)
+{
+ int n = 0, b = sizeof s8_16_32_64;
+ const char *p = (char*)&s8_16_32_64, *q = s8_16_32_64_rep;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+ n += memcmp (p + 17, q + 17, b - 17);
+ n += memcmp (p + 18, q + 18, b - 18);
+ n += memcmp (p + 19, q + 19, b - 19);
+ n += memcmp (p + 20, q + 20, b - 20);
+ n += memcmp (p + 21, q + 21, b - 21);
+ n += memcmp (p + 22, q + 22, b - 22);
+ n += memcmp (p + 23, q + 23, b - 23);
+
+ p = (char*)&s8_16_32_64_des;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+ n += memcmp (p + 17, q + 17, b - 17);
+ n += memcmp (p + 18, q + 18, b - 18);
+ n += memcmp (p + 19, q + 19, b - 19);
+ n += memcmp (p + 20, q + 20, b - 20);
+ n += memcmp (p + 21, q + 21, b - 21);
+ n += memcmp (p + 22, q + 22, b - 22);
+ n += memcmp (p + 23, q + 23, b - 23);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+struct S64_x_3
+{
+ int64_t i64a[3];
+};
+
+_Static_assert (sizeof (struct S64_x_3) == 24);
+
+const struct S64_x_3 s64_x_3 =
+ { { 0x0000000021220001LLU, 0x0000000031323334LLU, 0x4142434445464748LLU } };
+
+const char s64_x_3_rep[sizeof s64_x_3] =
+ {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ "\x00\x00\x00\x00\x21\x22\x00\x01"
+ "\x00\x00\x00\x00\x31\x32\x33\x34"
+ "\x41\x42\x43\x44\x45\x46\x47\x48"
+#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ "\x01\x00\x22\x21\x00\x00\x00\x00"
+ "\x34\x33\x32\x31\x00\x00\x00\x00"
+ "\x48\x47\x46\x45\x44\x43\x42\x41"
+#endif
+ };
+
+void eq_64_x_3 (void)
+{
+ int n = 0, b = sizeof s8_16_32_64;
+ const char *p = (char*)&s8_16_32_64, *q = s64_x_3_rep;
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+ n += memcmp (p + 9, q + 9, b - 9);
+ n += memcmp (p + 10, q + 10, b - 10);
+ n += memcmp (p + 11, q + 11, b - 11);
+ n += memcmp (p + 12, q + 12, b - 12);
+ n += memcmp (p + 13, q + 13, b - 13);
+ n += memcmp (p + 14, q + 14, b - 14);
+ n += memcmp (p + 15, q + 15, b - 15);
+ n += memcmp (p + 16, q + 16, b - 16);
+ n += memcmp (p + 17, q + 17, b - 17);
+ n += memcmp (p + 18, q + 18, b - 18);
+ n += memcmp (p + 19, q + 19, b - 19);
+ n += memcmp (p + 20, q + 20, b - 20);
+ n += memcmp (p + 21, q + 21, b - 21);
+ n += memcmp (p + 22, q + 22, b - 22);
+ n += memcmp (p + 23, q + 23, b - 23);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memcmp-4.c b/gcc/testsuite/gcc.dg/memcmp-4.c
new file mode 100644
index 0000000..bbac719
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-4.c
@@ -0,0 +1,81 @@
+/* PR middle-end/78257 - missing memcmp optimization with constant arrays
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+typedef __INT8_TYPE__ int8_t;
+typedef __INT16_TYPE__ int16_t;
+typedef __INT32_TYPE__ int32_t;
+typedef __SIZE_TYPE__ size_t;
+
+extern int memcmp (const void*, const void*, size_t);
+
+/* Verify that initializers for flexible array members are handled
+ correctly. */
+
+struct Si16_x
+{
+ int16_t n, a[];
+};
+
+const struct Si16_x si16_4 =
+ {
+ 0x1112, { 0x2122, 0x3132, 0x4142 }
+ };
+
+const char si16_4_rep[] =
+ {
+ 0x12, 0x11, 0x22, 0x21, 0x32, 0x31, 0x42, 0x41
+ };
+
+void eq_si16_x (void)
+{
+ int n = 0, b = sizeof si16_4_rep;
+ const char *p = (const char*)&si16_4, *q = si16_4_rep;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+
+ p = (const char*)&si16_4.n;
+
+ n += memcmp (p, q, b);
+ n += memcmp (p + 1, q + 1, b - 1);
+ n += memcmp (p + 2, q + 2, b - 2);
+ n += memcmp (p + 3, q + 3, b - 3);
+ n += memcmp (p + 4, q + 4, b - 4);
+ n += memcmp (p + 5, q + 5, b - 5);
+ n += memcmp (p + 6, q + 6, b - 6);
+ n += memcmp (p + 7, q + 7, b - 7);
+ n += memcmp (p + 8, q + 8, b - 8);
+
+ p = (const char*)si16_4.a;
+ q = si16_4_rep + 2;
+
+ n += memcmp (p, q, b - 2);
+ n += memcmp (p + 1, q + 1, b - 3);
+ n += memcmp (p + 2, q + 2, b - 4);
+ n += memcmp (p + 3, q + 3, b - 5);
+ n += memcmp (p + 4, q + 4, b - 6);
+ n += memcmp (p + 5, q + 5, b - 7);
+ n += memcmp (p + 6, q + 6, b - 8);
+
+ p = (const char*)&si16_4.a[1];
+ q = si16_4_rep + 4;
+
+ n += memcmp (p, q, b - 4);
+ n += memcmp (p + 1, q + 1, b - 5);
+ n += memcmp (p + 2, q + 2, b - 6);
+ n += memcmp (p + 3, q + 3, b - 7);
+ n += memcmp (p + 4, q + 4, b - 8);
+
+ if (n != 0)
+ __builtin_abort ();
+}
+
+/* { dg-final { scan-tree-dump-not "abort" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memcmp-5.c b/gcc/testsuite/gcc.dg/memcmp-5.c
new file mode 100644
index 0000000..34bae92
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-5.c
@@ -0,0 +1,72 @@
+/* PR middle-end/78257 - missing memcmp optimization with constant arrays
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+#define A "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0"
+
+const char a257[sizeof A - 1] = A;
+const char a258[sizeof A] = A;
+
+_Static_assert (sizeof A == 258);
+_Static_assert (sizeof a257 == 257);
+
+/* Verify that initializers longer than 256 characters (an internal limit
+ on the size of a buffer used to store representations in) are handled. */
+
+void eq_256plus (void)
+{
+ int n = 0;
+
+ n += __builtin_memcmp (a257, A, sizeof a257);
+ n += __builtin_memcmp (a257 + 1, A + 1, sizeof a257 - 1);
+ n += __builtin_memcmp (a257 + 2, A + 2, sizeof a257 - 2);
+ n += __builtin_memcmp (a257 + 127, A + 127, sizeof a257 - 127);
+ n += __builtin_memcmp (a257 + 128, A + 128, sizeof a257 - 128);
+ n += __builtin_memcmp (a257 + 255, A + 255, 2);
+ n += __builtin_memcmp (a257 + 256, A + 256, 1);
+
+ n += __builtin_memcmp (a258, A, sizeof a257);
+ n += __builtin_memcmp (a258 + 1, A + 1, sizeof a257 - 1);
+ n += __builtin_memcmp (a258 + 2, A + 2, sizeof a257 - 2);
+ n += __builtin_memcmp (a258 + 127, A + 127, sizeof a257 - 127);
+ n += __builtin_memcmp (a258 + 128, A + 128, sizeof a257 - 128);
+ n += __builtin_memcmp (a258 + 256, A + 256, 2);
+ n += __builtin_memcmp (a258 + 257, A + 257, 1);
+
+ if (n)
+ __builtin_abort ();
+}
+
+#define X "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
+ "1"
+
+void lt_256plus (void)
+{
+ int n = 0;
+
+ n += 0 > __builtin_memcmp (a257, X, sizeof a257);
+ n += 0 > __builtin_memcmp (a257 + 1, X + 1, sizeof a257 - 1);
+ n += 0 > __builtin_memcmp (a257 + 2, X + 2, sizeof a257 - 2);
+ n += 0 > __builtin_memcmp (a257 + 127, X + 127, sizeof a257 - 127);
+ n += 0 > __builtin_memcmp (a257 + 128, X + 128, sizeof a257 - 128);
+ n += 0 > __builtin_memcmp (a257 + 255, X + 255, 2);
+ n += 0 > __builtin_memcmp (a257 + 256, X + 256, 1);
+
+ n += 0 > __builtin_memcmp (a258, X, sizeof a258);
+ n += 0 > __builtin_memcmp (a258 + 1, X + 1, sizeof a258 - 1);
+ n += 0 > __builtin_memcmp (a258 + 2, X + 2, sizeof a258 - 2);
+ n += 0 > __builtin_memcmp (a258 + 127, X + 127, sizeof a257 - 127);
+ n += 0 > __builtin_memcmp (a258 + 128, X + 128, sizeof a257 - 128);
+ n += 0 > __builtin_memcmp (a258 + 256, X + 256, 2);
+ n += 0 == __builtin_memcmp (a258 + 257, X + 257, 1);
+
+ if (n != 14)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/memcmp-6.c b/gcc/testsuite/gcc.dg/memcmp-6.c
new file mode 100644
index 0000000..d573526
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-6.c
@@ -0,0 +1,47 @@
+/* PR tree-optimization/96670 - ICE on memchr with an empty initializer
+ { dg-do compile }
+ { dg-options "-O -Wall -fdump-tree-optimized" } */
+
+struct {
+ int i, j;
+} const s = { };
+
+const char a[sizeof s] = { };
+
+void memcmp_success_unused (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ __builtin_memcmp (p, a, n);
+ __builtin_memcmp (a, p, n);
+}
+
+void memcmp_success_used (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ if (__builtin_memcmp (p, a, n)
+ || __builtin_memcmp (a, p, n))
+ __builtin_abort ();
+}
+
+void memcmp_fail_unused (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ __builtin_memcmp (p, a, n);
+ __builtin_memcmp (a, p, n);
+}
+
+void memcmp_fail_used (void)
+{
+ int n = (char *)&s.j - (char *)&s;
+ char *p = (char *)&s;
+ if (__builtin_memcmp (p, a, n)
+ || __builtin_memcmp (a, p, n))
+ __builtin_abort ();
+}
+
+/* { dg-prune-output "\\\[-Wunused-value" }
+ { dg-final { scan-tree-dump-not "abort" "optimized" } }
+ { dg-final { scan-tree-dump-not "memcmp \\\(" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/memcmp-pr95189.c b/gcc/testsuite/gcc.dg/memcmp-pr95189.c
new file mode 100644
index 0000000..d8250ec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/memcmp-pr95189.c
@@ -0,0 +1,28 @@
+/* PR middle-end/95189 - memcmp being wrongly stripped like strcmp
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+char a4[] = "\0abc";
+char a8[] = "\0abcdefg";
+char a16[] = "\0abcdefghijklmno";
+
+int cmp4 (void)
+{
+ return __builtin_memcmp (a4, "\0\0\0\0", 4);
+}
+
+int cmp8 (void)
+{
+ return __builtin_memcmp (a8, "\0\0\0\0\0\0\0\0", 8);
+}
+
+int cmp16 (void)
+{
+ return __builtin_memcmp (a16, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
+}
+
+int main (void)
+{
+ if (cmp4 () < 1 || cmp8 () < 1 || cmp16 () < 1)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-1.c b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-1.c
index 0c7e096..909f8a6 100644
--- a/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-1.c
+++ b/gcc/testsuite/gcc.dg/no_profile_instrument_function-attr-1.c
@@ -18,7 +18,7 @@ int main ()
return foo ();
}
-/* { dg-final { scan-tree-dump-times "__gcov0\\.main.* = PROF_edge_counter" 1 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "__gcov0\[._\]main.* = PROF_edge_counter" 1 "optimized"} } */
/* { dg-final { scan-tree-dump-times "__gcov_indirect_call_profiler_v" 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "__gcov_time_profiler_counter = " 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times "__gcov_init" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c
deleted file mode 100644
index 5712dbd..0000000
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-default.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-show-caret" } */
-
-#include <stdlib.h>
-
-void *wrapped_malloc (size_t size)
-{
- return malloc (size);
-}
-
-void wrapped_free (void *ptr)
-{
- free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
- /* { dg-begin-multiline-output "" }
- free (ptr);
- ^~~~~~~~~~
- 'test': events 1-2
- |
- | {
- | ^
- | |
- | (1) entering 'test'
- | boxed_int *obj = make_boxed_int (i);
- | ~~~~~~~~~~~~~~~~~~
- | |
- | (2) calling 'make_boxed_int'
- |
- +--> 'make_boxed_int': events 3-4
- |
- | {
- | ^
- | |
- | (3) entering 'make_boxed_int'
- | boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
- | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- | |
- | (4) calling 'wrapped_malloc'
- |
- +--> 'wrapped_malloc': events 5-6
- |
- | {
- | ^
- | |
- | (5) entering 'wrapped_malloc'
- | return malloc (size);
- | ~~~~~~~~~~~~~
- | |
- | (6) calling 'malloc'
- |
- <-------------+
- |
- 'test': event 7
- |
- | free_boxed_int (obj);
- | ^~~~~~~~~~~~~~~~~~~~
- | |
- | (7) calling 'free_boxed_int'
- |
- +--> 'free_boxed_int': events 8-9
- |
- | {
- | ^
- | |
- | (8) entering 'free_boxed_int'
- | wrapped_free (bi);
- | ~~~~~~~~~~~~~~~~~
- | |
- | (9) calling 'wrapped_free'
- |
- +--> 'wrapped_free': events 10-11
- |
- | {
- | ^
- | |
- | (10) entering 'wrapped_free'
- | free (ptr);
- | ~~~~~~~~~~
- | |
- | (11) calling 'free'
- |
- <-------------+
- |
- 'test': event 12
- |
- | free_boxed_int (obj);
- | ^~~~~~~~~~~~~~~~~~~~
- | |
- | (12) calling 'free_boxed_int'
- |
- +--> 'free_boxed_int': events 13-14
- |
- | {
- | ^
- | |
- | (13) entering 'free_boxed_int'
- | wrapped_free (bi);
- | ~~~~~~~~~~~~~~~~~
- | |
- | (14) calling 'wrapped_free'
- |
- +--> 'wrapped_free': events 15-16
- |
- | {
- | ^
- | |
- | (15) entering 'wrapped_free'
- | free (ptr);
- | ~~~~~~~~~~
- | |
- | (16) calling 'free'
- |
- { dg-end-multiline-output "" } */
-}
-
-typedef struct boxed_int
-{
- int i;
-} boxed_int;
-
-boxed_int *
-make_boxed_int (int i)
-{
- boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
- result->i = i;
- return result;
-}
-
-void
-free_boxed_int (boxed_int *bi)
-{
- wrapped_free (bi);
-}
-
-void test (int i)
-{
- boxed_int *obj = make_boxed_int (i);
-
- free_boxed_int (obj);
-
- free_boxed_int (obj);
-}
-
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-plain.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-plain.c
new file mode 100644
index 0000000..75acd25
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-path-format-plain.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+
+#include <stdlib.h>
+
+void *wrapped_malloc (size_t size)
+{
+ return malloc (size);
+}
+
+void wrapped_free (void *ptr)
+{
+ free (ptr); /* { dg-warning "double-free of 'ptr' \\\[CWE-415\\]" } */
+}
+
+typedef struct boxed_int
+{
+ int i;
+} boxed_int;
+
+boxed_int *
+make_boxed_int (int i)
+{
+ boxed_int *result = (boxed_int *)wrapped_malloc (sizeof (boxed_int));
+ result->i = i;
+ return result;
+}
+
+void
+free_boxed_int (boxed_int *bi)
+{
+ wrapped_free (bi);
+}
+
+void test (int i)
+{ /* { dg-message "\\(1\\) entering 'test'" } */
+ boxed_int *obj = make_boxed_int (i); /* { dg-message "\\(2\\) calling 'make_boxed_int'" } */
+ /* etc */
+
+ free_boxed_int (obj);
+
+ free_boxed_int (obj);
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
index 03b7804..d7691e4 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-expressions-1.c
@@ -540,15 +540,15 @@ void test_builtin_types_compatible_p (unsigned long i)
__emit_expression_range (0,
f (i) + __builtin_types_compatible_p (long, int)); /* { dg-warning "range" } */
/* { dg-begin-multiline-output "" }
- f (i) + __builtin_types_compatible_p (long, int));
- ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ f (i) + __builtin_types_compatible_p (long, int));
+ ~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */
__emit_expression_range (0,
__builtin_types_compatible_p (long, int) + f (i)); /* { dg-warning "range" } */
/* { dg-begin-multiline-output "" }
- __builtin_types_compatible_p (long, int) + f (i));
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
+ __builtin_types_compatible_p (long, int) + f (i));
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~
{ dg-end-multiline-output "" } */
}
@@ -671,8 +671,8 @@ void test_multiple_ordinary_maps (void)
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, foo (0,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"));
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"));
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ dg-end-multiline-output "" } */
/* Another expression that transitions between ordinary maps; this
@@ -685,8 +685,8 @@ void test_multiple_ordinary_maps (void)
/* { dg-begin-multiline-output "" }
__emit_expression_range (0, foo (0, "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789",
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- 0));
- ~~
+ 0));
+ ~~
{ dg-end-multiline-output "" } */
}
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
index 946a234..b2b269a 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-paths-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers" } */
+/* { dg-options "-fdiagnostics-show-caret -fdiagnostics-show-line-numbers -fdiagnostics-path-format=inline-events" } */
#include <stddef.h>
#include <stdlib.h>
@@ -43,9 +43,9 @@ make_a_list_of_random_ints_badly(PyObject *self,
| | (1) when 'PyList_New' fails, returning NULL
| 26 |
| 27 | for (i = 0; i < count; i++) {
- | | ~~~
- | | |
- | | (2) when 'i < count'
+ | | ~~~~~~~~~
+ | | |
+ | | (2) when 'i < count'
| 28 | item = PyLong_FromLong(random());
| 29 | PyList_Append(list, item);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
index ac4fa1b..4cba87b 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-string-literals-1.c
@@ -335,11 +335,11 @@ pr87652 (const char *stem, int counter)
/* { dg-error "unable to read substring location: unable to read source line" "" { target c } 329 } */
/* { dg-error "unable to read substring location: failed to get ordinary maps" "" { target c++ } 329 } */
/* { dg-begin-multiline-output "" }
- __emit_string_literal_range(__FILE__":%5d: " format, \
+ __emit_string_literal_range(__FILE__":%5d: " format, \
^~~~~~~~
{ dg-end-multiline-output "" { target c } } */
/* { dg-begin-multiline-output "" }
- __emit_string_literal_range(__FILE__":%5d: " format, \
+ __emit_string_literal_range(__FILE__":%5d: " format, \
^
{ dg-end-multiline-output "" { target c++ } } */
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index c02b008..5dd102a 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -100,7 +100,7 @@ set plugin_test_list [list \
diagnostic-test-paths-2.c \
diagnostic-test-paths-3.c \
diagnostic-test-paths-4.c \
- diagnostic-path-format-default.c \
+ diagnostic-path-format-plain.c \
diagnostic-path-format-none.c \
diagnostic-path-format-separate-events.c \
diagnostic-path-format-inline-events-1.c \
diff --git a/gcc/testsuite/gcc.dg/pr21137.c b/gcc/testsuite/gcc.dg/pr21137.c
new file mode 100644
index 0000000..6d73dea
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr21137.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+void foo();
+
+void test5_1(int e)
+{
+ if ((e >> 31) & 64)
+ foo();
+}
+
+typedef int myint;
+
+void test5_2(myint e)
+{
+ if ((e >> 31) & 64)
+ foo();
+}
+
+/* { dg-final { scan-tree-dump-times " < 0" 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr30957-1.c b/gcc/testsuite/gcc.dg/pr30957-1.c
index 6a0ed20..5644109 100644
--- a/gcc/testsuite/gcc.dg/pr30957-1.c
+++ b/gcc/testsuite/gcc.dg/pr30957-1.c
@@ -1,4 +1,4 @@
-/* { dg-do run } */
+/* { dg-do run { xfail { mmix-*-* } } } */
/* We don't (and don't want to) perform this optimisation on soft-float targets,
where each addition is a library call. /
/* { dg-require-effective-target hard_float } */
@@ -33,4 +33,4 @@ main ()
exit (0);
}
-/* { dg-final { scan-rtl-dump "Expanding Accumulator" "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump "Expanding Accumulator" "loop2_unroll" { xfail mmix-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/pr44194-1.c b/gcc/testsuite/gcc.dg/pr44194-1.c
index 20b74a5..a38270b 100644
--- a/gcc/testsuite/gcc.dg/pr44194-1.c
+++ b/gcc/testsuite/gcc.dg/pr44194-1.c
@@ -1,4 +1,5 @@
/* { dg-do compile { target { { { { { { { { { { i?86-*-* x86_64-*-* } && x32 } || lp64 } && { ! s390*-*-* } } && { ! hppa*64*-*-* } } && { ! alpha*-*-* } } && { { ! powerpc*-*-linux* } || powerpc_elfv2 } } && { ! nvptx-*-* } } } } } } */
+/* { dg-skip-if "returns that struct in memory" { mmix-*-* } } */
/* { dg-options "-O2 -fdump-rtl-dse1 -fdump-rtl-final" } */
/* Restrict to 64-bit targets since 32-bit targets usually return small
diff --git a/gcc/testsuite/gcc.dg/pr51628-17.c b/gcc/testsuite/gcc.dg/pr51628-17.c
index 0be95b2..42dc9d7 100644
--- a/gcc/testsuite/gcc.dg/pr51628-17.c
+++ b/gcc/testsuite/gcc.dg/pr51628-17.c
@@ -7,4 +7,4 @@ struct A {
} __attribute__ ((packed));
long* f8 (struct A *p) { return &p->i; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-19.c b/gcc/testsuite/gcc.dg/pr51628-19.c
index 7ff03e8..91ff39a 100644
--- a/gcc/testsuite/gcc.dg/pr51628-19.c
+++ b/gcc/testsuite/gcc.dg/pr51628-19.c
@@ -16,11 +16,11 @@ bar (int n, int k, void *ptr)
int *p0, *p1;
p0 = p->x;
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
foo (p0);
p1 = &p->x[1];
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
foo (p1);
return &p->x[1];
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/pr51628-20.c b/gcc/testsuite/gcc.dg/pr51628-20.c
index bcdbff1..2249d85 100644
--- a/gcc/testsuite/gcc.dg/pr51628-20.c
+++ b/gcc/testsuite/gcc.dg/pr51628-20.c
@@ -8,4 +8,4 @@ struct C { struct B b; } __attribute__ ((packed));
extern struct C *p;
long* g8 (void) { return p; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-21.c b/gcc/testsuite/gcc.dg/pr51628-21.c
index 0c7fab7..f1adbe6 100644
--- a/gcc/testsuite/gcc.dg/pr51628-21.c
+++ b/gcc/testsuite/gcc.dg/pr51628-21.c
@@ -8,4 +8,4 @@ struct C { struct B b; } __attribute__ ((packed));
extern struct C p[];
long* g8 (void) { return p; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-22.c b/gcc/testsuite/gcc.dg/pr51628-22.c
index 1bd5d79..25ac36c 100644
--- a/gcc/testsuite/gcc.dg/pr51628-22.c
+++ b/gcc/testsuite/gcc.dg/pr51628-22.c
@@ -6,4 +6,4 @@ struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
int* g4 (struct C *p) { return &p->b; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-24.c b/gcc/testsuite/gcc.dg/pr51628-24.c
index 3ad99cd..1e454a1 100644
--- a/gcc/testsuite/gcc.dg/pr51628-24.c
+++ b/gcc/testsuite/gcc.dg/pr51628-24.c
@@ -7,4 +7,4 @@ struct A {
} __attribute__ ((packed));
short* f2 (struct A *p) { return &p->i; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-25.c b/gcc/testsuite/gcc.dg/pr51628-25.c
index 94a3a8f..f00d9b1 100644
--- a/gcc/testsuite/gcc.dg/pr51628-25.c
+++ b/gcc/testsuite/gcc.dg/pr51628-25.c
@@ -6,4 +6,4 @@ struct B { int i; };
struct C { struct B b; } __attribute__ ((packed));
long* g8 (struct C *p) { return p; }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr51628-34.c b/gcc/testsuite/gcc.dg/pr51628-34.c
index 51d4b26..0f6ae34 100644
--- a/gcc/testsuite/gcc.dg/pr51628-34.c
+++ b/gcc/testsuite/gcc.dg/pr51628-34.c
@@ -9,9 +9,9 @@ baz (int x, struct S *p)
{
return (x
? &p->a
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
: &p->b);
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
}
short *
@@ -19,7 +19,7 @@ qux (int x, struct S *p)
{
return (short *) (x
? &p->a
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
: &p->b);
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/pr51683.c b/gcc/testsuite/gcc.dg/pr51683.c
index c477cd8..7a624e4 100644
--- a/gcc/testsuite/gcc.dg/pr51683.c
+++ b/gcc/testsuite/gcc.dg/pr51683.c
@@ -12,6 +12,9 @@ void *
foo (void *p)
{
return bar ((void *) 0x12345000, p, 256);
+ /* Integers converted to pointers are assumed to be the result of
+ (invalid) arithmetic on null pointers.
+ { dg-prune-output "writing 256 bytes into a region of size 0" } */
}
/* { dg-final { scan-tree-dump "memcpy" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr53037-1.c b/gcc/testsuite/gcc.dg/pr53037-1.c
index 3ea5ae6..3f22696 100644
--- a/gcc/testsuite/gcc.dg/pr53037-1.c
+++ b/gcc/testsuite/gcc.dg/pr53037-1.c
@@ -40,7 +40,7 @@ struct foo5
{
int i1;
int x __attribute__((warn_if_not_aligned(16))); /* { dg-warning "'x' offset 4 in 'struct foo5' isn't aligned to 16" } */
-}; /* { dg-warning "alignment 4 of 'struct foo5' is less than 16" } */
+}; /* { dg-warning {alignment [0-9]+ of 'struct foo5' is less than 16} } */
struct foo6
{
@@ -73,7 +73,7 @@ union bar3
{
int i1;
int x __attribute__((warn_if_not_aligned(16)));
-}; /* { dg-warning "alignment 4 of 'union bar3' is less than 16" } */
+}; /* { dg-warning {alignment [0-9]+ of 'union bar3' is less than 16} } */
union bar4
{
diff --git a/gcc/testsuite/gcc.dg/pr55940.c b/gcc/testsuite/gcc.dg/pr55940.c
index d046d0b..85761f6 100644
--- a/gcc/testsuite/gcc.dg/pr55940.c
+++ b/gcc/testsuite/gcc.dg/pr55940.c
@@ -1,5 +1,6 @@
/* PR target/55940 */
/* { dg-do run } */
+/* { dg-skip-if "pointer arithmetic can wrap" { msp430-*-* } { "*" } { "-mlarge" } } */
/* { dg-options "-Os" } */
/* { dg-additional-options "-mpreferred-stack-boundary=2" { target { { i?86-*-* x86_64-*-* } && ia32 } } } */
diff --git a/gcc/testsuite/gcc.dg/pr78902.c b/gcc/testsuite/gcc.dg/pr78902.c
index 51b4254..a9a617c 100644
--- a/gcc/testsuite/gcc.dg/pr78902.c
+++ b/gcc/testsuite/gcc.dg/pr78902.c
@@ -12,4 +12,5 @@ void foo(void)
__builtin_aligned_alloc (10, 16); /* { dg-warning "ignoring return value of '__builtin_aligned_alloc' declared with attribute 'warn_unused_result'" } */
__builtin_strdup ("pes"); /* { dg-warning "ignoring return value of '__builtin_strdup' declared with attribute 'warn_unused_result'" } */
__builtin_strndup ("pes", 10); /* { dg-warning "ignoring return value of '__builtin_strndup' declared with attribute 'warn_unused_result'" } */
+ /* { dg-warning "\\\[-Wstringop-overread" "strndup excessive bound" { target *-*-* } .-1 } */
}
diff --git a/gcc/testsuite/gcc.dg/pr79214.c b/gcc/testsuite/gcc.dg/pr79214.c
index 23119ed..3f5d935 100644
--- a/gcc/testsuite/gcc.dg/pr79214.c
+++ b/gcc/testsuite/gcc.dg/pr79214.c
@@ -84,5 +84,5 @@ char* test_strncat (int i)
{
const char *s = i < 0 ? "123" : "4567";
- return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound between 4 and \[0-9\]+" } */
+ return strncat (d, s, range ()); /* { dg-warning ".__builtin_strncat. specified bound \\\[4, \[0-9\]+] exceeds destination size 3" } */
}
diff --git a/gcc/testsuite/gcc.dg/pr81192.c b/gcc/testsuite/gcc.dg/pr81192.c
index 0049f37..71bbc13 100644
--- a/gcc/testsuite/gcc.dg/pr81192.c
+++ b/gcc/testsuite/gcc.dg/pr81192.c
@@ -1,4 +1,20 @@
-/* { dg-options "-Os -fdump-tree-pre-details" } */
+/* { dg-options "-Os -fdump-tree-pre-details -fdisable-tree-evrp" } */
+
+/* Disable tree-evrp because the new version of evrp sees
+<bb 3> :
+ if (j_8(D) != 2147483647)
+ goto <bb 4>; [50.00%]
+ else
+ goto <bb 5>; [50.00%]
+<bb 4> :
+ iftmp.2_11 = j_8(D) + 1;
+<bb 5> :
+ # iftmp.2_12 = PHI <j_8(D)(3), iftmp.2_11(4)>
+
+EVRP now recognizes a constant can be propagated into the 3->5 edge and
+produces
+ # iftmp.2_12 = PHI <2147483647(3), iftmp.2_11(4)>
+which causes the situation being tested to dissapear before we get to PRE. */
#if __SIZEOF_INT__ == 2
#define unsigned __UINT32_TYPE__
diff --git a/gcc/testsuite/gcc.dg/pr84131.c b/gcc/testsuite/gcc.dg/pr84131.c
index 0ba9651..ced2e5d 100644
--- a/gcc/testsuite/gcc.dg/pr84131.c
+++ b/gcc/testsuite/gcc.dg/pr84131.c
@@ -1,7 +1,8 @@
/* PR 94131 - ICE on printf with a VLA string and -fno-tree-ccp
-fno-tree-forwprop
{ dg-do compile }
- { dg-options "-O1 -fno-tree-ccp -fno-tree-forwprop" } */
+ { dg-options "-O1 -fno-tree-ccp -fno-tree-forwprop" }
+ { dg-require-effective-target alloca } */
void rv1 (int n)
{
diff --git a/gcc/testsuite/gcc.dg/pr86314.c b/gcc/testsuite/gcc.dg/pr86314.c
index 8962a3c..565fb02 100644
--- a/gcc/testsuite/gcc.dg/pr86314.c
+++ b/gcc/testsuite/gcc.dg/pr86314.c
@@ -1,5 +1,5 @@
// PR target/86314
-// { dg-do run { target sync_int_long } }
+// { dg-do run { target sync_int_long_stack } }
// { dg-options "-O2" }
__attribute__((noinline, noclone)) unsigned long
diff --git a/gcc/testsuite/gcc.dg/pr87314-1.c b/gcc/testsuite/gcc.dg/pr87314-1.c
index 9bc9056..0cb9c07 100644
--- a/gcc/testsuite/gcc.dg/pr87314-1.c
+++ b/gcc/testsuite/gcc.dg/pr87314-1.c
@@ -8,4 +8,6 @@ int h() { return "bye"=="helloooobye"+8; }
/* { dg-final { scan-tree-dump-times "hello" 1 "original" } } */
/* The test in h() should be retained because the result depends on
string merging. */
-/* { dg-final { scan-assembler "hellooo" } } */
+/* { dg-final { scan-assembler "hellooo" { target { ! nvptx*-*-* } } } } */
+/* { dg-final { scan-assembler "104, 101, 108, 108, 111, 111, 111" { target { nvptx*-*-* } } } } */
+
diff --git a/gcc/testsuite/gcc.dg/pr87485.c b/gcc/testsuite/gcc.dg/pr87485.c
index 7e09173..17d1c24 100644
--- a/gcc/testsuite/gcc.dg/pr87485.c
+++ b/gcc/testsuite/gcc.dg/pr87485.c
@@ -2,6 +2,7 @@
/* { dg-do compile { target int128 } } */
/* { dg-options "-O2 -fschedule-insns -fno-guess-branch-probability -fno-isolate-erroneous-paths-dereference -fno-omit-frame-pointer -fno-split-wide-types -fno-tree-ccp -fno-tree-sra" } */
/* { dg-additional-options "-fstack-protector-strong" { target fstack_protector } } */
+/* { dg-require-effective-target scheduling } */
int *a;
diff --git a/gcc/testsuite/gcc.dg/pr88928.c b/gcc/testsuite/gcc.dg/pr88928.c
index c0a1f76..0b6c1d7 100644
--- a/gcc/testsuite/gcc.dg/pr88928.c
+++ b/gcc/testsuite/gcc.dg/pr88928.c
@@ -3,4 +3,4 @@
struct a { } __attribute__((__packed__));
void c (struct a **);
void d (const struct a *b) { c ((struct a **) b); }
-/* { dg-warning "may result in an unaligned pointer value" "" { target *-*-* } .-1 } */
+/* { dg-warning "may result in an unaligned pointer value" "" { target { ! default_packed } } .-1 } */
diff --git a/gcc/testsuite/gcc.dg/pr93986.c b/gcc/testsuite/gcc.dg/pr93986.c
index bdbc192..0d533f4 100644
--- a/gcc/testsuite/gcc.dg/pr93986.c
+++ b/gcc/testsuite/gcc.dg/pr93986.c
@@ -1,6 +1,7 @@
/* PR tree-optimization/93986 - ICE in decompose, at wide-int.h:984
{ dg-do compile }
- { dg-options "-O1 -foptimize-strlen -ftree-slp-vectorize" } */
+ { dg-options "-O1 -foptimize-strlen -ftree-slp-vectorize" }
+ { dg-require-effective-target alloca } */
int dd (void);
diff --git a/gcc/testsuite/gcc.dg/pr94234-1.c b/gcc/testsuite/gcc.dg/pr94234-1.c
new file mode 100644
index 0000000..d85563b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94234-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+typedef __INTPTR_TYPE__ ssize_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+ptrdiff_t foo (char *a, ssize_t n, ssize_t m)
+{
+ char *b1 = a + 8 * n;
+ char *b2 = a + 8 * (n + 1);
+
+ return (b1 + m) - (b2 + m);
+}
+
+/* { dg-final { scan-tree-dump-times "return -8;" 1 "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94234-2.c b/gcc/testsuite/gcc.dg/pr94234-2.c
new file mode 100644
index 0000000..1f4b194
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94234-2.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+int use_fn (int a);
+
+int foo (int n)
+{
+ int b1 = 8 * (n + 1);
+ int b2 = 8 * n;
+
+ use_fn (b1 ^ b2);
+
+ return b1 - b2;
+}
+
+unsigned goo (unsigned m_param, unsigned n_param)
+{
+ unsigned b1 = m_param * (n_param + 2);
+ unsigned b2 = m_param * (n_param + 1);
+
+ use_fn (b1 ^ b2);
+
+ return b1 - b2;
+}
+
+unsigned hoo (unsigned k_param)
+{
+ unsigned b1 = k_param * 28;
+ unsigned b2 = k_param * 15;
+ unsigned b3 = k_param * 12;
+
+ use_fn (b1 ^ b2 ^ b3);
+
+ return (b1 - b2) - b3;
+}
+
+/* { dg-final { scan-tree-dump-times "return 8;" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "return m_param" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-not "return k_param" "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94234-3.c b/gcc/testsuite/gcc.dg/pr94234-3.c
new file mode 100644
index 0000000..9bb9b46
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94234-3.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop1" } */
+
+typedef __SIZE_TYPE__ size_t;
+typedef __PTRDIFF_TYPE__ ptrdiff_t;
+
+ptrdiff_t foo1 (char *a, size_t n)
+{
+ char *b1 = a + 8 * n;
+ char *b2 = a + 8 * (n - 1);
+
+ return b1 - b2;
+}
+
+int use_ptr (char *a, char *b);
+
+ptrdiff_t foo2 (char *a, size_t n)
+{
+ char *b1 = a + 8 * (n - 1);
+ char *b2 = a + 8 * n;
+
+ use_ptr (b1, b2);
+
+ return b1 - b2;
+}
+
+int use_int (int i);
+
+unsigned goo (unsigned m_param, unsigned n_param)
+{
+ unsigned b1 = m_param * (n_param + 2);
+ unsigned b2 = m_param * (n_param + 1);
+ int r = (int)(b1) - (int)(b2);
+
+ use_int (r);
+
+ return r;
+}
+
+/* { dg-final { scan-tree-dump-times "return 8;" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "return -8;" 1 "forwprop1" } } */
+/* { dg-final { scan-tree-dump-times "return m_param" 1 "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-1.c b/gcc/testsuite/gcc.dg/pr94600-1.c
new file mode 100644
index 0000000..149e4f3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2" } */
+/* { dg-additional-options "-DALIGN_VAR" { target { ! non_strict_align } } } */
+
+/* Assignments to a whole struct of suitable size (32 bytes) must not be
+ picked apart into field accesses. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0;
+
+static t0 a0[]
+#ifdef ALIGN_VAR
+__attribute__((aligned (4)))
+#endif
+ = {
+ { .f0 = 7, .f1 = 99, .f3 = 1, },
+ { .f0 = 7, .f1 = 251, .f3 = 1, },
+ { .f0 = 8, .f1 = 127, .f3 = 5, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+};
+
+void
+foo(void)
+{
+ __SIZE_TYPE__ i;
+ __SIZE_TYPE__ base = 0x000a0000;
+ for (i = 0; i < (sizeof (a0) / sizeof ((a0)[0])); i++) {
+ *(volatile t0 *) (base + 44 + i * 4) = a0[i];
+ }
+}
+
+/* The only volatile accesses should be the obvious writes. */
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 6 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 6 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-2.c b/gcc/testsuite/gcc.dg/pr94600-2.c
new file mode 100644
index 0000000..cb96cc9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-2.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2" } */
+
+/* Unrolled version of pr94600-1.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0;
+
+void
+bar(void)
+{
+ t0 a00 = { .f0 = 7, .f1 = 99, .f3 = 1, };
+ t0 a01 = { .f0 = 7, .f1 = 251, .f3 = 1, };
+ t0 a02 = { .f0 = 8, .f1 = 127, .f3 = 5, };
+ t0 a03 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a04 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a05 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ __SIZE_TYPE__ base = 0x000a0000;
+
+ *(volatile t0 *) ((base) + 44 + (0) * 4) = a00;
+ *(volatile t0 *) ((base) + 44 + (1) * 4) = a01;
+ *(volatile t0 *) ((base) + 44 + (2) * 4) = a02;
+ *(volatile t0 *) ((base) + 44 + (3) * 4) = a03;
+ *(volatile t0 *) ((base) + 44 + (4) * 4) = a04;
+ *(volatile t0 *) ((base) + 44 + (5) * 4) = a05;
+}
+
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 6 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 6 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-3.c b/gcc/testsuite/gcc.dg/pr94600-3.c
new file mode 100644
index 0000000..2fce9f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-3.c
@@ -0,0 +1,40 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2 -fno-unroll-loops" } */
+/* { dg-additional-options "-DALIGN_VAR" { target { ! non_strict_align } } } */
+
+/* Same-address version of pr94600-1.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0;
+
+static t0 a0[]
+#ifdef ALIGN_VAR
+__attribute__((aligned (4)))
+#endif
+ = {
+ { .f0 = 7, .f1 = 99, .f3 = 1, },
+ { .f0 = 7, .f1 = 251, .f3 = 1, },
+ { .f0 = 8, .f1 = 127, .f3 = 5, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+};
+
+void
+foo(void)
+{
+ __SIZE_TYPE__ i;
+ __SIZE_TYPE__ base = 0x000a0000;
+ for (i = 0; i < (sizeof (a0) / sizeof ((a0)[0])); i++) {
+ *(volatile t0 *) (base + 44) = a0[i];
+ }
+}
+
+/* The loop isn't unrolled. */
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 1 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-4.c b/gcc/testsuite/gcc.dg/pr94600-4.c
new file mode 100644
index 0000000..c2901ab
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-4.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2" } */
+
+/* Unrolled version of pr94600-2.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0;
+
+void
+bar(void)
+{
+ t0 a00 = { .f0 = 7, .f1 = 99, .f3 = 1, };
+ t0 a01 = { .f0 = 7, .f1 = 251, .f3 = 1, };
+ t0 a02 = { .f0 = 8, .f1 = 127, .f3 = 5, };
+ t0 a03 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a04 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a05 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ __SIZE_TYPE__ base = 0x000a0000;
+
+ *(volatile t0 *) ((base) + 44) = a00;
+ *(volatile t0 *) ((base) + 44) = a01;
+ *(volatile t0 *) ((base) + 44) = a02;
+ *(volatile t0 *) ((base) + 44) = a03;
+ *(volatile t0 *) ((base) + 44) = a04;
+ *(volatile t0 *) ((base) + 44) = a05;
+}
+
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 6 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 6 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-5.c b/gcc/testsuite/gcc.dg/pr94600-5.c
new file mode 100644
index 0000000..3be0249
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-5.c
@@ -0,0 +1,34 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2 -fno-unroll-loops" } */
+
+/* Target-as-parameter version of pr94600-1.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0 __attribute__((__aligned__(4)));
+
+static t0 a0[] = {
+ { .f0 = 7, .f1 = 99, .f3 = 1, },
+ { .f0 = 7, .f1 = 251, .f3 = 1, },
+ { .f0 = 8, .f1 = 127, .f3 = 5, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+};
+
+void
+foo(volatile t0 *b)
+{
+ __SIZE_TYPE__ i;
+ for (i = 0; i < (sizeof (a0) / sizeof ((a0)[0])); i++) {
+ b[i+11] = a0[i];
+ }
+}
+
+/* The loop isn't unrolled. */
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 1 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-6.c b/gcc/testsuite/gcc.dg/pr94600-6.c
new file mode 100644
index 0000000..c247afe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-6.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2" } */
+
+/* Target-as-parameter version of pr94600-2.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0 __attribute__((__aligned__(4)));
+
+void
+bar(volatile t0 *b)
+{
+ t0 a00 = { .f0 = 7, .f1 = 99, .f3 = 1, };
+ t0 a01 = { .f0 = 7, .f1 = 251, .f3 = 1, };
+ t0 a02 = { .f0 = 8, .f1 = 127, .f3 = 5, };
+ t0 a03 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a04 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a05 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+
+ b[11+0] = a00;
+ b[11+1] = a01;
+ b[11+2] = a02;
+ b[11+3] = a03;
+ b[11+4] = a04;
+ b[11+5] = a05;
+}
+
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 6 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 6 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-7.c b/gcc/testsuite/gcc.dg/pr94600-7.c
new file mode 100644
index 0000000..81c5231
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-7.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2 -fno-unroll-loops" } */
+
+/* Target-as-parameter version of pr94600-3.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0 __attribute__((__aligned__(4)));
+
+static t0 a0[] = {
+ { .f0 = 7, .f1 = 99, .f3 = 1, },
+ { .f0 = 7, .f1 = 251, .f3 = 1, },
+ { .f0 = 8, .f1 = 127, .f3 = 5, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+ { .f0 = 5, .f1 = 1, .f3 = 1, },
+};
+
+void
+foo(volatile t0 *b)
+{
+ __SIZE_TYPE__ i;
+ for (i = 0; i < (sizeof (a0) / sizeof ((a0)[0])); i++) {
+ b[11] = a0[i];
+ }
+}
+
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 1 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 1 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr94600-8.c b/gcc/testsuite/gcc.dg/pr94600-8.c
new file mode 100644
index 0000000..201b2add4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr94600-8.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target size32plus } */
+/* { dg-options "-fdump-rtl-final -O2" } */
+
+/* Unrolled version of pr94600-2.c. */
+
+typedef struct {
+ unsigned int f0 : 4;
+ unsigned int f1 : 11;
+ unsigned int f2 : 10;
+ unsigned int f3 : 7;
+} t0 __attribute__((__aligned__(4)));
+
+void
+bar(volatile t0 *b)
+{
+ t0 a00 = { .f0 = 7, .f1 = 99, .f3 = 1, };
+ t0 a01 = { .f0 = 7, .f1 = 251, .f3 = 1, };
+ t0 a02 = { .f0 = 8, .f1 = 127, .f3 = 5, };
+ t0 a03 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a04 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+ t0 a05 = { .f0 = 5, .f1 = 1, .f3 = 1, };
+
+ b[11] = a00;
+ b[11] = a01;
+ b[11] = a02;
+ b[11] = a03;
+ b[11] = a04;
+ b[11] = a05;
+}
+
+/* { dg-final { scan-rtl-dump-times {\(mem/v} 6 "final" } } */
+/* { dg-final { scan-rtl-dump-times {\(set \(mem/v} 6 "final" } } */
diff --git a/gcc/testsuite/gcc.dg/pr95133.c b/gcc/testsuite/gcc.dg/pr95133.c
index 523deca..5e23359 100644
--- a/gcc/testsuite/gcc.dg/pr95133.c
+++ b/gcc/testsuite/gcc.dg/pr95133.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O3" } */
+/* { dg-require-effective-target label_values } */
extern int a[16];
void f (int *ip, int x)
diff --git a/gcc/testsuite/gcc.dg/pr95857.c b/gcc/testsuite/gcc.dg/pr95857.c
index 41506ea..afd6f46 100644
--- a/gcc/testsuite/gcc.dg/pr95857.c
+++ b/gcc/testsuite/gcc.dg/pr95857.c
@@ -1,6 +1,7 @@
/* PR tree-optimization/95857 */
/* { dg-do compile } */
/* { dg-options "-O2" } */
+/* { dg-require-effective-target label_values } */
struct E { int e; };
int bar (void), baz (void);
diff --git a/gcc/testsuite/gcc.dg/pr96298.c b/gcc/testsuite/gcc.dg/pr96298.c
new file mode 100644
index 0000000..8f825751
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96298.c
@@ -0,0 +1,18 @@
+/* PR rtl-optimization/96298 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-forwprop" } */
+
+typedef unsigned char __attribute__ ((__vector_size__ (8))) v64u8;
+
+v64u8 a;
+
+int
+main (void)
+{
+ v64u8 x = (a - 1) ^ -a;
+ for (unsigned i = 0; i < sizeof (x); i++)
+ if (x[i] != 0xff)
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr96335.c b/gcc/testsuite/gcc.dg/pr96335.c
new file mode 100644
index 0000000..ab243b3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96335.c
@@ -0,0 +1,12 @@
+/* PR middle-end/96335 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void bar (int, void *) __attribute__((__access__(__read_only__, 2)));
+
+void
+foo (void *x)
+{
+ void (*fn) () = bar;
+ fn (0, x);
+}
diff --git a/gcc/testsuite/gcc.dg/pr96370.c b/gcc/testsuite/gcc.dg/pr96370.c
new file mode 100644
index 0000000..b939b21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96370.c
@@ -0,0 +1,8 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-O2 -ffast-math" } */
+
+void c(_Decimal128);
+void a(_Decimal128 b)
+{
+ c(-b * b);
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-1.c b/gcc/testsuite/gcc.dg/pr96377-1.c
new file mode 100644
index 0000000..75b0c96
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-1.c
@@ -0,0 +1,32 @@
+/* { dg-options "-fno-lax-vector-conversions -Wno-psabi" } */
+/* { dg-message "use '-flax-vector-conversions' to permit conversions" "" { target *-*-* } 0 } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { v8hi x; v4si y; };
+union u1 { v8hi x; v4si y; };
+union u2 { v4si s; v8hi y; };
+
+void
+foo (v4si i, v8hi h)
+{
+ struct s x1 = { i, i }; // { dg-error "incompatible types when initializing type '__vector" }
+ struct s x2 = { h, h }; // { dg-error "incompatible types" }
+ struct s x3 = { i, h }; // { dg-error "incompatible types" }
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i }; // { dg-error "incompatible types" }
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h }; // { dg-error "incompatible types" }
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h }; // { dg-error "incompatible types" }
+ v4si z3[] = { h, i }; // { dg-error "incompatible types" }
+ v4si z4[] = { h, h }; // { dg-error "incompatible types" }
+ v8hi z5[] = { i, i }; // { dg-error "incompatible types" }
+ v8hi z6[] = { i, h }; // { dg-error "incompatible types" }
+ v8hi z7[] = { h, i }; // { dg-error "incompatible types" }
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-2.c b/gcc/testsuite/gcc.dg/pr96377-2.c
new file mode 100644
index 0000000..8355040
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-2.c
@@ -0,0 +1,31 @@
+/* { dg-options "-flax-vector-conversions -Wno-psabi" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { v8hi x; v4si y; };
+union u1 { v8hi x; v4si y; };
+union u2 { v4si s; v8hi y; };
+
+void
+foo (v4si i, v8hi h)
+{
+ struct s x1 = { i, i };
+ struct s x2 = { h, h };
+ struct s x3 = { i, h };
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i };
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h };
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h };
+ v4si z3[] = { h, i };
+ v4si z4[] = { h, h };
+ v8hi z5[] = { i, i };
+ v8hi z6[] = { i, h };
+ v8hi z7[] = { h, i };
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-3.c b/gcc/testsuite/gcc.dg/pr96377-3.c
new file mode 100644
index 0000000..66dce01
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-3.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-fno-lax-vector-conversions" } */
+/* { dg-message "use '-flax-vector-conversions' to permit conversions" "" { target *-*-* } 0 } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { v8hi x; v4si y; };
+union u1 { v8hi x; v4si y; };
+union u2 { v4si s; v8hi y; };
+
+void
+foo (__Int32x4_t i, __Int16x8_t h)
+{
+ struct s x1 = { i, i }; // { dg-error "incompatible types when initializing type '__vector" }
+ struct s x2 = { h, h }; // { dg-error "incompatible types" }
+ struct s x3 = { i, h }; // { dg-error "incompatible types" }
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i }; // { dg-error "incompatible types" }
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h }; // { dg-error "incompatible types" }
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h }; // { dg-error "incompatible types" }
+ v4si z3[] = { h, i }; // { dg-error "incompatible types" }
+ v4si z4[] = { h, h }; // { dg-error "incompatible types" }
+ v8hi z5[] = { i, i }; // { dg-error "incompatible types" }
+ v8hi z6[] = { i, h }; // { dg-error "incompatible types" }
+ v8hi z7[] = { h, i }; // { dg-error "incompatible types" }
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-4.c b/gcc/testsuite/gcc.dg/pr96377-4.c
new file mode 100644
index 0000000..f7aaf49
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-4.c
@@ -0,0 +1,32 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-flax-vector-conversions" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { v8hi x; v4si y; };
+union u1 { v8hi x; v4si y; };
+union u2 { v4si s; v8hi y; };
+
+void
+foo (__Int32x4_t i, __Int16x8_t h)
+{
+ struct s x1 = { i, i };
+ struct s x2 = { h, h };
+ struct s x3 = { i, h };
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i };
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h };
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h };
+ v4si z3[] = { h, i };
+ v4si z4[] = { h, h };
+ v8hi z5[] = { i, i };
+ v8hi z6[] = { i, h };
+ v8hi z7[] = { h, i };
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-5.c b/gcc/testsuite/gcc.dg/pr96377-5.c
new file mode 100644
index 0000000..3d0c24b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-5.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-fno-lax-vector-conversions" } */
+/* { dg-message "use '-flax-vector-conversions' to permit conversions" "" { target *-*-* } 0 } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { __Int16x8_t x; __Int32x4_t y; };
+union u1 { __Int16x8_t x; __Int32x4_t y; };
+union u2 { __Int32x4_t s; __Int16x8_t y; };
+
+void
+foo (v4si i, v8hi h)
+{
+ struct s x1 = { i, i }; // { dg-error "incompatible types when initializing type '__Int16x8_t" }
+ struct s x2 = { h, h }; // { dg-error "incompatible types" }
+ struct s x3 = { i, h }; // { dg-error "incompatible types" }
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i }; // { dg-error "incompatible types" }
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h }; // { dg-error "incompatible types" }
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h }; // { dg-error "incompatible types" }
+ v4si z3[] = { h, i }; // { dg-error "incompatible types" }
+ v4si z4[] = { h, h }; // { dg-error "incompatible types" }
+ v8hi z5[] = { i, i }; // { dg-error "incompatible types" }
+ v8hi z6[] = { i, h }; // { dg-error "incompatible types" }
+ v8hi z7[] = { h, i }; // { dg-error "incompatible types" }
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96377-6.c b/gcc/testsuite/gcc.dg/pr96377-6.c
new file mode 100644
index 0000000..165327f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96377-6.c
@@ -0,0 +1,32 @@
+/* { dg-do compile { target aarch64*-*-* } } */
+/* { dg-options "-flax-vector-conversions" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+typedef short v8hi __attribute__((vector_size(16)));
+
+struct s { __Int16x8_t x; __Int32x4_t y; };
+union u1 { __Int16x8_t x; __Int32x4_t y; };
+union u2 { __Int32x4_t s; __Int16x8_t y; };
+
+void
+foo (v4si i, v8hi h)
+{
+ struct s x1 = { i, i };
+ struct s x2 = { h, h };
+ struct s x3 = { i, h };
+ struct s x4 = { h, i };
+
+ union u1 y1 = { i };
+ union u1 y2 = { h };
+ union u2 y3 = { i };
+ union u2 y4 = { h };
+
+ v4si z1[] = { i, i };
+ v4si z2[] = { i, h };
+ v4si z3[] = { h, i };
+ v4si z4[] = { h, h };
+ v8hi z5[] = { i, i };
+ v8hi z6[] = { i, h };
+ v8hi z7[] = { h, i };
+ v8hi z8[] = { h, h };
+}
diff --git a/gcc/testsuite/gcc.dg/pr96453.c b/gcc/testsuite/gcc.dg/pr96453.c
new file mode 100644
index 0000000..f758e7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96453.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-Og -fno-early-inlining -fno-tree-ccp -fno-tree-dce" } */
+/* { dg-additional-options "-mavx -mno-sse4.2" { target x86_64-*-* i?86-*-* } } */
+
+typedef int __attribute__ ((__vector_size__ (16))) U;
+typedef unsigned long __attribute__ ((__vector_size__ (16))) V;
+
+static inline int
+bar (unsigned long e, V f)
+{
+ V g = f != e;
+ (union {U b;}){(U) g};
+}
+
+void
+foo (void)
+{
+ int j = bar (8, (V) { });
+ for (unsigned i;; i[&j])
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr96466.c b/gcc/testsuite/gcc.dg/pr96466.c
new file mode 100644
index 0000000..a8840f5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96466.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/96466 */
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-Og -finline-functions-called-once -fno-tree-ccp" } */
+
+typedef unsigned long __attribute__ ((__vector_size__ (8))) V;
+
+V
+bar (unsigned long x, V v)
+{
+ v &= x >= v;
+ return (V) v;
+}
+
+V
+foo (void)
+{
+ return bar (5, (V) 4441221375);
+}
diff --git a/gcc/testsuite/gcc.dg/pr96514.c b/gcc/testsuite/gcc.dg/pr96514.c
new file mode 100644
index 0000000..891b4da
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96514.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+
+int __attribute__ ((pure, returns_twice))
+r0 (void);
+
+void
+vy (int t7)
+{
+ while (t7 == 0)
+ r0 ();
+}
+
+void
+qw (int t7)
+{
+ vy (t7);
+
+ if (0)
+ r0 ();
+}
+
+void __attribute__ ((simd))
+un (int t7)
+{
+ qw (t7);
+ qw (t7);
+}
diff --git a/gcc/testsuite/gcc.dg/pr96558.c b/gcc/testsuite/gcc.dg/pr96558.c
new file mode 100644
index 0000000..2f5739e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96558.c
@@ -0,0 +1,32 @@
+/* PR target/96558 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2 -fno-expensive-optimizations -fno-gcse" } */
+
+int ky;
+long int h1;
+__int128 f1;
+
+int
+sd (void);
+
+int __attribute__ ((simd))
+i8 (void)
+{
+ __int128 vh;
+
+ if (sd () == 0)
+ h1 = 0;
+
+ do
+ {
+ long int lf = (long int) f1 ? h1 : 0;
+
+ ky += lf;
+ vh = lf | f1;
+ f1 = 1;
+ }
+ while (vh < (f1 ^ 2));
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr96579.c b/gcc/testsuite/gcc.dg/pr96579.c
new file mode 100644
index 0000000..982f8ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96579.c
@@ -0,0 +1,4 @@
+/* { dg-do compile { target dfp } } */
+/* { dg-options "-O -fno-tree-forwprop -ffast-math -fno-tree-vrp" } */
+
+#include "pr96370.c"
diff --git a/gcc/testsuite/gcc.dg/pr96818.c b/gcc/testsuite/gcc.dg/pr96818.c
new file mode 100644
index 0000000..ea2ac54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96818.c
@@ -0,0 +1,14 @@
+// { dg-do compile }
+// { dg-options "-O2" }
+
+int a, b, c;
+void d() {
+ unsigned short e;
+ while (b)
+ ;
+ e = (e + 5) / a;
+ switch (e)
+ case 0:
+ case 3:
+ c = a;
+}
diff --git a/gcc/testsuite/gcc.dg/pr96931.c b/gcc/testsuite/gcc.dg/pr96931.c
new file mode 100644
index 0000000..94b8a11
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr96931.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fpredictive-commoning -fno-tree-loop-im" } */
+
+int bl;
+
+void
+p3 (void);
+
+void __attribute__ ((returns_twice))
+ie (void)
+{
+ p3 ();
+
+ bl = 0;
+ for (;;)
+ ++bl;
+
+ ie ();
+}
diff --git a/gcc/testsuite/gcc.dg/pr97078.c b/gcc/testsuite/gcc.dg/pr97078.c
new file mode 100644
index 0000000..997d5fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97078.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffloat-store" } */
+
+extern void foo (long double);
+
+void bar (long double d)
+{
+ foo (d);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97192.c b/gcc/testsuite/gcc.dg/pr97192.c
new file mode 100644
index 0000000..16647ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97192.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -ftracer" } */
+/* { dg-additional-options "-mavx512vl" { target x86_64-*-* i?86-*-* } } */
+
+typedef int __attribute__ ((__vector_size__ (32))) V;
+
+int a, b;
+V v;
+
+int
+foo (void)
+{
+ b -= 4 - !a;
+ V u = 0 != v == a;
+ return u[0];
+}
diff --git a/gcc/testsuite/gcc.dg/pr97238.c b/gcc/testsuite/gcc.dg/pr97238.c
new file mode 100644
index 0000000..746e93a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97238.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -Wno-psabi -w" } */
+
+typedef int __attribute__ ((__vector_size__ (8))) V;
+int b, c, e;
+V d;
+
+V
+foo (void)
+{
+ return (b || e) | c > d | ((b || e) | c > d);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97315-2.c b/gcc/testsuite/gcc.dg/pr97315-2.c
new file mode 100644
index 0000000..5dd1b6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97315-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void c(int);
+
+int a;
+void b()
+{
+ if (a >= 2147483647)
+ c(a + 1);
+}
diff --git a/gcc/testsuite/gcc.dg/pr97317.c b/gcc/testsuite/gcc.dg/pr97317.c
new file mode 100644
index 0000000..f07327a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97317.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct a {
+ unsigned c : 17;
+};
+struct a b;
+int d(void) {
+ short e = b.c;
+ return e ? 0 : b.c;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97322.c b/gcc/testsuite/gcc.dg/pr97322.c
new file mode 100644
index 0000000..f253c0d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97322.c
@@ -0,0 +1,17 @@
+/* PR target/97322 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+foo (unsigned long long x, unsigned long long *y)
+{
+ y[0] = x / 10;
+ y[1] = x % 10;
+}
+
+void
+bar (unsigned int x, unsigned int *y)
+{
+ y[0] = x / 10;
+ y[1] = x % 10;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97357.c b/gcc/testsuite/gcc.dg/pr97357.c
new file mode 100644
index 0000000..6b391b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97357.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-require-effective-target indirect_jumps } */
+
+#include <setjmp.h>
+#include <stdlib.h>
+
+void * my_malloc (size_t size);
+
+typedef struct glk {
+ struct glk *nxt;
+} glk;
+
+typedef struct Lock
+{
+ glk ByteLock;
+} Lock;
+
+static Lock *l, *lk;
+
+void bytelocks(glk *rethead, jmp_buf jb)
+{
+ glk *cur, *cur_lk;
+
+ if (( setjmp (jb)) == 0)
+ for (cur = &l->ByteLock; cur != ((glk *)0) ; cur = (cur)->nxt)
+ for (cur_lk = &lk->ByteLock; cur_lk != ((glk *)0); cur_lk = cur_lk->nxt)
+ {
+ glk *retrng;
+
+ if(!rethead)
+ rethead = (glk *) my_malloc (sizeof(glk));
+ retrng = (glk *) my_malloc (sizeof(glk));
+
+ retrng->nxt = rethead;
+ }
+
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97359.c b/gcc/testsuite/gcc.dg/pr97359.c
new file mode 100644
index 0000000..142542e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97359.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+typedef unsigned int uint32_t;
+int a;
+void b(uint32_t c) {
+ uint32_t *d = &c;
+ for (; a;)
+ for (;; (*d %= a) / (*d > 1 > (c > 0)) ?: d)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr97371.c b/gcc/testsuite/gcc.dg/pr97371.c
new file mode 100644
index 0000000..ffefad0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr97371.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -w" } */
+
+int a, b;
+void c() {
+ if (b >> 38)
+ a = b;
+}
diff --git a/gcc/testsuite/gcc.dg/pubtypes-2.c b/gcc/testsuite/gcc.dg/pubtypes-2.c
index 6669f3d..116e348 100644
--- a/gcc/testsuite/gcc.dg/pubtypes-2.c
+++ b/gcc/testsuite/gcc.dg/pubtypes-2.c
@@ -2,7 +2,7 @@
/* { dg-options "-O0 -gdwarf-2 -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
/* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x12e+\[ \t\]+\[#;]+\[ \t\]+Pub Info Length" } } */
+/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} } } */
/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
diff --git a/gcc/testsuite/gcc.dg/pubtypes-3.c b/gcc/testsuite/gcc.dg/pubtypes-3.c
index 345e4ed..3fb3468 100644
--- a/gcc/testsuite/gcc.dg/pubtypes-3.c
+++ b/gcc/testsuite/gcc.dg/pubtypes-3.c
@@ -2,7 +2,7 @@
/* { dg-options "-O0 -gdwarf-2 -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
/* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x12e+\[ \t\]+\[#;]+\[ \t\]+Pub Info Length" } } */
+/* { dg-final { scan-assembler {long+[ \t]+0x14d+[ \t]+[#;]+[ \t]+Pub Info Length} } } */
/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
/* { dg-final { scan-assembler-not "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
diff --git a/gcc/testsuite/gcc.dg/pubtypes-4.c b/gcc/testsuite/gcc.dg/pubtypes-4.c
index da2f9b0..83fba8d 100644
--- a/gcc/testsuite/gcc.dg/pubtypes-4.c
+++ b/gcc/testsuite/gcc.dg/pubtypes-4.c
@@ -2,7 +2,7 @@
/* { dg-options "-O0 -gdwarf-2 -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } } */
/* { dg-final { scan-assembler "__debug_pubtypes" } } */
-/* { dg-final { scan-assembler "long+\[ \t\]+0x165+\[ \t\]+\[#;]+\[ \t\]+Pub Info Length" } } */
+/* { dg-final { scan-assembler {long+[ \t]+0x184+[ \t]+[#;]+[ \t]+Pub Info Length} } } */
/* { dg-final { scan-assembler "used_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
/* { dg-final { scan-assembler-not "unused_struct\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
/* { dg-final { scan-assembler "\"list_name_type\\\\0\"+\[ \t\]+\[#;]+\[ \t\]+external name" } } */
diff --git a/gcc/testsuite/gcc.dg/redecl-4.c b/gcc/testsuite/gcc.dg/redecl-4.c
index 8f12488..2c214bb 100644
--- a/gcc/testsuite/gcc.dg/redecl-4.c
+++ b/gcc/testsuite/gcc.dg/redecl-4.c
@@ -15,7 +15,7 @@ f (void)
/* Should get format warnings even though the built-in declaration
isn't "visible". */
printf (
- "%s", 1); /* { dg-warning "8:format" } */
+ "%s", 1); /* { dg-warning "15:format" } */
/* The type of strcmp here should have no prototype. */
if (0)
strcmp (1);
diff --git a/gcc/testsuite/gcc.dg/sinatan-2.c b/gcc/testsuite/gcc.dg/sinatan-2.c
index 8e7ea3c..64d6d30 100644
--- a/gcc/testsuite/gcc.dg/sinatan-2.c
+++ b/gcc/testsuite/gcc.dg/sinatan-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-optimized" } */
+/* { dg-require-effective-target c99_runtime } */
extern float sinf (float);
extern float cosf (float);
diff --git a/gcc/testsuite/gcc.dg/sinhovercosh-1.c b/gcc/testsuite/gcc.dg/sinhovercosh-1.c
index d41093f..564d3c5 100644
--- a/gcc/testsuite/gcc.dg/sinhovercosh-1.c
+++ b/gcc/testsuite/gcc.dg/sinhovercosh-1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-optimized" } */
+/* { dg-require-effective-target c99_runtime } */
extern float sinhf (float);
extern float coshf (float);
diff --git a/gcc/testsuite/gcc.dg/spellcheck-inttypes.c b/gcc/testsuite/gcc.dg/spellcheck-inttypes.c
index 1146a7c..611d7f0 100644
--- a/gcc/testsuite/gcc.dg/spellcheck-inttypes.c
+++ b/gcc/testsuite/gcc.dg/spellcheck-inttypes.c
@@ -1,7 +1,7 @@
/* { dg-options "-std=c99" } */
/* Prevent AIX from implicitly including inttypes.h. */
#ifdef _AIX
-#define _H_INTTYPES_TYPE_TS
+#define _STD_TYPES_T
#endif
#include <stdio.h>
#include <stdint.h>
diff --git a/gcc/testsuite/gcc.dg/store_merging_31.c b/gcc/testsuite/gcc.dg/store_merging_31.c
new file mode 100644
index 0000000..32c21eb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/store_merging_31.c
@@ -0,0 +1,27 @@
+/* PR tree-optimization/97053 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+struct S { short a; char b[9]; int c; char d; int e; };
+
+__attribute__((noipa)) void
+foo (char *x, char *y)
+{
+ if (__builtin_strcmp (x, "ABCDXXXX") != 0
+ || __builtin_strcmp (y, "ABCDXXXX") != 0)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+ char a[9] = "XXXXXXXX";
+ struct S b = {};
+ __builtin_memcpy (a, "ABCD", 4);
+ b.a = 5;
+ __builtin_memcpy (b.b, a, 8);
+ b.d = 'X';
+ b.e = 1;
+ foo (a, b.b);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/store_merging_32.c b/gcc/testsuite/gcc.dg/store_merging_32.c
new file mode 100644
index 0000000..8c90489
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/store_merging_32.c
@@ -0,0 +1,129 @@
+/* PR tree-optimization/97053 */
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-tree-dse" } */
+
+struct __attribute__((packed, may_alias)) S { long long s; };
+struct __attribute__((packed, may_alias)) T { short t; };
+
+__attribute__((noipa)) void
+test (char *p, char *q, int s)
+{
+ if ((s & 1) == 0)
+ {
+ if (*(short __attribute__((may_alias)) *) &p[sizeof (short)]
+ != *(short __attribute__((may_alias)) *) &q[sizeof (short)]
+ || (((struct S __attribute__((may_alias)) *) &p[1])->s
+ != ((struct S __attribute__((may_alias)) *) &q[1])->s)
+ || (*(short __attribute__((may_alias)) *) &p[2 * sizeof (short)]
+ != *(short __attribute__((may_alias)) *) &q[2 * sizeof (short)]))
+ __builtin_abort ();
+ }
+ else
+ {
+ if (*(short __attribute__((may_alias)) *) &p[sizeof (short)]
+ != *(short __attribute__((may_alias)) *) &q[sizeof (short)]
+ || (((struct S __attribute__((may_alias)) *) &p[1])->s
+ != ((struct S __attribute__((may_alias)) *) &q[1])->s)
+ || (((struct T __attribute__((may_alias)) *) &p[2 * sizeof (short) - 1])->t
+ != ((struct T __attribute__((may_alias)) *) &q[2 * sizeof (short) - 1])->t)
+ || p[3 * sizeof (short) - 2] != q[3 * sizeof (short) - 2])
+ __builtin_abort ();
+ }
+}
+
+__attribute__((noipa)) void
+foo (long long *p, char *q, char *r, char *s)
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = 1;
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &a[2 * sizeof (short)] = 2;
+ *(short __attribute__((may_alias)) *) &q[sizeof (short)] = 1;
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &s[2 * sizeof (short)] = 2;
+ test (a, q, 0);
+}
+
+__attribute__((noipa)) void
+bar (long long *p, char *q, char *r, char *s, char *t)
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = 1;
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ ((struct T __attribute__((may_alias)) *) &a[2 * sizeof (short) - 1])->t = 2;
+ a[3 * sizeof (short) - 2] = 3;
+ *(short __attribute__((may_alias)) *) &q[sizeof (short)] = 1;
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ ((struct T __attribute__((may_alias)) *) &s[2 * sizeof (short) - 1])->t = 2;
+ t[3 * sizeof (short) - 2] = 3;
+ test (a, q, 1);
+}
+
+__attribute__((noipa)) void
+baz (long long *p, char *q, char *r, char *s)
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[2 * sizeof (short)] = 2;
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = 1;
+ *(short __attribute__((may_alias)) *) &q[2 * sizeof (short)] = 2;
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &s[sizeof (short)] = 1;
+ test (a, q, 2);
+}
+
+__attribute__((noipa)) void
+qux (long long *p, char *q, char *r, char *s, char *t)
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[2 * sizeof (short) - 1] = 2;
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ a[3 * sizeof (short) - 2] = 3;
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = 1;
+ ((struct T __attribute__((may_alias)) *) &q[2 * sizeof (short) - 1])->t = 2;
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ s[3 * sizeof (short) - 2] = 3;
+ ((struct T __attribute__((may_alias)) *) &t[sizeof (short)])->t = 1;
+ test (a, q, 3);
+}
+
+__attribute__((noipa)) void
+corge (long long *p, char *q, char *r, char *s, short u[3])
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[2 * sizeof (short)] = u[2];
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = u[1];
+ *(short __attribute__((may_alias)) *) &q[2 * sizeof (short)] = u[2];
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &s[sizeof (short)] = u[1];
+ test (a, q, 4);
+}
+
+__attribute__((noipa)) void
+garply (long long *p, char *q, char *r, char *s, short u[3])
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ *(short __attribute__((may_alias)) *) &a[sizeof (short)] = u[1];
+ ((struct S __attribute__((may_alias)) *) &a[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &a[2 * sizeof (short)] = u[2];
+ *(short __attribute__((may_alias)) *) &s[sizeof (short)] = u[1];
+ ((struct S __attribute__((may_alias)) *) &r[1])->s = p[0];
+ *(short __attribute__((may_alias)) *) &q[2 * sizeof (short)] = u[2];
+ test (a, q, 6);
+}
+
+int
+main ()
+{
+ char a[64] __attribute__((aligned (__alignof (short))));
+ long long p = -1LL;
+ short u[] = { 1, 2, 3 };
+ foo (&p, &a[0], &a[0], &a[0]);
+ bar (&p, &a[0], &a[0], &a[0], &a[0]);
+ baz (&p, &a[0], &a[0], &a[0]);
+ qux (&p, &a[0], &a[0], &a[0], &a[0]);
+ corge (&p, &a[0], &a[0], &a[0], u);
+ garply (&p, &a[0], &a[0], &a[0], u);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/strcmpopt_10.c b/gcc/testsuite/gcc.dg/strcmpopt_10.c
index 94fda59..d7f94ac 100644
--- a/gcc/testsuite/gcc.dg/strcmpopt_10.c
+++ b/gcc/testsuite/gcc.dg/strcmpopt_10.c
@@ -3,7 +3,7 @@
when the pointer pointed to by the enclosing object references an object
sufficiently large to store a string of equal length.
{ dg-do compile }
- { dg-options "-O2 -Wall -Wextra -fdump-tree-optimized" } */
+ { dg-options "-O2 -Wall -Wextra -Wno-stringop-overread -fdump-tree-optimized" } */
void init (void*);
diff --git a/gcc/testsuite/gcc.dg/strcmpopt_12.c b/gcc/testsuite/gcc.dg/strcmpopt_12.c
new file mode 100644
index 0000000..d8077b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strcmpopt_12.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/96758 */
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+int v = 1;
+
+int
+main ()
+{
+ const char *s = v ? "a" : "b";
+ char x[5];
+ char y[5] = "a\0a";
+ __builtin_memcpy (x, y, sizeof (y));
+ if (__builtin_strncmp (x, s, 4) != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-55.c b/gcc/testsuite/gcc.dg/strlenopt-55.c
index ea6fb22..ca89ecd 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-55.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-55.c
@@ -3,7 +3,8 @@
Verify that strlen() of braced initialized array is folded
{ dg-do compile }
- { dg-options "-O1 -Wall -fdump-tree-gimple -fdump-tree-optimized" } */
+ { dg-options "-O1 -Wall -fdump-tree-gimple -fdump-tree-optimized" }
+ { dg-require-effective-target large_initializer } */
#include "strlenopt.h"
diff --git a/gcc/testsuite/gcc.dg/strlenopt-57.c b/gcc/testsuite/gcc.dg/strlenopt-57.c
index b7212bc..2f67bab 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-57.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-57.c
@@ -21,9 +21,9 @@ void test_var_flexarray_cst_off (void)
{
/* Use arbitrary constants greater than 16 in case GCC ever starts
unrolling strlen() calls with small array arguments. */
- a[0] = 17 < strlen (a0.a + 1); // { dg-warning "\\\[-Warray-bounds" }
- a[1] = 19 < strlen (a1.a + 1);
- a[2] = 23 < strlen (a9.a + 9);
+ a[0] = 17 < strlen (a0.a + 1); // { dg-warning "\\\[-Warray-bounds|-Wstringop-overread" }
+ a[1] = 19 < strlen (a1.a + 1); // { dg-warning "\\\[-Wstringop-overread" }
+ a[2] = 23 < strlen (a9.a + 9); // { dg-warning "\\\[-Wstringop-overread" }
a[3] = 29 < strlen (ax.a + 3);
}
diff --git a/gcc/testsuite/gcc.dg/strlenopt-83.c b/gcc/testsuite/gcc.dg/strlenopt-83.c
index 5baafea..baa80cf 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-83.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-83.c
@@ -1,7 +1,8 @@
/* PR tree-optimization/83821 - local aggregate initialization defeats
strlen optimization
{ dg-do compile }
- { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+ { dg-options "-O2 -Wall -fdump-tree-optimized" }
+ { dg-require-effective-target alloca } */
#include "strlenopt.h"
char *p_p2, *p_p5, *p_p9, *p_p14;
diff --git a/gcc/testsuite/gcc.dg/strlenopt-84.c b/gcc/testsuite/gcc.dg/strlenopt-84.c
index d6102b6..0c9da3c 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-84.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-84.c
@@ -3,7 +3,8 @@
Verify that stores that overwrite an interior nul are correctly
reflected in strlen results.
{ dg-do run }
- { dg-options "-O2 -Wall" } */
+ { dg-options "-O2 -Wall" }
+ { dg-require-effective-target alloca } */
#define false (0 == 1)
#define true (0 == 0)
diff --git a/gcc/testsuite/gcc.dg/strlenopt-91.c b/gcc/testsuite/gcc.dg/strlenopt-91.c
index 2381d03..a305561 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-91.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-91.c
@@ -1,7 +1,8 @@
/* PR tree-optimization/92412 - excessive errno aliasing assumption defeats
optimization
{ dg-do compile }
- { dg-options "-O2 -Wall -fdump-tree-optimized" } */
+ { dg-options "-O2 -Wall -fdump-tree-optimized" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/strncmp-3.c b/gcc/testsuite/gcc.dg/strncmp-3.c
new file mode 100644
index 0000000..0e8101c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/strncmp-3.c
@@ -0,0 +1,57 @@
+/* PR middle-end/95189 - memcmp being wrongly stripped like strcmp
+ { dg-do run }
+ { dg-options "-O2 -Wall" } */
+
+#define AB_D "ab\0d"
+#define ABCDEF_H "abcdef\0h"
+#define ABCDEFGHIJKLMN_P "abcdefghijklmn\0p"
+
+char ab_d[] = AB_D;
+char abcdef_h[] = ABCDEF_H;
+
+extern int strncmp (const char*, const char*, __SIZE_TYPE__);
+
+__attribute__((noipa)) void sink (const void *p, ...) { (void)&p; }
+
+#define strncmp(a, b, n) (sink (a, b), strncmp (a, b, n))
+
+int main (void)
+{
+ int zero = 0;
+
+ zero += strncmp (ab_d, AB_D, 1);
+ zero += strncmp (ab_d, AB_D, 2);
+ zero += strncmp (ab_d, AB_D, 3);
+ zero += strncmp (ab_d, AB_D, 4);
+ zero += strncmp (ab_d, AB_D, 5);
+
+ zero += strncmp (ab_d, ABCDEF_H, 1);
+ zero += strncmp (ab_d, ABCDEF_H, 2);
+
+ zero += strncmp (abcdef_h, AB_D, 2);
+
+ zero += strncmp (abcdef_h, ABCDEF_H, 2);
+ zero += strncmp (abcdef_h, ABCDEF_H, 3);
+ zero += strncmp (abcdef_h, ABCDEF_H, 4);
+ zero += strncmp (abcdef_h, ABCDEF_H, 5);
+ zero += strncmp (abcdef_h, ABCDEF_H, 6);
+ zero += strncmp (abcdef_h, ABCDEF_H, 7);
+ zero += strncmp (abcdef_h, ABCDEF_H, 8);
+ zero += strncmp (abcdef_h, ABCDEF_H, 9);
+
+ if (zero != 0)
+ __builtin_abort ();
+
+ int neg = 0;
+
+ neg -= strncmp (ab_d, ABCDEF_H, 3) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 4) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 5) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 6) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 7) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 8) < 0;
+ neg -= strncmp (ab_d, ABCDEF_H, 9) < 0;
+
+ if (neg != -7)
+ __builtin_abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/tanhbysinh.c b/gcc/testsuite/gcc.dg/tanhbysinh.c
index fde72c2..9dbe133 100644
--- a/gcc/testsuite/gcc.dg/tanhbysinh.c
+++ b/gcc/testsuite/gcc.dg/tanhbysinh.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-Ofast -fdump-tree-optimized" } */
+/* { dg-require-effective-target c99_runtime } */
extern float sinhf (float);
extern float tanhf (float);
@@ -37,4 +38,4 @@ tanhbysinhl_ (long double x)
/* {dg-final { scan-tree-dump-not "tanhl " "optimized" }} */
/* { dg-final { scan-tree-dump "cosh " "optimized" } } */
/* { dg-final { scan-tree-dump "coshf " "optimized" } } */
-/* { dg-final { scan-tree-dump "coshl " "optimized" } } */ \ No newline at end of file
+/* { dg-final { scan-tree-dump "coshl " "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c
index 84eedfd..7145671 100644
--- a/gcc/testsuite/gcc.dg/tls/thr-cse-1.c
+++ b/gcc/testsuite/gcc.dg/tls/thr-cse-1.c
@@ -4,6 +4,7 @@
registers and thus getting the counts wrong. */
/* { dg-additional-options "-mshort-calls" { target epiphany-*-* } } */
/* { dg-require-effective-target tls_emulated } */
+/* { dg-additional-options "-fdump-rtl-final-slim" { target nvptx-*-* } }*/
/* Test that we only get one call to emutls_get_address when CSE is
active. Note that the var _must_ be initialized for the scan asm
@@ -18,10 +19,12 @@ int foo (int b, int c, int d)
return a;
}
-/* { dg-final { scan-assembler-not "emutls_get_address.*emutls_get_address.*" { target { ! { "*-wrs-vxworks" "*-*-darwin8" "hppa*-*-hpux*" "i?86-*-mingw*" "x86_64-*-mingw*" visium-*-* } } } } } */
+/* { dg-final { scan-assembler-not "emutls_get_address.*emutls_get_address.*" { target { ! { "*-wrs-vxworks" "*-*-darwin8" "hppa*-*-hpux*" "i?86-*-mingw*" "x86_64-*-mingw*" visium-*-* nvptx-*-* } } } } } */
/* { dg-final { scan-assembler-not "call\tL___emutls_get_address.stub.*call\tL___emutls_get_address.stub.*" { target "*-*-darwin8" } } } */
/* { dg-final { scan-assembler-not "(b,l|bl) __emutls_get_address.*(b,l|bl) __emutls_get_address.*" { target "hppa*-*-hpux*" } } } */
/* { dg-final { scan-assembler-not "tls_lookup.*tls_lookup.*" { target *-wrs-vxworks } } } */
/* { dg-final { scan-assembler-not "call\t___emutls_get_address.*call\t___emutls_get_address" { target "i?86-*-mingw*" } } } */
/* { dg-final { scan-assembler-not "call\t__emutls_get_address.*call\t__emutls_get_address" { target "x86_64-*-mingw*" } } } */
/* { dg-final { scan-assembler-not "%l __emutls_get_address.*%l __emutls_get_address" { target visium-*-* } } } */
+
+/* { dg-final { scan-rtl-dump-times "emutls_get_address" 1 "final" { target nvptx-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/torture/20200727-0.c b/gcc/testsuite/gcc.dg/torture/20200727-0.c
new file mode 100644
index 0000000..ab91568
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/20200727-0.c
@@ -0,0 +1,82 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-g" } */
+
+typedef long unsigned int size_t;
+typedef signed int __int32_t;
+typedef __int32_t int32_t;
+typedef long int ptrdiff_t;
+typedef enum {
+ BT_UNKNOWN = 0, BT_INTEGER, BT_LOGICAL, BT_REAL, BT_COMPLEX, BT_DERIVED, BT_CHARACTER, BT_CLASS, BT_PROCEDURE, BT_HOLLERITH, BT_VOID, BT_ASSUMED, BT_UNION, BT_BOZ } bt;
+typedef int32_t GFC_INTEGER_4;
+typedef ptrdiff_t index_type;
+typedef size_t gfc_charlen_type;
+typedef struct descriptor_dimension {
+ index_type _stride;
+ index_type lower_bound;
+ } descriptor_dimension;
+typedef struct {
+ descriptor_dimension dim[15];
+ } gfc_full_array_i4;
+typedef void (*formatted_dtio)(void *, GFC_INTEGER_4 *, char *, gfc_full_array_i4 *, GFC_INTEGER_4 *, char *, gfc_charlen_type, gfc_charlen_type);
+typedef enum { DECIMAL_POINT, DECIMAL_COMMA, DECIMAL_UNSPECIFIED } unit_decimal;
+typedef struct st_parameter_dt {
+ union {
+ struct {
+ struct gfc_unit *current_unit;
+ unsigned namelist_mode : 1;
+ unsigned unit_is_internal : 1;
+ formatted_dtio fdtio_ptr;
+ } p;
+ } u;
+ } st_parameter_dt;
+typedef struct gfc_unit {
+ int unit_number;
+ unit_decimal decimal_status;
+ int (*next_char_fn_ptr) (st_parameter_dt *);
+ void (*push_char_fn_ptr) (st_parameter_dt *, int);
+ } gfc_unit;
+void read_real (st_parameter_dt *dtp)
+{
+ int c;
+ int seen_dp;
+ seen_dp = 0;
+ for (;;)
+ {
+ c = ((dtp)->u.p.current_unit->next_char_fn_ptr (dtp));
+ if (c == ',' && dtp->u.p.current_unit->decimal_status == DECIMAL_COMMA)
+ c = '.';
+ switch (c) {
+ case '.':
+ if (seen_dp) goto bad_real;
+ seen_dp = 1;
+ ((dtp)->u.p.current_unit->push_char_fn_ptr (dtp, c));
+ goto real_loop;
+ case 'E':
+ case 'e':
+ case 'D':
+ case 'd':
+ case 'Q':
+ case 'q':
+ goto exp1;
+ case '+':
+ case '-':
+ ((dtp)->u.p.current_unit->push_char_fn_ptr (dtp, 'e'));
+ goto got_repeat;
+ }
+ }
+got_repeat:
+real_loop:
+ for (;;)
+ {
+ c = ((dtp)->u.p.current_unit->next_char_fn_ptr (dtp));
+ switch (c) {
+ case '.':
+ if (seen_dp) goto bad_real;
+ seen_dp = 1;
+ ((dtp)->u.p.current_unit->push_char_fn_ptr (dtp, c));
+ }
+ }
+exp1:
+bad_real:
+ return;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
index 11367d1..12e6f25 100644
--- a/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
+++ b/gcc/testsuite/gcc.dg/torture/Wsizeof-pointer-memaccess1.c
@@ -1,6 +1,6 @@
/* Test -Wsizeof-pointer-memaccess warnings. */
/* { dg-do compile } */
-/* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow -Wno-stringop-truncation" } */
+/* { dg-options "-Wall -Wno-array-bounds -Wno-sizeof-array-argument -Wno-stringop-overflow -Wno-stringop-overread -Wno-stringop-truncation" } */
/* Test just twice, once with -O0 non-fortified, once with -O2 fortified. */
/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O2" } } */
/* { dg-skip-if "" { *-*-* } { "-flto" } { "" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
index 707d539..1070230 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-3.c
@@ -4,6 +4,7 @@
/* { dg-require-effective-target int128 } */
/* { dg-require-effective-target fenv } */
/* { dg-options "-frounding-math" } */
+/* { dg-xfail-run-if "see PR80556 c63" { x86_64-*-darwin* i68?-*-darwin* } { "*" } { "" } } */
#include <fenv.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
index 09600f9..3facf32 100644
--- a/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
+++ b/gcc/testsuite/gcc.dg/torture/fp-int-convert-timode-4.c
@@ -4,6 +4,7 @@
/* { dg-require-effective-target int128 } */
/* { dg-require-effective-target fenv } */
/* { dg-options "-frounding-math" } */
+/* { dg-xfail-run-if "see PR80556 c63" { x86_64-*-darwin* i68?-*-darwin* } { "*" } { "" } } */
#include <fenv.h>
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.dg/torture/pr39074-2.c b/gcc/testsuite/gcc.dg/torture/pr39074-2.c
index 0693f2d..7286a4f 100644
--- a/gcc/testsuite/gcc.dg/torture/pr39074-2.c
+++ b/gcc/testsuite/gcc.dg/torture/pr39074-2.c
@@ -30,5 +30,5 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */
-/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.\?.._. = { i }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.\?.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr39074.c b/gcc/testsuite/gcc.dg/torture/pr39074.c
index 54c444e..40ecdb9 100644
--- a/gcc/testsuite/gcc.dg/torture/pr39074.c
+++ b/gcc/testsuite/gcc.dg/torture/pr39074.c
@@ -29,5 +29,5 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "y.._. = { i }" "alias" } } */
-/* { dg-final { scan-tree-dump "y.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.\?.._. = { i }" "alias" } } */
+/* { dg-final { scan-tree-dump "y.\?.._., points-to NULL, points-to vars: { D..... }" "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr57147-1.c b/gcc/testsuite/gcc.dg/torture/pr57147-1.c
index 5c2a30e..5fd4ee7 100644
--- a/gcc/testsuite/gcc.dg/torture/pr57147-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pr57147-1.c
@@ -2,11 +2,11 @@
/* { dg-options "-fdump-tree-optimized" } */
/* { dg-skip-if "" { *-*-* } { "-fno-fat-lto-objects" } { "" } } */
-struct __jmp_buf_tag {};
+struct __jmp_buf_tag { int mask; };
typedef struct __jmp_buf_tag jmp_buf[1];
extern int _setjmp (struct __jmp_buf_tag __env[1]);
-jmp_buf g_return_jmp_buf;
+extern jmp_buf g_return_jmp_buf;
void SetNaClSwitchExpectations (void)
{
diff --git a/gcc/testsuite/gcc.dg/torture/pr57147-3.c b/gcc/testsuite/gcc.dg/torture/pr57147-3.c
index 7a5926a..699c7f9 100644
--- a/gcc/testsuite/gcc.dg/torture/pr57147-3.c
+++ b/gcc/testsuite/gcc.dg/torture/pr57147-3.c
@@ -1,8 +1,7 @@
/* { dg-do compile } */
typedef char * ptr_t;
-struct __jmp_buf_tag {
-};
+struct __jmp_buf_tag { int mask; };
typedef struct __jmp_buf_tag sigjmp_buf[1];
sigjmp_buf GC_jmp_buf;
int __sigsetjmp (sigjmp_buf, int);
diff --git a/gcc/testsuite/gcc.dg/torture/pr59330.c b/gcc/testsuite/gcc.dg/torture/pr59330.c
index 74b832e..536171e 100644
--- a/gcc/testsuite/gcc.dg/torture/pr59330.c
+++ b/gcc/testsuite/gcc.dg/torture/pr59330.c
@@ -1,4 +1,5 @@
/* { dg-do run } */
+/* { dg-skip-if "free inseparable from malloc when wrapped" { mmix-knuth-mmixware } } */
void free(void *ptr)
{
diff --git a/gcc/testsuite/gcc.dg/torture/pr92088-1.c b/gcc/testsuite/gcc.dg/torture/pr92088-1.c
index b56f8ad..488bdcb 100644
--- a/gcc/testsuite/gcc.dg/torture/pr92088-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pr92088-1.c
@@ -1,4 +1,5 @@
/* { dg-do run } */
+/* { dg-require-effective-target alloca } */
int __attribute__((noipa))
g (char *p)
diff --git a/gcc/testsuite/gcc.dg/torture/pr92088-2.c b/gcc/testsuite/gcc.dg/torture/pr92088-2.c
index a20a01c..6c9e504 100644
--- a/gcc/testsuite/gcc.dg/torture/pr92088-2.c
+++ b/gcc/testsuite/gcc.dg/torture/pr92088-2.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target alloca } */
void foo(int n)
{
diff --git a/gcc/testsuite/gcc.dg/torture/pr93124.c b/gcc/testsuite/gcc.dg/torture/pr93124.c
index 16bc8b5..0d361d8 100644
--- a/gcc/testsuite/gcc.dg/torture/pr93124.c
+++ b/gcc/testsuite/gcc.dg/torture/pr93124.c
@@ -1,4 +1,5 @@
/* { dg-additional-options "-fno-rerun-cse-after-loop -fno-guess-branch-probability -fno-tree-fre" } */
+/* { dg-require-effective-target alloca } */
int x;
diff --git a/gcc/testsuite/gcc.dg/torture/pr94479.c b/gcc/testsuite/gcc.dg/torture/pr94479.c
index 53285bb..3e40582 100644
--- a/gcc/testsuite/gcc.dg/torture/pr94479.c
+++ b/gcc/testsuite/gcc.dg/torture/pr94479.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-require-stack-check "specific" } */
/* { dg-additional-options "-fstack-check -w" } */
+/* { dg-require-effective-target alloca } */
int a;
struct b {
diff --git a/gcc/testsuite/gcc.dg/torture/pr96130.c b/gcc/testsuite/gcc.dg/torture/pr96130.c
new file mode 100644
index 0000000..f722b9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96130.c
@@ -0,0 +1,26 @@
+/* PR ipa/96130 */
+/* { dg-do compile } */
+
+struct S { unsigned j : 3; };
+int k, l, m;
+
+void
+foo (struct S x)
+{
+ while (l != 5)
+ switch (x.j)
+ {
+ case 1:
+ case 3:
+ case 4:
+ case 6:
+ case 2:
+ case 5:
+ l = m;
+ case 7:
+ case 0:
+ k = 0;
+ default:
+ break;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96133.c b/gcc/testsuite/gcc.dg/torture/pr96133.c
index 8d051ce..ac31a71 100644
--- a/gcc/testsuite/gcc.dg/torture/pr96133.c
+++ b/gcc/testsuite/gcc.dg/torture/pr96133.c
@@ -1,7 +1,7 @@
/* { dg-do run } */
typedef int T;
-static const T a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
+static const T a[2][3] __attribute__((aligned(2*sizeof(T)))) = { { 1, 2, 3 }, { 4, 5, 6 } };
typedef T v2 __attribute__((vector_size(2*sizeof(T))));
int
diff --git a/gcc/testsuite/gcc.dg/torture/pr96349.c b/gcc/testsuite/gcc.dg/torture/pr96349.c
new file mode 100644
index 0000000..4ce3949
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96349.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+
+void __attribute__ ((returns_twice))
+gr (void);
+
+void
+ib (void);
+
+void
+zg (void);
+
+void
+yw (int uz)
+{
+ gr ();
+
+ for (;;)
+ if (uz != 0)
+ {
+ uz = 0;
+ ib ();
+ }
+ else
+ zg ();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96491.c b/gcc/testsuite/gcc.dg/torture/pr96491.c
new file mode 100644
index 0000000..784559f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96491.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+
+int rj;
+
+void __attribute__ ((returns_twice))
+da (void)
+{
+ rj = 1;
+}
+
+void
+c5 (void)
+{
+ for (;;)
+ ++rj;
+}
+
+void
+ls (int kz)
+{
+ if (kz == 0)
+ {
+ rj = 0;
+ c5 ();
+ }
+
+ da ();
+ c5 ();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96522.c b/gcc/testsuite/gcc.dg/torture/pr96522.c
new file mode 100644
index 0000000..2f55d1a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96522.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-additional-options "-fno-tree-pta" } */
+
+__attribute__((noipa)) void
+bar (void)
+{
+ volatile int v = 1;
+ if (v)
+ __builtin_abort ();
+}
+
+__attribute__((noipa)) void
+baz (void)
+{
+}
+
+__attribute__((noipa)) void
+foo (int n, double *p, double *x)
+{
+ if (n < 10 && p != 0)
+ for (int i = 0; i < 10; i++)
+ if (x[0] < p[i])
+ x[i] = 0;
+ if (p != 0)
+ bar ();
+ else
+ baz ();
+}
+
+int
+main ()
+{
+ double arr[10];
+ foo (1000, 0, arr);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96548.c b/gcc/testsuite/gcc.dg/torture/pr96548.c
new file mode 100644
index 0000000..a054742
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96548.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int c9, d3;
+
+void
+sg (int *rs, int f2)
+{
+ for (;;)
+ {
+ if (*rs < 1)
+ __builtin_unreachable ();
+
+ for (c9 = 0; c9 < 1; ++c9)
+ while (f2 < 1)
+ ++c9;
+
+ if (d3)
+ c9 += !!f2 ? 0 : d3;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr96760.c b/gcc/testsuite/gcc.dg/torture/pr96760.c
new file mode 100644
index 0000000..4f6bbe9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr96760.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+char a = 0, f = 0, c = 5;
+unsigned long d = 0;
+int g = 0;
+int *e = &g;
+
+int main() {
+ char b = 0;
+ for (;;) {
+ for (a = 0; a < 2; a++) { // no UB I believe
+ if (c) {
+ if (d != 0)
+ __builtin_abort ();
+ return 0;
+ }
+ }
+ f = (d++, *e);
+ }
+
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97135.c b/gcc/testsuite/gcc.dg/torture/pr97135.c
new file mode 100644
index 0000000..223f4d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97135.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+long long e, *d = &e;
+int a, b, c;
+
+int
+main ()
+{
+ for (; c <= 5; c++)
+ for (b = 0; b <= 5; b++)
+ {
+ for (a = 1; a <= 5; a++)
+ ;
+ *d = 0;
+ if (c)
+ break;
+ }
+ if (a != 6)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97330-1.c b/gcc/testsuite/gcc.dg/torture/pr97330-1.c
new file mode 100644
index 0000000..7dce5bd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97330-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+typedef int a;
+typedef char b;
+int c;
+void d(e, f, dst, g, avail, h) int e;
+b *f, *dst;
+a g, avail;
+int h;
+{
+ b i = *f;
+ if (e)
+ goto j;
+ while (avail) {
+ *dst = i;
+ j:
+ avail -= c;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr97330-2.c b/gcc/testsuite/gcc.dg/torture/pr97330-2.c
new file mode 100644
index 0000000..a064483
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr97330-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+int a, b, d;
+char c, e;
+void f(void) {
+ char g = c;
+ if (b)
+ goto h;
+ while (d) {
+ e = c;
+ h:
+ d -= a;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pta-callused-1.c b/gcc/testsuite/gcc.dg/torture/pta-callused-1.c
index b35959c..0ca6ac9 100644
--- a/gcc/testsuite/gcc.dg/torture/pta-callused-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pta-callused-1.c
@@ -21,4 +21,4 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "p.._. = { i j }" "alias" } } */
+/* { dg-final { scan-tree-dump "p.\?.._. = { i j }" "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
index 31585a0..5ec0558 100644
--- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
@@ -9,7 +9,7 @@
/* arm_hf_eabi: Variadic funcs use Base AAPCS. Normal funcs use VFP variant.
avr: Variadic funcs don't pass arguments in registers, while normal funcs
do. */
-/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* } } } */
+/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { csky*-*-* avr-*-* riscv*-*-* or1k*-*-* msp430-*-* amdgcn-*-* pru-*-* } } } */
/* { dg-skip-if "Variadic funcs have all args on stack. Normal funcs have args in registers." { nds32*-*-* } { v850*-*-* } } */
/* { dg-require-effective-target untyped_assembly } */
diff --git a/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c
index 450308d..511b610 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/cold_partition_label.c
@@ -3,6 +3,12 @@
/* { dg-require-effective-target freorder } */
/* { dg-options "-O2 -freorder-blocks-and-partition -save-temps -fdump-tree-optimized" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 1000000
+#else
+#define MAXITER 10000
+#endif
+
#define SIZE 10000
const char *sarr[SIZE];
@@ -32,7 +38,7 @@ main (int argc, char *argv[])
int i;
buf_hot = "hello";
buf_cold = "world";
- for (i = 0; i < 1000000; i++)
+ for (i = 0; i < MAXITER; i++)
foo (argc);
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-1.c b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-1.c
index a13b08c..b57d30f 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-1.c
@@ -3,6 +3,12 @@
/* { dg-require-profiling "-fprofile-generate" } */
/* { dg-options "-O2 -flto -DDOJOB=1 -fdump-ipa-profile_estimate" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 350000000
+#else
+#define MAXITER 3500000
+#endif
+
#include <stdio.h>
typedef int (*fptr) (int);
@@ -22,7 +28,7 @@ main()
x = one (3);
- for (i = 0; i < 350000000; i++)
+ for (i = 0; i < MAXITER; i++)
{
x = (*p) (3);
p = table[x];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-2.c b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-2.c
index 9b996fc..6b5ae93 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indir-call-topn-2.c
@@ -3,6 +3,12 @@
/* { dg-require-profiling "-fprofile-generate" } */
/* { dg-options "-O2 -flto -DDOJOB=1 -fdump-ipa-profile_estimate" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 350000000
+#else
+#define MAXITER 3500000
+#endif
+
#include <stdio.h>
typedef int (*fptr) (int);
@@ -21,7 +27,7 @@ int foo ()
x = one (3);
- for (i = 0; i < 350000000; i++)
+ for (i = 0; i < MAXITER; i++)
{
x = (*p) (3);
p = table[x];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-malloc.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-malloc.c
new file mode 100644
index 0000000..454e224
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-malloc.c
@@ -0,0 +1,49 @@
+/* { dg-options "-O2 -ldl" } */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+#include <dlfcn.h>
+
+int global;
+int global2;
+
+void report1 (size_t size)
+{
+ global++;
+}
+
+void report2 (size_t size)
+{
+ global2++;
+}
+
+typedef void (*tp) (size_t);
+static tp fns[] = {report1, report2};
+
+void* malloc(size_t size)
+{
+ static void* (*real_malloc)(size_t) = NULL;
+ if (!real_malloc)
+ real_malloc = dlsym(RTLD_NEXT, "malloc");
+
+ void *p = real_malloc (size);
+ fns[size % 2] (size);
+ // fprintf(stderr, "malloc(%d) = %p\n", size, p);
+ return p;
+}
+
+void *calloc (size_t n, size_t size)
+{
+ void *ptr = malloc (n * size);
+ __builtin_memset (ptr, 0, n * size);
+ return ptr;
+}
+
+void *ptr;
+
+int main()
+{
+ ptr = malloc (16);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-topn.c b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-topn.c
index 063996c..9a1a0be 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-topn.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/indir-call-prof-topn.c
@@ -1,6 +1,12 @@
/* { dg-require-profiling "-fprofile-generate" } */
/* { dg-options "-O2 -fdump-ipa-profile_estimate" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 350000000
+#else
+#define MAXITER 3500000
+#endif
+
#include <stdio.h>
typedef int (*fptr) (int);
@@ -26,7 +32,7 @@ main()
one (3);
- for (i = 0; i < 350000000; i++)
+ for (i = 0; i < MAXITER; i++)
{
x = (*p) (3);
p = table[x];
diff --git a/gcc/testsuite/gcc.dg/tree-prof/pr96394.c b/gcc/testsuite/gcc.dg/tree-prof/pr96394.c
new file mode 100644
index 0000000..4280182
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/pr96394.c
@@ -0,0 +1,64 @@
+/* PR ipa/96394 */
+/* { dg-options "-O2" } */
+
+typedef struct _entry {
+ int has_next;
+ int next_ix;
+ int count;
+} entry;
+
+extern entry table[];
+
+void *
+__attribute__((noipa))
+PyErr_Format(entry * e){ return 0; }
+
+void ae(entry *);
+int h(entry *);
+int ap(entry *);
+int ag(entry *);
+
+int ag(entry *j) {
+ if (j->has_next)
+ h(&table[j->next_ix]);
+ return 0;
+}
+static int ai(entry *j, int k(entry *), int l, int m) {
+ int am = 1;
+ int ab;
+
+ /* k is either 'h' or 'ap': 50%/50% */
+ ab = k(j);
+
+ /* loop never gets executed on real data */
+ for (; j->count >= 2; am += 2)
+ if (l) {
+ entry *i = &table[am + m];
+ PyErr_Format(i);
+ }
+ return ab;
+}
+void
+__attribute__((noipa))
+bug() {
+ h(table);
+ h(table);
+}
+int h(entry *j) { return ai(j, ap, 4, 5); }
+int ap(entry *j) { return ai(j, ag, 14, 4); }
+
+int main(void)
+{
+ bug();
+}
+
+entry table[2] = {
+ { .has_next = 1
+ , .next_ix = 1
+ , .count = 0
+ },
+ { .has_next = 0
+ , .next_ix = 0
+ , .count = 0
+ },
+};
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c
index 89ecc1c..2087d0d 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-1.c
@@ -3,6 +3,12 @@
/* { dg-require-effective-target freorder } */
/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 1000000
+#else
+#define MAXITER 10000
+#endif
+
#define SIZE 10000
#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
@@ -24,7 +30,7 @@ main (int argc, char *argv[])
int i;
buf_hot = "hello";
buf_cold = "world";
- for (i = 0; i < 1000000; i++)
+ for (i = 0; i < MAXITER; i++)
foo (argc);
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c
index b856457..b02526b 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-2.c
@@ -4,6 +4,12 @@
/* { dg-require-effective-target freorder } */
/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 1000000
+#else
+#define MAXITER 10000
+#endif
+
#define SIZE 10000
#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
@@ -20,7 +26,7 @@ main (int argc, char *argv[])
int i;
buf_hot = "hello";
buf_cold = "world";
- for (i = 0; i < 1000000; i++)
+ for (i = 0; i < MAXITER; i++)
foo (argc);
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c b/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c
index 8d85cf3..da06407 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/section-attr-3.c
@@ -4,6 +4,12 @@
/* { dg-require-effective-target freorder } */
/* { dg-options "-O2 -fno-profile-reorder-functions -freorder-blocks-and-partition -save-temps" } */
+#ifdef FOR_AUTOFDO_TESTING
+#define MAXITER 1000000
+#else
+#define MAXITER 10000
+#endif
+
#define SIZE 10000
#define NOINLINE __attribute__((noinline)) __attribute__ ((noclone))
@@ -24,7 +30,7 @@ main (int argc, char *argv[])
int i;
buf_hot = "hello";
buf_cold = "world";
- for (i = 0; i < 1000000; i++)
+ for (i = 0; i < MAXITER; i++)
foo (argc);
return 0;
}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c
index 0903f3c..0e01e51 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030807-10.c
@@ -7,7 +7,7 @@ unsigned int
subreg_highpart_offset (outermode, innermode)
int outermode, innermode;
{
- unsigned int offset = 0;
+ unsigned int offset = 1;
int difference = (mode_size[innermode] - mode_size[outermode]);
if (difference > 0)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnot-2.c b/gcc/testsuite/gcc.dg/tree-ssa/andnot-2.c
new file mode 100644
index 0000000..e0955ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnot-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */
+
+typedef long vec __attribute__((vector_size(16)));
+vec f(vec x){
+ vec y = x < 10;
+ return y & (y == 0);
+}
+
+/* { dg-final { scan-tree-dump-not "_expr" "forwprop3" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
index 6fd1bca..685a4fd 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-warn-22.c
@@ -1,7 +1,8 @@
/* PR tree-optimization/91567 - Spurious -Wformat-overflow warnings building
glibc (32-bit only)
{ dg-do compile }
- { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtins-folding-gimple-ub.c b/gcc/testsuite/gcc.dg/tree-ssa/builtins-folding-gimple-ub.c
index 0912b68..3946a8c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtins-folding-gimple-ub.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtins-folding-gimple-ub.c
@@ -14,13 +14,13 @@ main (void)
/* MEMCHR. */
if (__builtin_memchr ("", 'x', 1000)) /* Not folded away. */
{
- /* { dg-warning "reading 1000 bytes from a region of size 1" "" { target *-*-* } .-2 } */
+ /* { dg-warning "\\\[-Wstringop-overread" "" { target *-*-* } .-2 } */
__builtin_abort ();
}
if (__builtin_memchr (foo1, 'x', 1000)) /* Not folded away. */
{
- /* { dg-warning "reading 1000 bytes from a region of size 1" "" { target *-*-* } .-2 } */
+ /* { dg-warning "\\\[-Wstringop-overread" "" { target *-*-* } .-2 } */
__builtin_abort ();
}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-3.c b/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-3.c
new file mode 100644
index 0000000..f52e04d2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/copy-sign-3.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/96715 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-not "= __builtin_copysign" "optimized" } } */
+/* { dg-final { scan-tree-dump-times " = -x_\[0-9]*\\(D\\)" 3 "optimized" } } */
+
+float
+foo (float x)
+{
+ return __builtin_copysignf (x, -x);
+}
+
+double
+bar (double x)
+{
+ return __builtin_copysign (x, -x);
+}
+
+long double
+baz (long double x)
+{
+ return __builtin_copysignl (x, -x);
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
index 9de73ff..f3871bf 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-36.c
@@ -21,4 +21,5 @@ main ()
return 0;
}
-/* { dg-final { scan-tree-dump "if \\(b.0_\[0-9\]+ != 0\\)" "cddce1" } } */
+/* { dg-final { scan-tree-dump "if \\(b.0_\[0-9\]+ != 0\\)" "cddce1" { target { ! mmix-knuth-mmixware } } } } */
+/* { dg-final { scan-tree-dump "if \\(b::1_\[0-9\]+ != 0\\)" "cddce1" { target { mmix-knuth-mmixware } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/local-pure-const.c b/gcc/testsuite/gcc.dg/tree-ssa/local-pure-const.c
index 3c358e0..6746758 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/local-pure-const.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/local-pure-const.c
@@ -12,5 +12,5 @@ t(int a, int b, int c)
p = &c;
return *p;
}
-/* { dg-final { scan-tree-dump-times "local memory is OK" 1 "local-pure-const1"} } */
+/* { dg-final { scan-tree-dump-times "local or readonly memory is OK" 1 "local-pure-const1"} } */
/* { dg-final { scan-tree-dump-times "found to be const" 1 "local-pure-const1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c
index af7a3da..0c73111 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-19.c
@@ -22,6 +22,6 @@ void tuned_STREAM_Copy()
However, due to a bug in jump threading, we end up peeling one iteration from
the loop, which creates an additional occurrence. */
-/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )a," 2 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MEM.(base: &|symbol: )c," 2 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MEM\[^;\]*&a" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MEM\[^;\]*&c" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-2.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-2.c
index bda2516..e58561a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-2.c
@@ -27,7 +27,6 @@ void xxx(void)
/* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MEM\\\[base" 1 "optimized" } } */
/* 17 * iter should be strength reduced. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-3.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-3.c
index d3b26b7..74491f8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-3.c
@@ -20,8 +20,7 @@ void xxx(void)
/* Access to arr_base[iter].y should not be strength reduced, since
we have a memory mode including multiplication by 4. */
-/* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "step:" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "MEM\[^;\]* \* 4" 1 "optimized" } } */
/* And original induction variable should be preserved. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-1.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-1.c
new file mode 100644
index 0000000..a80ca6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-1.c
@@ -0,0 +1,45 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+int p,q,r,s,*ptr=&q, *ptr2=&p;
+__attribute__ ((noinline))
+int
+test (int *p)
+{
+ *p = 1;
+}
+int
+test1()
+{
+ q = 123;
+ test(&p);
+ return q;
+}
+int
+test2()
+{
+ int *ptr = p ? &q : &s;
+ *ptr = 124;
+ test(&p);
+ return *ptr;
+}
+int
+test3()
+{
+ int *ptr = p ? &p : &s;
+ q = 125;
+ test(ptr);
+ return q;
+}
+int
+test4()
+{
+ int *ptr1 = p ? &q : &s;
+ int *ptr = p ? &r : &p;
+ *ptr1 = 126;
+ test(ptr);
+ return *ptr1;
+}
+/* { dg-final { scan-tree-dump "return 123" "optimized"} } */
+/* { dg-final { scan-tree-dump "return 124" "optimized"} } */
+/* { dg-final { scan-tree-dump "return 125" "optimized"} } */
+/* { dg-final { scan-tree-dump "return 126" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-2.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-2.c
new file mode 100644
index 0000000..9999d37
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-2.c
@@ -0,0 +1,26 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+short aa;
+void
+__attribute__ ((noinline, noclone))
+recursive (int *a, int *b, int *c, int level)
+{
+ if (level && c)
+ {
+ recursive (b,a,c,0);
+ aa++;
+ }
+ else
+ *a=0;
+}
+int
+main()
+{
+ int x = 123, y=124, z=125;
+ recursive (&x,&y,&z,1);
+ if (y)
+ __builtin_abort ();
+ if (!__builtin_constant_p (z))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/modref-3.c b/gcc/testsuite/gcc.dg/tree-ssa/modref-3.c
new file mode 100644
index 0000000..668c6c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/modref-3.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+struct a
+{
+ int b;
+ int c;
+};
+
+__attribute__ ((noclone, noinline))
+void
+test (struct a *a)
+{
+ a->b = 2;
+}
+int
+foo ()
+{
+ struct a a = {113,114};
+ test (&a);
+ return a.c;
+}
+int
+foo2 (struct a *a)
+{
+ a->b = 123;
+ a->c = 124;
+ test (a);
+ return a->c;
+}
+/* { dg-final { scan-tree-dump "return 114" "optimized"} } */
+/* { dg-final { scan-tree-dump "return 124" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c
index 9c22c53..cf74e15 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr77445-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-thread-details-blocks-stats" } */
+/* { dg-options "-O2 -fdisable-tree-evrp -fdump-tree-thread-details-blocks-stats" } */
typedef enum STATES {
START=0,
INVALID,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93121-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93121-1.c
new file mode 100644
index 0000000..4bf40c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93121-1.c
@@ -0,0 +1,56 @@
+/* PR libstdc++/93121 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+union U { int a[3]; short c[6]; struct S { int d; int a : 2; int f : 1; int b : 24; int c : 5; int e; } b; };
+const union U u = { .b = { 0x7efa3412, 3, 0, 0x50eca8, 0xb, 0x1eeffeed } };
+const union U v = { .b = { 0x7efa3412, 1, 1, 0x7feedb, 0x5, 0x1eeffeed } };
+union W { struct T { long long int a, b : 11, c : 3, d : 37, e : 1, f : 10, g : 2, h; } a; int b[6]; short c[12]; long long d[3]; };
+const union W w = { .a = { 0x0feedbacdeadbeefLL, -1011, 2, -0xbacdeadbeLL, -1, 721, 1, 0x0feedbacdeadbeefLL } };
+int a, b, c, d, e, f, g, h, i, j, k, l;
+long long m;
+
+void
+foo ()
+{
+ a = u.a[1];
+ b = v.a[1];
+ c = u.c[2];
+ d = u.c[3];
+ e = v.c[2];
+ f = v.c[3];
+ g = w.b[2];
+ h = w.b[3];
+ i = w.c[4];
+ j = w.c[5];
+ k = w.c[6];
+ l = w.c[7];
+ m = w.d[1];
+}
+
+/* { dg-final { scan-tree-dump-times "a = 1518822723;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "b = 738162397;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "c = 25923;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "d = 23175;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "e = 30429;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "f = 11263;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "g = 1418761229;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "h = 1830622408;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "i = -27635;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "j = 21648;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "k = 5320;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "l = 27933;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "m = 7862463375103529997;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "a = -904030965;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "b = 1878907749;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "c = -13795;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "d = -27381;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "e = 28669;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "f = -9371;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "g = -2119529884;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "h = 709385029;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "i = -32342;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "j = -30108;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "k = 10824;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "l = 23365;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "m = -9103311533965288635;" 1 "optimized" { target be } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c
new file mode 100644
index 0000000..323dca6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr93121-2.c
@@ -0,0 +1,22 @@
+/* PR libstdc++/93121 */
+/* { dg-do compile { target { ilp32 || lp64 } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+union U { int a[3]; struct S { int d; int a : 3; int b : 24; int c : 5; int e; } b; };
+const union U u = { .a = { 0x7efa3412, 0x5a876543, 0x1eeffeed } };
+int a, b, c;
+
+void
+foo ()
+{
+ a = u.b.a;
+ b = u.b.b;
+ c = u.b.c;
+}
+
+/* { dg-final { scan-tree-dump-times "a = 3;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "b = 5303464;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "c = 11;" 1 "optimized" { target le } } } */
+/* { dg-final { scan-tree-dump-times "a = 2;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "b = -2868438;" 1 "optimized" { target be } } } */
+/* { dg-final { scan-tree-dump-times "c = 3;" 1 "optimized" { target be } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr94801.c b/gcc/testsuite/gcc.dg/tree-ssa/pr94801.c
new file mode 100644
index 0000000..5382e5e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr94801.c
@@ -0,0 +1,16 @@
+/* PR tree-optimization/94801 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump-times "return 0;" 2 "optimized" } } */
+
+int
+foo (int a)
+{
+ return __builtin_clz (a) >> 5;
+}
+
+int
+bar (int a)
+{
+ return __builtin_ctz (a) >> 5;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c
new file mode 100644
index 0000000..c830a3d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95433-2.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fwrapv -fdump-tree-gimple" } */
+
+typedef __INT32_TYPE__ int32_t;
+typedef unsigned __INT32_TYPE__ uint32_t;
+
+int e(int32_t x){return 3*x==5;}
+int f(int32_t x){return 3*x==-5;}
+int g(int32_t x){return -3*x==5;}
+int h(int32_t x){return 7*x==3;}
+int i(uint32_t x){return 7*x==3;}
+
+/* { dg-final { scan-tree-dump-times "== 1431655767" 1 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "== -1431655767" 2 "gimple" } } */
+/* { dg-final { scan-tree-dump-times "== 613566757" 2 "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c
new file mode 100644
index 0000000..4e161ee
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95433.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int f(int x){return x*7==17;}
+int g(int x){return x*3==15;}
+
+/* { dg-final { scan-tree-dump "return 0;" "optimized" } } */
+/* { dg-final { scan-tree-dump "== 5;" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
new file mode 100644
index 0000000..3d820a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr95906.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-forwprop3-raw -w -Wno-psabi" } */
+
+// FIXME: this should further optimize to a MAX_EXPR
+typedef signed char v16i8 __attribute__((vector_size(16)));
+v16i8 f(v16i8 a, v16i8 b)
+{
+ v16i8 cmp = (a > b);
+ return (cmp & a) | (~cmp & b);
+}
+
+/* { dg-final { scan-tree-dump-not "bit_(and|ior)_expr" "forwprop3" } } */
+/* { dg-final { scan-tree-dump-times "vec_cond_expr" 1 "forwprop3" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
new file mode 100644
index 0000000..f2a91ef
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96480.c
@@ -0,0 +1,23 @@
+/* PR tree-optimization/96480 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-final { scan-tree-dump " = _\[0-9]* <= 3;" "optimized" } } */
+
+int v[4];
+
+int
+foo (int x)
+{
+ int *p;
+ if (x == 0)
+ p = &v[0];
+ else if (x == 1)
+ p = &v[1];
+ else if (x == 2)
+ p = &v[2];
+ else if (x == 3)
+ p = &v[3];
+ else
+ p = &v[4];
+ return p != &v[4];
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96730.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96730.c
new file mode 100644
index 0000000..39a0684
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96730.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct a {
+ int b;
+ int c;
+} d() {
+ struct a e[9];
+ int f = 3362953455;
+ e[f] = e[6];
+ e[6].c = 1;
+}
+int main() {}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c
new file mode 100644
index 0000000..f5c2195
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct a {
+ int b;
+};
+int main() {
+ struct a d[][6] = {4};
+ struct a e;
+ d[1955249013][1955249013] = e;
+ return e.b;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96967.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96967.c
new file mode 100644
index 0000000..249dfc7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96967.c
@@ -0,0 +1,36 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fshort-enums" } */
+
+enum re {
+ o3,
+};
+
+int
+uj (int mq, enum re dn)
+{
+ enum re nr = mq;
+
+ switch (nr)
+ {
+ case 4:
+ if (dn == 0)
+ goto wdev_inactive_unlock;
+ break;
+
+ default:
+ break;
+ }
+
+ switch (nr)
+ {
+ case 0:
+ case 4:
+ return 0;
+
+ default:
+ break;
+ }
+
+ wdev_inactive_unlock:
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-20.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-20.c
index 3d2ea6b..a7d57f1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-20.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-20.c
@@ -15,5 +15,5 @@ int main(void)
printf ("%d %d\n", e, f);
}
-/* { dg-final { scan-tree-dump-times "\[ab\].._. \\\+ \[ab\].._." 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\[ab\].\?.._. \\\+ \[ab\].\?.._." 1 "optimized" } } */
/* { dg-final { scan-tree-dump-times " \\\+ " 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
index e4daa9d..a879d30 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c
@@ -27,4 +27,4 @@ foo ()
but the loop reads only one element at a time, and DOM cannot resolve these.
The same happens on powerpc depending on the SIMD support available. */
-/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* hppa*64*-*-* nvptx*-*-* } || { { { lp64 && { powerpc*-*-* sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } } } } } */
+/* { dg-final { scan-tree-dump "return 28;" "optimized" { xfail { { alpha*-*-* hppa*64*-*-* nvptx*-*-* mmix-knuth-mmixware } || { { { lp64 && { powerpc*-*-* sparc*-*-* riscv*-*-* } } || aarch64_sve } || { arm*-*-* && { ! arm_neon } } } } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c
index 551fbac..16a9ef4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-6.c
@@ -1,7 +1,41 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-thread1-details -fdump-tree-thread2-details" } */
-/* { dg-final { scan-tree-dump-times "FSM" 3 "thread1" } } */
-/* { dg-final { scan-tree-dump-times "FSM" 5 "thread2" } } */
+
+/* All the threads in the thread1 dump start on a X->BB12 edge, as can
+ be seen in the dump:
+
+ Registering FSM jump thread: (x, 12) incoming edge; ...
+ etc
+ etc
+
+ Before the new evrp, we were threading paths that started at the
+ following edges:
+
+ Registering FSM jump thread: (10, 12) incoming edge
+ Registering FSM jump thread: (6, 12) incoming edge
+ Registering FSM jump thread: (9, 12) incoming edge
+
+ This was because the PHI at BB12 had constant values coming in from
+ BB10, BB6, and BB9:
+
+ # state_10 = PHI <state_11(7), 0(10), state_11(5), 1(6), state_11(8), 2(9), state_11(11)>
+
+ Now with the new evrp, we get:
+
+ # state_10 = PHI <0(7), 0(10), state_11(5), 1(6), 0(8), 2(9), 1(11)>
+
+ Thus, we have 3 more paths that are known to be constant and can be
+ threaded. Which means that by the second threading pass, we can
+ only find one profitable path.
+
+ For the record, all these extra constants are better paths coming
+ out of switches. For example:
+
+ SWITCH_BB -> BBx -> BBy -> BBz -> PHI
+
+ We now know the value of the switch index at PHI. */
+/* { dg-final { scan-tree-dump-times "FSM" 6 "thread1" } } */
+/* { dg-final { scan-tree-dump-times "FSM" 1 "thread2" } } */
int sum0, sum1, sum2, sum3;
int foo (char *s, char **ret)
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
index a339557..bad5bc1 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-7.c
@@ -1,20 +1,31 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-thread1-stats -fdump-tree-thread2-stats -fdump-tree-dom2-stats -fdump-tree-thread3-stats -fdump-tree-dom3-stats -fdump-tree-vrp2-stats -fno-guess-branch-probability" } */
-/* { dg-final { scan-tree-dump "Jumps threaded: 16" "thread1" } } */
-/* { dg-final { scan-tree-dump "Jumps threaded: 9" "thread2" } } */
+
+/* Here we have the same issue as was commented in ssa-dom-thread-6.c.
+ The PHI coming into the threader has a lot more constants, so the
+ threader can thread more paths.
+
+$ diff clean/a.c.105t.mergephi2 a.c.105t.mergephi2
+252c252
+< # s_50 = PHI <s_49(10), 5(14), s_51(18), s_51(22), 1(26), 1(29), 1(31), s_51(5), 4(12), 1(15), 5(17), 1(19), 3(21), 1(23), 6(25), 7(28), s_51(30)>
+---
+> # s_50 = PHI <s_49(10), 5(14), 4(18), 5(22), 1(26), 1(29), 1(31), s_51(5), 4(12), 1(15), 5(17), 1(19), 3(21), 1(23), 6(25), 7(28), 7(30)>
+272a273
+
+ I spot checked a few and they all have the same pattern. We are
+ basically tracking the switch index better through multiple
+ paths. */
+
+/* { dg-final { scan-tree-dump "Jumps threaded: 19" "thread1" } } */
+/* { dg-final { scan-tree-dump "Jumps threaded: 8" "thread2" } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom2" } } */
+
/* aarch64 has the highest CASE_VALUES_THRESHOLD in GCC. It's high enough
to change decisions in switch expansion which in turn can expose new
jump threading opportunities. Skip the later tests on aarch64. */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "dom3" { target { ! aarch64*-*-* } } } } */
/* { dg-final { scan-tree-dump-not "Jumps threaded" "vrp2" { target { ! aarch64*-*-* } } } } */
-/* Most architectures get 3 threadable paths here, whereas aarch64 and
- possibly others get 5. We really should rewrite threading tests to
- test a specific IL sequence, not gobs of code whose IL can vary
- from architecture to architecture. */
-/* { dg-final { scan-tree-dump "Jumps threaded: \[35\]" "thread3" } } */
-
enum STATE {
S0=0,
SI,
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c
index 8abc28b..271e666 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-26.c
@@ -31,12 +31,14 @@ constraint_equal (struct constraint a, struct constraint b)
}
/* Most targets should be using this test. */
-/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! tic6x-*-* } } } } */
-/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! tic6x-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead store: x = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware } } } } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead store: y = " 1 "dse1" { target { ! { tic6x-*-* mmix-knuth-mmixware } } } } } */
/* The c6x port generates significantly different gimple which
changes the SRA and DSE decisions. Verify we remove all
- dead stores. */
+ dead stores. Similarly for mmix. */
/* { dg-final { scan-tree-dump-times "Deleted dead store: \[ax\].. = " 2 "dse1" { target tic6x-*-* } } } */
/* { dg-final { scan-tree-dump-times "Deleted dead store: \[by\].. = " 2 "dse1" { target tic6x-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead store: x::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */
+/* { dg-final { scan-tree-dump-times "Deleted dead store: y::. = " 1 "dse1" { target mmix-knuth-mmixware } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-40.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-40.c
new file mode 100644
index 0000000..36f69c0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dse-40.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-dse1-details" } */
+
+_Bool g(void);
+
+void f(int x)
+{
+ char arr[x];
+
+ arr[0] = 0;
+
+ if (g())
+ __builtin_abort();
+}
+
+/* { dg-final { scan-tree-dump "Deleted dead store" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-88.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-88.c
new file mode 100644
index 0000000..15d2ca0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-88.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fre1" } */
+
+double y[2];
+void foo (double x)
+{
+ y[0] = x * -3.;
+ y[1] = x * 3.;
+}
+void bar (double x, double z)
+{
+ y[0] = -z / x;
+ y[1] = z / x;
+}
+
+/* { dg-final { scan-tree-dump-times " \\* " 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times " / " 1 "fre1" } } */
+/* { dg-final { scan-tree-dump-times "= -_" 2 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-17.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-17.c
new file mode 100644
index 0000000..cf2e2a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-17.c
@@ -0,0 +1,15 @@
+/* PR tree-optimization/97307 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-sink-details" } */
+
+int pure_f(int a, int b) __attribute__((pure));
+int my_f(int a, int b)
+{
+ int x = pure_f(a, b);
+ if (a > 0)
+ return x;
+ return a;
+}
+
+/* We should sink the call to pure_f to the if block. */
+/* { dg-final { scan-tree-dump "Sinking # VUSE" "sink" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
index 17c56e9..00ddd29 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
@@ -11,5 +11,6 @@ v4si vs (v4si a, v4si b)
/* The compound literal should be placed directly in the vec_perm. */
/* Test is xfailed on 32-bit hppa*-*-* because target-callee-copies. */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR <a, b, { 0, 4, 1, 5 }>;" 1 "gimple" { xfail { hppa*-*-* && { ! lp64 } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR <a, b, { 0, 4, 1, 5 }>;" 1 "gimple" { target { ! mmix-knuth-mmixware } xfail { hppa*-*-* && { ! lp64 } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR <a::., b::., { 0, 4, 1, 5 }>;" 1 "gimple" { target mmix-knuth-mmixware } } } */
diff --git a/gcc/testsuite/gcc.dg/uninit-32.c b/gcc/testsuite/gcc.dg/uninit-32.c
index cdc0512..cf9efa0 100644
--- a/gcc/testsuite/gcc.dg/uninit-32.c
+++ b/gcc/testsuite/gcc.dg/uninit-32.c
@@ -1,7 +1,8 @@
/* PR middle-end/10138 - warn for uninitialized arrays passed as const*
arguments
{ dg-do compile }
- { dg-options "-O -Wall" } */
+ { dg-options "-O -Wall" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/uninit-33.c b/gcc/testsuite/gcc.dg/uninit-33.c
index a45f18d..732d33e 100644
--- a/gcc/testsuite/gcc.dg/uninit-33.c
+++ b/gcc/testsuite/gcc.dg/uninit-33.c
@@ -27,7 +27,7 @@ void nowarn_scalar_plus_fpri (void)
int i;
/* This gets a -Wstringop-overflow for reading past the end but not
-Wuninitialized because there's nothing to initialize there. */
- fpri (&i + 1); // { dg-warning "\\\[-Wstringop-overflow" }
+ fpri (&i + 1); // { dg-warning "\\\[-Wstringop-overread" }
}
void nowarn_array_assign_fpcri (void)
diff --git a/gcc/testsuite/gcc.dg/uninit-36.c b/gcc/testsuite/gcc.dg/uninit-36.c
index 9524e7a..f6307ce 100644
--- a/gcc/testsuite/gcc.dg/uninit-36.c
+++ b/gcc/testsuite/gcc.dg/uninit-36.c
@@ -3,7 +3,8 @@
Verify that passing pointers to uninitialized objects to const
arguments to built-ins is diagnosed where expected.
{ dg-do compile }
- { dg-options "-O -Wall" } */
+ { dg-options "-O -Wall" }
+ { dg-require-effective-target alloca } */
typedef __SIZE_TYPE__ size_t;
diff --git a/gcc/testsuite/gcc.dg/uninit-37.c b/gcc/testsuite/gcc.dg/uninit-37.c
new file mode 100644
index 0000000..b8c49ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/uninit-37.c
@@ -0,0 +1,154 @@
+/* PR middle-end/10138 - warn for uninitialized arrays passed as const arguments
+ Verify that -Wuninitialized and -Wmaybe-uninitialized trigger (or don't)
+ when passing uninitialized variables by reference to functions declared
+ with or without attribute access and with (or without) const qualified
+ arguments of array, VLA, or pointer types.
+ { dg-do compile }
+ { dg-options "-O2 -Wall -ftrack-macro-expansion=0" } */
+
+#define NONE /* none */
+#define RO(...) __attribute__ ((access (read_only, __VA_ARGS__)))
+#define RW(...) __attribute__ ((access (read_write, __VA_ARGS__)))
+#define WO(...) __attribute__ ((access (write_only, __VA_ARGS__)))
+#define X(...) __attribute__ ((access (none, __VA_ARGS__)))
+
+#define CONCAT(x, y) x ## y
+#define CAT(x, y) CONCAT (x, y)
+#define UNIQ(pfx) CAT (pfx, __LINE__)
+
+extern void sink (void*);
+
+
+#define T1(attr, name, type) \
+ void UNIQ (CAT (test_, name))(void) { \
+ extern attr void UNIQ (name)(type); \
+ int x; \
+ UNIQ (name)(&x); \
+ sink (&x); \
+ }
+
+#define T2(attr, name, types) \
+ void UNIQ (CAT (test_, name))(void) { \
+ extern attr void UNIQ (name)(types); \
+ int x; \
+ UNIQ (name)(1, &x); \
+ sink (&x); \
+ }
+
+
+typedef int IA_[];
+typedef const int CIA_[];
+
+T1 (NONE, fia_, IA_);
+T1 (NONE, fcia_, CIA_); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froia_, IA_); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwia_, IA_); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoia_, IA_);
+T1 (X (1), fxia_, IA_);
+
+
+typedef int IA1[1];
+typedef const int CIA1[1];
+
+T1 (NONE, fia1, IA1);
+T1 (NONE, fcia1, CIA1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froia1, IA1); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwia1, IA1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoia1, IA1);
+T1 (X (1), fxia1, IA1);
+
+
+#define IARS1 int[restrict static 1]
+#define CIARS1 const int[restrict static 1]
+
+T1 (NONE, fiars1, IARS1);
+T1 (NONE, fciars1, CIARS1);// { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froiars1, IARS1); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwiars1, IARS1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoiars1, IARS1);
+T1 (X (1), fxiars1, IARS1);
+
+
+#define IAS1 int[static 1]
+#define CIAS1 const int[static 1]
+
+T1 (NONE, fias1, IAS1);
+T1 (NONE, fcias1, CIAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froias1, IAS1); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwias1, IAS1); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoias1, IAS1);
+T1 (X (1), fxias1, IAS1);
+
+
+#define IAX int[*]
+#define CIAX const int[*]
+
+T1 (NONE, fiax, IAX);
+T1 (NONE, fciax, CIAX); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froiax, IAX); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwiax, IAX); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoiax, IAX);
+T1 (X (1), fxiax, IAX);
+
+
+#define IAN int n, int[n]
+#define CIAN int n, const int[n]
+
+T2 (NONE, fian, IAN);
+T2 (NONE, fcian, CIAN); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T2 (RO (2, 1), froian, IAN); // { dg-warning "\\\[-Wuninitialized" }
+T2 (RW (2, 1), frwian, IAN); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T2 (WO (2, 1), fwoian, IAN);
+T2 (X (2, 1), fxian, IAN);
+
+
+typedef int* IP;
+typedef const int* CIP;
+
+T1 (NONE, fip, IP);
+T1 (NONE, fcip, CIP); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (RO (1), froip, IP); // { dg-warning "\\\[-Wuninitialized" }
+T1 (RW (1), frwip, IP); // { dg-warning "\\\[-Wmaybe-uninitialized" }
+T1 (WO (1), fwoip, IP);
+T1 (X (1), fxip, IP);
+
+
+/* Verify that the notes printed after the warning mention attribute
+ access only when the attribute is explicitly used in the declaration
+ and not otherwise. */
+
+void test_note_cst_restrict (void)
+{
+ extern void
+ fccar (const char[restrict]); // { dg-message "by argument 1 of type 'const char\\\[restrict]' to 'fccar'" "note" }
+
+ char a[1]; // { dg-message "'a' declared here" "note" }
+ fccar (a); // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_vla (int n)
+{
+ extern void
+ fccvla (const char[n]); // { dg-message "by argument 1 of type 'const char\\\[n]' to 'fccvla'" "note" }
+
+ char a[2]; // { dg-message "'a' declared here" "note" }
+ fccvla (a); // { dg-warning "'a' may be used uninitialized" }
+}
+
+void test_note_ro (void)
+{
+ extern RO (1) void
+ frocar (char[restrict]); // { dg-message "in a call to 'frocar' declared with attribute 'access \\\(read_only, 1\\\)'" "note" }
+
+ char a[3]; // { dg-message "'a' declared here" "note" }
+ frocar (a); // { dg-warning "'a' is used uninitialized" }
+}
+
+void test_note_rw (void)
+{
+ extern RW (1) void
+ frwcar (char[restrict]); // { dg-message "in a call to 'frwcar' declared with attribute 'access \\\(read_write, 1\\\)'" "note" }
+
+ char a[4]; // { dg-message "'a' declared here" "note" }
+ frwcar (a); // { dg-warning "'a' may be used uninitialized" }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
index e6818cb..793c41f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
@@ -55,4 +55,4 @@ int main (void)
}
/* { dg-final { scan-tree-dump-not "can't force alignment" "slp1" } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
index ad6f878..697dc4e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
@@ -50,5 +50,5 @@ int main (void)
}
/* { dg-final { scan-tree-dump "unsupported unaligned access" "slp2" { target { ! vect_element_align } } } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_element_align } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
index cb8bddd..ff43253 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
@@ -49,5 +49,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect64 } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
index 302e20f..fdff76e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
@@ -46,5 +46,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
index e7d4e6c..62ee757 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
@@ -48,5 +48,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
index a749041..efe7d6a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
@@ -51,5 +51,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
index 42abd64..e68a9b6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
@@ -65,5 +65,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
index c20e0ff..f8bfb4b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
@@ -57,5 +57,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
index 9476653..db3f0ba 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
@@ -46,5 +46,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
index db446be..7e3ccb4 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -52,5 +52,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
index cee9db5..fcf1cd3 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
@@ -53,5 +53,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
index f6dfaa7..134858c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
@@ -63,6 +63,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
index 5464d09..d4c98d6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
@@ -63,6 +63,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
index b531651..92cc2a5 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
@@ -63,5 +63,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
/* { dg-final { scan-tree-dump "vectorizing SLP node starting from: _\[0-9\]+ = _\[0-9\]+ \\\* a0" "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
index e57ca41..ed4a595 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
@@ -51,5 +51,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
index d5b6bfb..ca049c8 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
@@ -55,5 +55,5 @@ int main (void)
/* Exclude POWER8 (only POWER cpu for which vect_element_align is true)
because loops have vectorized before SLP gets a shot. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" { target { vect_element_align && { ! powerpc*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { target { vect_element_align && { ! powerpc*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
index ec31329..7a9cf95 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
@@ -56,5 +56,5 @@ int main (void)
/* Exclude POWER8 (only POWER cpu for which vect_element_align is true)
because loops have vectorized before SLP gets a shot. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" { target { vect_element_align && { ! powerpc*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { target { vect_element_align && { ! powerpc*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
index 91b6cac..df52967 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
@@ -54,5 +54,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" { target { vect64 && vect_hw_misalign } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { target { vect64 && vect_hw_misalign } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
index 8ef8bb0..bc27f2f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
@@ -44,5 +44,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
index a4c01b9..8749a1f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
@@ -66,5 +66,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
index 747896b..b531350 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
@@ -56,5 +56,5 @@ int main (void)
/* Exclude POWER8 (only POWER cpu for which vect_element_align is true)
because loops have vectorized before SLP gets a shot. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" { target { { vect_int_mult && vect_element_align } && { ! powerpc*-*-* } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { target { { vect_int_mult && vect_element_align } && { ! powerpc*-*-* } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
index 4f47738..2636670 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
@@ -42,5 +42,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
index 224f9de..c3d7ae1 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
@@ -50,4 +50,4 @@ int main()
return a[21];
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
index 8e4e2d4..6a131e7 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
@@ -9,4 +9,4 @@ void f(){
a[1]=1+2*a[1]*a[1];
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-32.c b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
index 41bbf35..020b636 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-32.c
@@ -7,16 +7,21 @@ int foo (int *p, int a, int b)
{
int x[4];
int tem0, tem1, tem2, tem3;
+ int sum = 0;
tem0 = p[0] + 1 + a;
+ sum += tem0;
x[0] = tem0;
tem1 = p[1] + 2 + b;
+ sum += tem1;
x[1] = tem1;
tem2 = p[2] + 3 + b;
+ sum += tem2;
x[2] = tem2;
tem3 = p[3] + 4 + a;
+ sum += tem3;
x[3] = tem3;
bar (x);
- return tem0 + tem1 + tem2 + tem3;
+ return sum;
}
/* { dg-final { scan-tree-dump "vectorization is not profitable" "slp2" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-34.c b/gcc/testsuite/gcc.dg/vect/bb-slp-34.c
index c51c770..a625c45 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-34.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-34.c
@@ -32,4 +32,4 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_perm } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target vect_perm } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-35.c b/gcc/testsuite/gcc.dg/vect/bb-slp-35.c
index 5803f8e..81b228b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-35.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-35.c
@@ -9,4 +9,4 @@ void foo (int * __restrict__ p, short * __restrict__ q)
p[3] = q[3] + 1;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target vect_hw_misalign } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-36.c b/gcc/testsuite/gcc.dg/vect/bb-slp-36.c
index f424d12..fbcedd0 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-36.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-36.c
@@ -32,4 +32,4 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_perm } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target vect_perm } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-38.c b/gcc/testsuite/gcc.dg/vect/bb-slp-38.c
index 59aec54..a7bc032 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-38.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-38.c
@@ -40,5 +40,4 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_perm } } } */
-/* { dg-final { scan-tree-dump-times "basic block part vectorized" 2 "slp2" { target vect_perm } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target vect_perm } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
index 293b0e3..9e36963 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
@@ -38,4 +38,4 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-45.c b/gcc/testsuite/gcc.dg/vect/bb-slp-45.c
new file mode 100644
index 0000000..d24ef2a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-45.c
@@ -0,0 +1,36 @@
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
+
+extern void abort (void);
+
+double a[8], b[8];
+int x;
+
+void __attribute__((noinline,noclone))
+bar (void)
+{
+ x = 1;
+}
+
+void __attribute__((noinline,noclone))
+foo(int i)
+{
+ double tem1 = a[2*i];
+ double tem2 = 2*a[2*i+1];
+ bar ();
+ b[2*i] = 2*tem1;
+ b[2*i+1] = tem2;
+}
+
+int main()
+{
+ int i;
+ check_vect ();
+ for (i = 0; i < 8; ++i)
+ b[i] = i;
+ foo (2);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-46.c b/gcc/testsuite/gcc.dg/vect/bb-slp-46.c
new file mode 100644
index 0000000..8daa5c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-46.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-additional-options "-fdump-tree-optimized" } */
+
+int a[4], b[4];
+int foo ()
+{
+ int tem0 = a[0] + b[0];
+ int temx = tem0 * 17; /* this fails without a real need */
+ int tem1 = a[1] + b[1];
+ int tem2 = a[2] + b[2];
+ int tem3 = a[3] + b[3];
+ int temy = tem3 * 13;
+ a[0] = tem0;
+ a[1] = tem1;
+ a[2] = tem2;
+ a[3] = tem3;
+ return temx + temy;
+}
+
+/* We should extract the live lane from the vectorized add rather than
+ keeping the original scalar add.
+ ??? Because of a too conservative check we fail for temx here. */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
+/* { dg-final { scan-tree-dump "extracting lane for live stmt" "slp2" } } */
+/* { dg-final { scan-tree-dump-times "extracting lane for live stmt" 2 "slp2" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times " \\+ " 3 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " \\+ " 2 "optimized" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-47.c b/gcc/testsuite/gcc.dg/vect/bb-slp-47.c
new file mode 100644
index 0000000..9583b09
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-47.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+int bar();
+int foo (int *a, int b, int c)
+{
+ int tem0 = bar ();
+ int tem1 = tem0 + b;
+ int tem3 = tem1 + c;
+ a[0] = tem3;
+ a[1] = tem3 + 1;
+ a[2] = tem3 + 2;
+ a[3] = tem3 + 3;
+ return tem1;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-48.c b/gcc/testsuite/gcc.dg/vect/bb-slp-48.c
new file mode 100644
index 0000000..dfae617
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-48.c
@@ -0,0 +1,55 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fgimple -fdump-tree-optimized" } */
+/* { dg-require-effective-target vect_double } */
+
+double a[2];
+
+void __GIMPLE (ssa,startwith ("fix_loops"))
+foo (double x)
+{
+ double tem2;
+ double tem1;
+ double _1;
+ double _2;
+ double _3;
+ double _4;
+
+ __BB(2):
+ _1 = a[0];
+ _2 = x_6(D) * 3.0e+0;
+ tem1_7 = _1 + _2;
+ _3 = x_6(D) + 1.0e+0;
+ _4 = a[1];
+ tem2_8 = _4 + _3;
+ a[0] = tem1_7;
+ a[1] = tem2_8;
+ return;
+}
+
+void __GIMPLE (ssa,startwith ("fix_loops"))
+bar (double x)
+{
+ double tem2;
+ double tem1;
+ double _1;
+ double _2;
+ double _3;
+ double _4;
+
+ __BB(2):
+ _1 = a[0];
+ _2 = x_6(D) * 3.0e+0;
+ tem1_7 = _1 + _2;
+ _3 = x_6(D) + 1.0e+0;
+ _4 = a[1];
+ /* Once with operands swapped. */
+ tem2_8 = _3 + _4;
+ a[0] = tem1_7;
+ a[1] = tem2_8;
+ return;
+}
+
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
+/* We want to vectorize as { a[0], a[1] } + { x*3, x+1 } and thus
+ elide one add in each function. */
+/* { dg-final { scan-tree-dump-times " \\+ " 4 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-49.c b/gcc/testsuite/gcc.dg/vect/bb-slp-49.c
new file mode 100644
index 0000000..e7101fc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-49.c
@@ -0,0 +1,28 @@
+/* This checks that vectorized constructors have the correct ordering. */
+/* { dg-require-effective-target vect_int } */
+
+typedef int V __attribute__((__vector_size__(16)));
+
+__attribute__((__noipa__)) void
+foo (unsigned int x, V *y)
+{
+ unsigned int a[4] = { x + 0, x + 2, x + 4, x + 6 };
+ for (unsigned int i = 0; i < 3; ++i)
+ if (a[i] == 1234)
+ a[i]--;
+ *y = (V) { a[3], a[2], a[1], a[0] };
+}
+
+int
+main ()
+{
+ V b;
+ foo (0, &b);
+ if (b[0] != 6 || b[1] != 4 || b[2] != 2 || b[3] != 0)
+ __builtin_abort ();
+ return 0;
+}
+
+/* See that we vectorize an SLP instance. */
+/* { dg-final { scan-tree-dump "Analyzing vectorizable constructor" "slp1" } } */
+/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
index 192b7dc..bb78e1b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
@@ -47,5 +47,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-50.c b/gcc/testsuite/gcc.dg/vect/bb-slp-50.c
new file mode 100644
index 0000000..80216be
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-50.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+
+double a[2];
+double b[2];
+double c[2];
+double d[2];
+double e[2];
+void foo(double x)
+{
+ double tembc0 = b[1] + c[1];
+ double tembc1 = b[0] + c[0];
+ double temde0 = d[0] + e[1];
+ double temde1 = d[1] + e[0];
+ a[0] = tembc0 + temde0;
+ a[1] = tembc1 + temde1;
+}
+
+/* We should common the permutation on the tembc{0,1} operands. */
+/* { dg-final { scan-tree-dump-times "add new stmt: \[^\\n\\r\]* = VEC_PERM_EXPR" 2 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-51.c b/gcc/testsuite/gcc.dg/vect/bb-slp-51.c
new file mode 100644
index 0000000..1481018
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-51.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_double } */
+
+double a[2];
+double b[2];
+double c[2];
+double e[2];
+void foo(double x)
+{
+ double tembc0 = b[1] + c[1];
+ double tembc1 = b[0] + c[0];
+ double temde0 = 5 + e[1];
+ double temde1 = 11 + e[0];
+ a[0] = tembc0 + temde0;
+ a[1] = tembc1 + temde1;
+}
+
+/* We should common the permutations on the tembc{0,1} and temde{0,1}
+ operands. */
+/* { dg-final { scan-tree-dump-times "add new stmt: \[^\\r\\n\]* VEC_PERM_EXPR" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
index 98fe5ea..fa3e76d 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
@@ -45,5 +45,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
index b8bef8c..ebe8189 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
@@ -22,6 +22,7 @@ main1 (unsigned int x, unsigned int y)
a2 = *pin++ + 2;
a3 = *pin++ * 31;
+ /* But we can still vectorize the multiplication or the store. */
*pout++ = a0 * x;
*pout++ = a1 * y;
*pout++ = a2 * x;
@@ -46,5 +47,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
index 750d713..b653469 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
@@ -48,5 +48,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_hw_misalign } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
index cf355ef..381593b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
@@ -47,5 +47,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 0 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
index a5b643b..03a47fd 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
@@ -49,5 +49,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_hw_misalign } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
index d022d5f..b4cc101 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
@@ -46,5 +46,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
index 65d83a4..87ffc9b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-div-1.c
@@ -16,4 +16,4 @@ f (void)
x[7] /= 9;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-div-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-div-2.c
index 715c22a..dd17e8c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-div-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-div-2.c
@@ -11,4 +11,4 @@ f (void)
x[3] += y[3] / z[3] * 2;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target vect_int } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-1.c
index 0082b83..5a9fe42 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-1.c
@@ -64,4 +64,4 @@ main (void)
/* { dg-final { scan-tree-dump "demoting int to signed short" "slp2" { target { ! vect_widen_shift } } } } */
/* { dg-final { scan-tree-dump "demoting int to unsigned short" "slp2" { target { ! vect_widen_shift } } } } */
/* { dg-final { scan-tree-dump {\.AVG_FLOOR} "slp2" { target vect_avg_qi } } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp2" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { target vect_hw_misalign } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-2.c
index 042b7e9..15a94e6 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-over-widen-2.c
@@ -63,4 +63,4 @@ main (void)
/* { dg-final { scan-tree-dump "demoting int to signed short" "slp2" { target { ! vect_widen_shift } } } } */
/* { dg-final { scan-tree-dump "demoting int to unsigned short" "slp2" { target { ! vect_widen_shift } } } } */
/* { dg-final { scan-tree-dump {\.AVG_FLOOR} "slp2" { target vect_avg_qi } } } */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp2" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { target vect_hw_misalign } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
index d32cb75..f6b99ea 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
@@ -49,4 +49,4 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp1" { target { vect_element_align && vect_pack_trunc } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp1" { target { vect_element_align && vect_pack_trunc } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-phis-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-phis-1.c
new file mode 100644
index 0000000..014c13b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-phis-1.c
@@ -0,0 +1,20 @@
+/* From gcc.c-torture/execute/loop-13.c */
+/* { dg-do compile } */
+/* { dg-additional-options "-march=cascadelake" { target x86_64-*-* i?86-*-* } } */
+#define TYPE long
+
+void
+scale (TYPE *alpha, TYPE *x, int n)
+{
+ int i, ix;
+
+ if (*alpha != 1)
+ for (i = 0, ix = 0; i < n; i++, ix += 2)
+ {
+ TYPE tmpr, tmpi;
+ tmpr = *alpha * x[ix];
+ tmpi = *alpha * x[ix + 1];
+ x[ix] = tmpr;
+ x[ix + 1] = tmpi;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pow-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pow-1.c
index cfe654e..fc76700 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pow-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pow-1.c
@@ -29,4 +29,4 @@ main (void)
-mno-allow-movmisalign prevents vectorization. On POWER8 and later,
when vect_hw_misalign is true, vectorization occurs. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target {{ ! powerpc*-*-* } || { powerpc*-*-* && vect_hw_misalign }} } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target {{ ! powerpc*-*-* } || { powerpc*-*-* && vect_hw_misalign }} } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr58135.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr58135.c
index ca25000..d3ac0de 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr58135.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr58135.c
@@ -7,4 +7,4 @@ void foo ()
a[0] = a[1] = a[2] = a[3] = a[4]= 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
index 0e4f1a7..ea37e4e 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr65935.c
@@ -59,4 +59,7 @@ int main()
/* We should also be able to use 2-lane SLP to initialize the real and
imaginary components in the first loop of main. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 10 "slp1" } } */
+/* We should see the s->phase[dir] operand and only that operand built
+ from scalars. See PR97334. */
+/* { dg-final { scan-tree-dump-times "Building vector operands from scalars" 1 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
index fe52d18..b348526 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr69907.c
@@ -1,5 +1,7 @@
/* { dg-do compile } */
-/* { dg-additional-options "-O3" } */
+/* Disable for vectorization using partial vectors since it would have only
+ one iteration left, consequently BB vectorization won't happen. */
+/* { dg-additional-options "-O3 --param=vect-partial-vector-usage=0" } */
/* { dg-require-effective-target vect_unpack } */
#include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr78205.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr78205.c
index f5dc534..27cba9b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr78205.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr78205.c
@@ -22,6 +22,6 @@ void foo ()
but we do want to vectorize the other two store groups. But we may
end up using scalar loads to vectorize the last group. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 3 "slp2" } } */
/* { 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 " = c\\\[4\\\];" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-1.c
index f024dc7..dcba9a0 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-1.c
@@ -89,4 +89,4 @@ f6 (int n)
}
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 6 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 6 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c
index 11e8f0f..6b213d4 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-2.c
@@ -61,4 +61,4 @@ f4 (double *p, double *q)
}
}
-/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp1" } } */
+/* { dg-final { scan-tree-dump-not "optimized: basic block" "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-3.c
index 1cca1d0..793f185 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-3.c
@@ -59,4 +59,4 @@ f4 (double *p, double *q, unsigned int start, unsigned int n)
}
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 4 "slp1" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 4 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c
index 1aa3c8d..599f718 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr81635-4.c
@@ -44,4 +44,4 @@ f3 (double *p, double *q, unsigned int start, unsigned int n)
}
}
-/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp1" } } */
+/* { dg-final { scan-tree-dump-not "optimized: basic block" "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr90006.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr90006.c
index 104d3fb..7d82e94 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr90006.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr90006.c
@@ -28,4 +28,4 @@ int e()
return 0;
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" { target { { x86_64-*-* i?86-*-* } && ilp32 } } } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" { target { { x86_64-*-* i?86-*-* } && ilp32 } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-2.c
index 49e75d8..5a831ae 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839-2.c
@@ -16,5 +16,5 @@ v2df g(v2df a, v2df b)
/* Verify we manage to vectorize this with using the original vectors
and do not end up with any vector CTORs. */
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
/* { dg-final { scan-tree-dump-not "vect_cst" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c
index 0bfba01..931fd46 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95839.c
@@ -10,4 +10,4 @@ v4f32 f(v4f32 a, v4f32 b)
return (v4f32){a[0] + b[0], a[1] + b[1], a[2] + b[2], a[3] + b[3]};
}
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95866.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95866.c
index 5de4671..edcaf17 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pr95866.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pr95866.c
@@ -14,4 +14,4 @@ void foo()
/* The scalar shift argument should be extracted from the available vector. */
/* { dg-final { scan-tree-dump "BIT_FIELD_REF" "slp2" } } */
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c
index 39c23c3..40a02ed 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-1.c
@@ -41,4 +41,4 @@ 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 "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c
index 36938d0..968cdf1 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-subgroups-2.c
@@ -39,4 +39,4 @@ 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 "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
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 6ae9a89..fe36f90 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,4 @@ 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 "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c
index 915a962..df01918 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/ppc/costmodel-bb-slp-9a.c
@@ -38,4 +38,4 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { xfail { vect_no_align && { ! vect_hw_misalign } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr69297.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr69297.c
index e65a30c..ef74785 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr69297.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-pr69297.c
@@ -74,10 +74,28 @@ foo (int* diff)
d[13] = m[12] - m[13];
d[14] = m[14] + m[15];
d[15] = m[15] - m[14];
+ /* The following obviously profitable part should not make
+ the former unprofitable one profitable. */
+ diff[16 + 16] = diff[16];
+ diff[17 + 16] = diff[17];
+ diff[18 + 16] = diff[18];
+ diff[19 + 16] = diff[19];
+ diff[20 + 16] = diff[20];
+ diff[21 + 16] = diff[21];
+ diff[22 + 16] = diff[22];
+ diff[23 + 16] = diff[23];
+ diff[24 + 16] = diff[24];
+ diff[25 + 16] = diff[25];
+ diff[26 + 16] = diff[26];
+ diff[27 + 16] = diff[27];
+ diff[28 + 16] = diff[28];
+ diff[29 + 16] = diff[29];
+ diff[30 + 16] = diff[30];
+ diff[31 + 16] = diff[31];
for (k=0; k<16; k++)
satd += abs(d[k]);
return satd;
}
/* { dg-final { scan-tree-dump "vectorization is not profitable" "slp1" } } */
-/* { dg-final { scan-tree-dump-not "basic block vectorized" "slp1" } } */
+/* { dg-final { scan-tree-dump-times "Vectorizing SLP tree" 1 "slp1" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c
index 5121a88..819c4f6 100644
--- a/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c
+++ b/gcc/testsuite/gcc.dg/vect/costmodel/x86_64/costmodel-vect-slp.c
@@ -25,4 +25,4 @@ foo ()
}
/* { dg-final { scan-tree-dump-not "vectorization is not profitable" "slp2" } } */
-/* { dg-final { scan-tree-dump "basic block vectorized" "slp2" } } */
+/* { dg-final { scan-tree-dump "optimized: basic block" "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
index 1c75c87..cfea872 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
@@ -45,4 +45,4 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
index 49a7c05..6d67d12 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
@@ -63,4 +63,4 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp2" { target vect_call_lrint } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 2 "slp2" { target vect_call_lrint } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
index c7f9cd3..2202362 100644
--- a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
@@ -47,5 +47,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" { target vect_int_mult } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c b/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c
index 8fe67f4..e837418 100644
--- a/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-sra-bb-slp-pr50730.c
@@ -13,4 +13,4 @@ A sum(A a,A b)
return a;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
+/* { dg-final { scan-tree-dump-times "optimized: basic block" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr37027.c b/gcc/testsuite/gcc.dg/vect/pr37027.c
index ef6760e..69f5826 100644
--- a/gcc/testsuite/gcc.dg/vect/pr37027.c
+++ b/gcc/testsuite/gcc.dg/vect/pr37027.c
@@ -33,4 +33,4 @@ foo (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 } } } */
-
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr65947-3.c b/gcc/testsuite/gcc.dg/vect/pr65947-3.c
index 6b4077e..f1bfad6 100644
--- a/gcc/testsuite/gcc.dg/vect/pr65947-3.c
+++ b/gcc/testsuite/gcc.dg/vect/pr65947-3.c
@@ -51,6 +51,10 @@ main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" } } */
+/* Since the fix for PR97307 which sinks the load of a[i], preventing
+ if-conversion to happen, targets that cannot do masked loads only
+ vectorize the inline copy. */
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 2 "vect" { target vect_masked_load } } } */
+/* { dg-final { scan-tree-dump-times "LOOP VECTORIZED" 1 "vect" { target { ! vect_masked_load } } } } */
/* { dg-final { scan-tree-dump-times "optimizing condition reduction with FOLD_EXTRACT_LAST" 2 "vect" { target vect_fold_extract_last } } } */
/* { dg-final { scan-tree-dump-not "condition expression based on integer induction." "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr67790.c b/gcc/testsuite/gcc.dg/vect/pr67790.c
index 5e2d506..32eacd9 100644
--- a/gcc/testsuite/gcc.dg/vect/pr67790.c
+++ b/gcc/testsuite/gcc.dg/vect/pr67790.c
@@ -38,3 +38,4 @@ int main()
}
/* { dg-final { scan-tree-dump "vectorizing stmts using SLP" "vect" } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr92324-4.c b/gcc/testsuite/gcc.dg/vect/pr92324-4.c
index 8347985..57e117c 100644
--- a/gcc/testsuite/gcc.dg/vect/pr92324-4.c
+++ b/gcc/testsuite/gcc.dg/vect/pr92324-4.c
@@ -28,3 +28,5 @@ int main ()
__builtin_abort ();
return 0;
}
+
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr92558.c b/gcc/testsuite/gcc.dg/vect/pr92558.c
index 1d24fa0..11f4132 100644
--- a/gcc/testsuite/gcc.dg/vect/pr92558.c
+++ b/gcc/testsuite/gcc.dg/vect/pr92558.c
@@ -21,3 +21,5 @@ int main()
__builtin_abort ();
return 0;
}
+
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr95495.c b/gcc/testsuite/gcc.dg/vect/pr95495.c
index a961aef..683f0f2 100644
--- a/gcc/testsuite/gcc.dg/vect/pr95495.c
+++ b/gcc/testsuite/gcc.dg/vect/pr95495.c
@@ -14,3 +14,5 @@ h()
d += e[f].b >> 1 | e[f].b & 1;
}
}
+
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr96698.c b/gcc/testsuite/gcc.dg/vect/pr96698.c
new file mode 100644
index 0000000..1d141c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr96698.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+void test(int a, int* i)
+{
+ for (; a < 5; ++a)
+ {
+ int b = 0;
+ int c = 0;
+ for (; b != -11; b--)
+ for (int d = 0; d ==0; d++)
+ {
+ *i += c & a;
+ c = b;
+ }
+ }
+}
+
+/* We should be able to vectorize the inner cycle. */
+/* { dg-final { scan-tree-dump "OUTER LOOP VECTORIZED" "vect" { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr96783-1.c b/gcc/testsuite/gcc.dg/vect/pr96783-1.c
new file mode 100644
index 0000000..55d1364
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr96783-1.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+void __attribute__((noipa))
+foo (long *a, int off, int n)
+{
+ for (int i = 0; i < n; ++i)
+ {
+ long tem1 = a[0];
+ long tem2 = a[1];
+ long tem3 = a[2];
+ long tem4 = a[off + 1];
+ a[0] = tem4;
+ long tem5 = a[off + 2];
+ a[1] = tem5;
+ long tem6 = a[off + 3];
+ a[2] = tem6;
+ a[off + 1] = tem1;
+ a[off + 2] = tem2;
+ a[off + 3] = tem3;
+ a -= 3;
+ }
+}
+
+int main ()
+{
+ long a[3 * 9];
+ check_vect ();
+ for (int i = 0; i < 3 * 9; ++i)
+ a[i] = i;
+ foo (a + 3 * 5, 6-1, 5);
+ const long b[3 * 8] = { 0, 1, 2, 21, 22, 23, 18, 19, 20, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 };
+ for (int i = 0; i < 3 * 8; ++i)
+ if (a[i] != b[i])
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr96783-2.c b/gcc/testsuite/gcc.dg/vect/pr96783-2.c
new file mode 100644
index 0000000..33c3710
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr96783-2.c
@@ -0,0 +1,29 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+long a[1024];
+long b[1024];
+
+void __attribute__((noipa)) foo ()
+{
+ for (int i = 0; i < 256; ++i)
+ {
+ a[3*i] = b[1023 - 3*i - 2];
+ a[3*i + 1] = b[1023 - 3*i - 1];
+ a[3*i + 2] = b[1023 - 3*i];
+ }
+}
+
+int main()
+{
+ for (int i = 0; i < 1024; ++i)
+ b[i] = i;
+ foo ();
+ for (int i = 0; i < 256; ++i)
+ if (a[3*i] != 1023 - 3*i - 2
+ || a[3*i+1] != 1023 - 3*i - 1
+ || a[3*i+2] != 1023 - 3*i)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr96854.c b/gcc/testsuite/gcc.dg/vect/pr96854.c
new file mode 100644
index 0000000..e3980d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr96854.c
@@ -0,0 +1,20 @@
+/* { dg-additional-options "-ffast-math" } */
+
+double _Complex __attribute__((noipa))
+foo (double _Complex acc, const double _Complex *x, const double _Complex* y, int N)
+{
+ for (int c = 0; c < N; ++c)
+ acc -= x[c] * y[c];
+ return acc;
+}
+
+int
+main()
+{
+ static const double _Complex y[] = { 1, 2, };
+ static const double _Complex x[] = { 1, 3, };
+ double _Complex ref = foo (0, x, y, 2);
+ if (__builtin_creal (ref) != -7.)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr96920.c b/gcc/testsuite/gcc.dg/vect/pr96920.c
new file mode 100644
index 0000000..af5da4a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr96920.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int a[1024];
+int b[2048];
+
+void foo (int x, int y)
+{
+ for (int i = 0; i < 1024; ++i)
+ {
+ int tem0 = b[2*i];
+ int tem1 = b[2*i+1];
+ for (int j = 0; j < 32; ++j)
+ {
+ int tem = tem0;
+ tem0 = tem1;
+ tem1 = tem;
+ a[i] += tem0;
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97081-2.c b/gcc/testsuite/gcc.dg/vect/pr97081-2.c
new file mode 100644
index 0000000..98ad3c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97081-2.c
@@ -0,0 +1,32 @@
+/* PR tree-optimization/97081 */
+
+#include "tree-vect.h"
+
+unsigned short s[1024];
+unsigned char c[1024];
+
+__attribute__((noipa)) void
+foo (int n)
+{
+ for (int i = 0; i < 1024; i++)
+ s[i] = (s[i] << n) | (s[i] >> (__SIZEOF_SHORT__ * __CHAR_BIT__ - n));
+ for (int i = 0; i < 1024; i++)
+ c[i] = (c[i] << n) | (c[i] >> (__CHAR_BIT__ - n));
+}
+
+int
+main ()
+{
+ check_vect ();
+ for (int i = 0; i < 1024; i++)
+ {
+ s[i] = i;
+ c[i] = i;
+ }
+ foo (3);
+ for (int i = 0; i < 1024; i++)
+ if (s[i] != (unsigned short) ((i << 3) | (i >> (__SIZEOF_SHORT__ * __CHAR_BIT__ - 3)))
+ || c[i] != (unsigned char) ((((unsigned char) i) << 3) | (((unsigned char) i) >> (__CHAR_BIT__ - 3))))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97081.c b/gcc/testsuite/gcc.dg/vect/pr97081.c
new file mode 100644
index 0000000..bc83c88
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97081.c
@@ -0,0 +1,26 @@
+#include "tree-vect.h"
+
+#define EXEC_ROR2(a, b, sz) (a >> b) | (a << (64 - b))
+
+#define TYPE __UINT64_TYPE__
+
+void __attribute__((noipa))
+exec_VRORudi_i(TYPE *__restrict__ pvd,
+ TYPE *__restrict__ const pva, unsigned char IMM)
+{
+ unsigned char I2 = IMM & 63;
+
+ for (unsigned i = 0; i < 4; i++)
+ pvd[i] = EXEC_ROR2(pva[i], I2, 8);
+}
+
+int main()
+{
+ check_vect ();
+
+ TYPE pvd[4], pva[4] = { 0x0102030405060708, 0x0102030405060708, 0x0102030405060708, 0x0102030405060708 };
+ exec_VRORudi_i (pvd, pva, 7);
+ if (pvd[0] != 0x10020406080a0c0e)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97085.c b/gcc/testsuite/gcc.dg/vect/pr97085.c
new file mode 100644
index 0000000..ffde9f1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97085.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-march=armv8.2-a+sve" { target aarch64-*-* } } */
+
+int a, b, c, d;
+short e, g;
+unsigned short f;
+void h() {
+ for (; d; d++) {
+ g = d;
+ e = b == 0 ? 1 : a % b;
+ c ^= (f = e) > (g == 5);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97139.c b/gcc/testsuite/gcc.dg/vect/pr97139.c
new file mode 100644
index 0000000..1b9f31c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97139.c
@@ -0,0 +1,27 @@
+/* { dg-require-effective-target vect_int } */
+
+#include "tree-vect.h"
+
+int pix[4];
+
+int __attribute__((noipa)) foo (void)
+{
+ pix[0] = pix[0] / 4;
+ pix[1] = pix[1] / 4;
+ pix[2] = pix[2] / 4;
+ pix[3] = pix[3] / 4;
+ return pix[0] + pix[1] + pix[2] + pix[3];
+}
+
+int main ()
+{
+ check_vect ();
+
+ pix[0] = 8;
+ pix[1] = 16;
+ pix[2] = 32;
+ pix[3] = 64;
+ if (foo () != 30)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97173.c b/gcc/testsuite/gcc.dg/vect/pr97173.c
new file mode 100644
index 0000000..fd4a889
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97173.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+
+typedef struct {
+ char *track;
+ char *clocks;
+ char *fm;
+ char *weak;
+} disk_t;
+
+disk_t disk_update_tlens_d;
+int disk_update_tlens_d_0;
+
+void disk_update_tlens() {
+ disk_update_tlens_d.track = disk_update_tlens_d.clocks =
+ disk_update_tlens_d.track + disk_update_tlens_d_0;
+ disk_update_tlens_d.fm = disk_update_tlens_d.clocks + disk_update_tlens_d_0;
+ disk_update_tlens_d.weak = disk_update_tlens_d.fm;
+ disk_update_tlens_d.track[2] = 5;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97236.c b/gcc/testsuite/gcc.dg/vect/pr97236.c
new file mode 100644
index 0000000..9d3dc20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97236.c
@@ -0,0 +1,43 @@
+typedef unsigned char __uint8_t;
+typedef __uint8_t uint8_t;
+typedef struct plane_t {
+ uint8_t *p_pixels;
+ int i_lines;
+ int i_pitch;
+} plane_t;
+
+typedef struct {
+ plane_t p[5];
+} picture_t;
+
+#define N 4
+
+void __attribute__((noipa))
+picture_Clone(picture_t *picture, picture_t *res)
+{
+ for (int i = 0; i < N; i++) {
+ res->p[i].p_pixels = picture->p[i].p_pixels;
+ res->p[i].i_lines = picture->p[i].i_lines;
+ res->p[i].i_pitch = picture->p[i].i_pitch;
+ }
+}
+
+int
+main()
+{
+ picture_t aaa, bbb;
+ uint8_t pixels[10] = {1, 1, 1, 1, 1, 1, 1, 1};
+
+ for (unsigned i = 0; i < N; i++)
+ aaa.p[i].p_pixels = pixels;
+
+ picture_Clone (&aaa, &bbb);
+
+ uint8_t c = 0;
+ for (unsigned i = 0; i < N; i++)
+ c += bbb.p[i].p_pixels[0];
+
+ if (c != N)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/pr97241.c b/gcc/testsuite/gcc.dg/vect/pr97241.c
new file mode 100644
index 0000000..d4be8f6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr97241.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 --param max-loop-header-insns=2" } */
+
+short int *ev;
+int l4;
+
+short int
+a7 (void)
+{
+ short int uo = ev[0], ie = uo;
+
+ for (int kp = 0; kp < l4; kp += 4)
+ {
+ uo += ev[kp + 1];
+ ie += ev[kp];
+ }
+
+ return uo + ie;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/slp-3.c b/gcc/testsuite/gcc.dg/vect/slp-3.c
index 5e40499..46ab584 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-3.c
@@ -141,8 +141,8 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_fully_masked } } } } */
-/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_fully_masked } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_fully_masked } } } }*/
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_fully_masked } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { target { ! vect_partial_vectors } } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 4 loops" 1 "vect" { target vect_partial_vectors } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 3 "vect" { target { ! vect_partial_vectors } } } }*/
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 4 "vect" { target vect_partial_vectors } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-46.c b/gcc/testsuite/gcc.dg/vect/slp-46.c
index 17dfa285..58a238a 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-46.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-46.c
@@ -1,4 +1,5 @@
/* { dg-require-effective-target vect_double } */
+/* { dg-additional-options "--param vect-epilogues-nomask=0" } */
#include "tree-vect.h"
diff --git a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
index 5200ed1..9621886 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-multitypes-11.c
@@ -49,5 +49,7 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target vect_unpack } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target vect_unpack xfail { vect_variable_length && vect_load_lanes } } } } */
+/* The epilogues are vectorized using partial vectors. */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_unpack && {! vect_partial_vectors_usage_1 } } xfail { vect_variable_length && vect_load_lanes } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "vect" { target { vect_unpack && vect_partial_vectors_usage_1 } xfail { vect_variable_length && vect_load_lanes } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
index ca7803e..4128cca 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-1.c
@@ -80,7 +80,9 @@ 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 } } } } } */
+/* { 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" 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 b86a3dc..b137821 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-5.c
@@ -104,7 +104,9 @@ 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 } } } } } */
+/* { 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" 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 97a0ebf..3848929 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-6.c
@@ -103,7 +103,9 @@ 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 } } } } } */
+/* { 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" 1 "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-7.c b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
index 346411f..498999a 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-7.c
@@ -96,7 +96,9 @@ 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 } } } } } */
+/* { 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" 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-8.c b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
index 17aa111..9e59832 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-8.c
@@ -60,7 +60,9 @@ int main (int argc, const char* argv[])
}
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_byte } } } } */
-/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_byte && { ! vect_load_lanes } } } } } */
+/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_byte && { { ! 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_byte && { { ! vect_load_lanes } && vect_partial_vectors_usage_1 } } } } } */
/* { 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_byte && 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-9.c b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
index c54420a..ab75f44 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-perm-9.c
@@ -61,7 +61,9 @@ int main (int argc, const char* argv[])
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { target { vect_perm_short || vect_load_lanes } } } } */
/* We don't try permutes with a group size of 3 for variable-length
vectors. */
-/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target { vect_perm_short && { ! vect_perm3_short } } xfail vect_variable_length } } } */
+/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 1 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && { ! vect_partial_vectors_usage_1 } } } xfail vect_variable_length } } } */
+/* Try to vectorize the epilogue using partial vectors. */
+/* { dg-final { scan-tree-dump-times "permutation requires at least three vectors" 2 "vect" { target { vect_perm_short && { { ! vect_perm3_short } && vect_partial_vectors_usage_1 } } xfail vect_variable_length } } } */
/* { dg-final { scan-tree-dump-not "permutation requires at least three vectors" "vect" { target vect_perm3_short } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 0 "vect" { target { { ! vect_perm3_short } || vect_load_lanes } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { target { vect_perm3_short && { ! vect_load_lanes } } } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c
index b353dd7..b9bddb8 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-1.c
@@ -44,4 +44,4 @@ 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 } } } */
-
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c
index 15dd599..aa09d01 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-2.c
@@ -41,4 +41,5 @@ 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 } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
index 7358275..4969fe8 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-3.c
@@ -60,3 +60,4 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vect_recog_dot_prod_pattern: detected" 1 "vect" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "vect" { target { vect_short_mult && { vect_widen_sum_hi_to_si && vect_unpack } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "vect" { xfail { vect_widen_sum_hi_to_si_pattern || { ! vect_unpack } } } } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
index d58e5b0..266b439 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-4.c
@@ -58,4 +58,5 @@ 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" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c
index f457c11..11f5a741 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-5.c
@@ -46,4 +46,4 @@ int main (void)
/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 2 "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 } } } */
-
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
index 43d1cee..05cc9ed 100644
--- a/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
+++ b/gcc/testsuite/gcc.dg/vect/slp-reduc-7.c
@@ -56,4 +56,4 @@ 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" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-cond-13.c b/gcc/testsuite/gcc.dg/vect/vect-cond-13.c
new file mode 100644
index 0000000..2dfb879
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-cond-13.c
@@ -0,0 +1,38 @@
+/* { dg-do run } */
+
+#include "tree-vect.h"
+
+int a[1024];
+int b[1024];
+
+int
+foo ()
+{
+ int tem;
+ for (int i = 0; i < 1024; ++i)
+ {
+ if (a[i] < 0)
+ tem = -a[i] - 1;
+ else
+ tem = a[i];
+ b[i] = tem + 10;
+ }
+ return tem;
+}
+
+int main()
+{
+ check_vect ();
+
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i - 333;
+ __asm__ volatile ("" ::: "memory");
+ }
+ int res = foo ();
+ if (res != 1023 - 333)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target vect_condition } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-live-6.c b/gcc/testsuite/gcc.dg/vect/vect-live-6.c
new file mode 100644
index 0000000..c986c97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-live-6.c
@@ -0,0 +1,31 @@
+#include "tree-vect.h"
+
+int a[1024];
+int b[1024];
+
+_Bool
+fn1 ()
+{
+ _Bool tem;
+ for (int i = 0; i < 1024; ++i)
+ {
+ tem = !a[i];
+ b[i] = tem;
+ }
+ return tem;
+}
+
+int main()
+{
+ check_vect ();
+ for (int i = 0; i < 1024; ++i)
+ {
+ a[i] = i & 5;
+ __asm__ volatile ("" ::: "memory");
+ }
+ if (fn1 () != !(1023 & 5) || b[2] != 1)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target vect_int } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-reduc-in-order-4.c b/gcc/testsuite/gcc.dg/vect/vect-reduc-in-order-4.c
index 1cc046e..7706a2d 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-reduc-in-order-4.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-reduc-in-order-4.c
@@ -43,3 +43,4 @@ main ()
/* { dg-final { scan-tree-dump {in-order unchained SLP reductions not supported} "vect" } } */
/* { dg-final { scan-tree-dump-not {vectorizing stmts using SLP} "vect" } } */
+/* { dg-final { scan-tree-dump-times "VECT_PERM_EXPR" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-17.c b/gcc/testsuite/gcc.dg/vect/vect-simd-17.c
new file mode 100644
index 0000000..951ba3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-17.c
@@ -0,0 +1,304 @@
+/* { dg-additional-options "-fopenmp-simd -fno-tree-vectorize" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump "vectorized 1\[1-2] loops" "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "tree-vect.h"
+
+int x, i, j;
+volatile int a, b, c, d, e, f, g, h;
+int k[11][101];
+
+__attribute__((noipa)) void
+doit (void)
+{
+ int niters, err = 0;
+ for (i = 1; i <= 10; i++)
+ for (j = 1; j <= 10 * i; j++)
+ {
+ k[i][j] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = 1; b = 11; c = 1; d = 0; e = 1; f = 10; g = 1; h = 1;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = 1; i <= 10; i++)
+ for (j = 1; j <= 10 * i; j++)
+ {
+ err |= (i < 1);
+ err |= (i > 10);
+ err |= (j < 1);
+ err |= (j > 10 * i);
+ err |= (k[i][j] != 1);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 11 || j != 101 || x != 10340 || niters != 550 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i < 1);
+ err |= (i > 10);
+ err |= (j < 1);
+ err |= (j > 10 * i);
+ err |= (k[i][j] != 2);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 11 || j != 101 || x != 10340 || niters != 550 || err)
+ abort ();
+ for (i = 1; i <= 10; i++)
+ for (j = 1; j <= 10 * i; j++)
+ if (k[i][j] == 3)
+ k[i][j] = 0;
+ else
+ abort ();
+ for (i = 0; i < 11; i++)
+ for (j = 0; j < 101; j++)
+ if (k[i][j] != 0)
+ abort ();
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10 * i; j++)
+ {
+ k[i][j] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = 0; b = 10; c = 1; d = 0; e = 0; f = 10; g = 0; h = 1;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10 * i; j++)
+ {
+ err |= (i < 0);
+ err |= (i >= 10);
+ err |= (j < 0);
+ err |= (j >= 10 * i);
+ err |= (k[i][j] != 1);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 10 || j != 90 || x != 9305 || niters != 450 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i < 0);
+ err |= (i >= 10);
+ err |= (j < 0);
+ err |= (j >= 10 * i);
+ err |= (k[i][j] != 2);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 10 || j != 90 || x != 9305 || niters != 450 || err)
+ abort ();
+ for (i = 0; i < 10; i++)
+ for (j = 0; j < 10 * i; j++)
+ if (k[i][j] == 3)
+ k[i][j] = 0;
+ else
+ abort ();
+ for (i = 0; i < 11; i++)
+ for (j = 0; j < 101; j++)
+ if (k[i][j] != 0)
+ abort ();
+ for (i = 4; i < 10; i++)
+ for (j = -9 + 2 * i; j < i; j++)
+ {
+ k[i][j + 1] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = 4; b = 10; c = 1; d = 2; e = -9; f = 1; g = 0; h = 1;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = 4; i < 10; i++)
+ for (j = -9 + 2 * i; j < i; j++)
+ {
+ err |= (i < 4);
+ err |= (i >= 10);
+ err |= (j < -9 + 2 * i);
+ err |= (j >= i);
+ err |= (k[i][j + 1] != 1);
+ k[i][j + 1]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (/*i != 10 || j != 9 || */x != 8199 || niters != 15 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i < 4);
+ err |= (i >= 10);
+ err |= (j < -9 + 2 * i);
+ err |= (j >= i);
+ err |= (k[i][j + 1] != 2);
+ k[i][j + 1]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (/*i != 10 || j != 9 || */x != 8199 || niters != 15 || err)
+ abort ();
+ for (i = 4; i < 10; i++)
+ for (j = -9 + 2 * i; j < i; j++)
+ if (k[i][j + 1] == 3)
+ k[i][j + 1] = 0;
+ else
+ abort ();
+ for (i = 0; i < 11; i++)
+ for (j = 0; j < 101; j++)
+ if (k[i][j] != 0)
+ abort ();
+ for (i = 1; i < 10; i += 2)
+ for (j = 1; j < i + 1; j++)
+ {
+ k[i][j] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = 1; b = 10; c = 2; d = 0; e = 1; f = 1; g = 1; h = 1;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = 1; i < 10; i += 2)
+ for (j = 1; j < i + 1; j++)
+ {
+ err |= (i < 1);
+ err |= (i >= 10);
+ err |= (j < 1);
+ err |= (j >= i + 1);
+ err |= (k[i][j] != 1);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 11 || j != 10 || x != 9225 || niters != 25 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i < 1);
+ err |= (i >= 10);
+ err |= (j < 1);
+ err |= (j >= i + 1);
+ err |= (k[i][j] != 2);
+ k[i][j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 11 || j != 10 || x != 9225 || niters != 25 || err)
+ abort ();
+ for (i = 1; i < 10; i += 2)
+ for (j = 1; j < i + 1; j++)
+ if (k[i][j] == 3)
+ k[i][j] = 0;
+ else
+ abort ();
+ for (i = 0; i < 11; i++)
+ for (j = 0; j < 101; j++)
+ if (k[i][j] != 0)
+ abort ();
+ for (j = -11; j >= -41; j -= 15)
+ {
+ k[0][-j] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = 4; b = 8; c = 12; d = -8; e = -9; f = -3; g = 6; h = 15;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = 4; i < 8; i += 12)
+ for (j = -8 * i - 9; j < i * -3 + 6; j += 15)
+ {
+ err |= (i != 4);
+ err |= (j < -41);
+ err |= (j > -11);
+ err |= (k[0][-j] != 1);
+ k[0][-j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 16 || j != 4 || x != 5109 || niters != 3 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i != 4);
+ err |= (j < -41);
+ err |= (j > -11);
+ err |= (k[0][-j] != 2);
+ k[0][-j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (i != 16 || j != 4 || x != 5109 || niters != 3 || err)
+ abort ();
+ for (j = -11; j >= -41; j -= 15)
+ if (k[0][-j] == 3)
+ k[0][-j] = 0;
+ else
+ abort ();
+ for (j = -11; j >= -41; j--)
+ if (k[0][-j] != 0)
+ abort ();
+ for (j = -34; j <= -7; j++)
+ {
+ k[0][-j] = 1;
+ asm volatile ("" : : : "memory");
+ }
+ a = -13; b = 7; c = 12; d = 3; e = 5; f = 0; g = -6; h = 1;
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = -13; i < 7; i += 12)
+ for (j = 3 * i + 5; j < -6; j++)
+ {
+ err |= (i != -13);
+ err |= (j < -34);
+ err |= (j > -7);
+ err |= (k[0][-j] != 1);
+ k[0][-j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (/*i != 11 || j != 2 || */x != -12295 || niters != 28 || err)
+ abort ();
+ niters = 0; i = -100; j = -100; x = -100;
+ #pragma omp simd collapse(2) lastprivate (i, j, x) reduction(+:niters) reduction(|:err)
+ for (i = a; i < b; i += c)
+ for (j = d * i + e; j < g + i * f; j += h)
+ {
+ err |= (i != -13);
+ err |= (j < -34);
+ err |= (j > -7);
+ err |= (k[0][-j] != 2);
+ k[0][-j]++;
+ x = i * 1024 + (j & 1023);
+ niters++;
+ }
+ if (/*i != 11 || j != 2 || */x != -12295 || niters != 28 || err)
+ abort ();
+ for (j = -34; j <= -7; j++)
+ if (k[0][-j] == 3)
+ k[0][-j] = 0;
+ else
+ abort ();
+}
+
+int
+main ()
+{
+ check_vect ();
+ doit ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-18.c b/gcc/testsuite/gcc.dg/vect/vect-simd-18.c
new file mode 100644
index 0000000..b25f5a5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-18.c
@@ -0,0 +1,40 @@
+/* { dg-additional-options "-fopenmp-simd -fno-tree-vectorize" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "tree-vect.h"
+
+__attribute__((noipa)) int
+foo (int s, int *p)
+{
+ int r = 0, l = 0, i;
+ #pragma omp simd reduction (+:r) linear(l)
+ for (i = 0; i < 10000; i += s)
+ {
+ p[l++] = i;
+ r += i * 3;
+ }
+ return r;
+}
+
+int p[10000 / 78];
+
+int
+main ()
+{
+ int i, r;
+ check_vect ();
+ r = foo (78, p);
+ for (i = 0; i < 10000 / 78; i++)
+ if (p[i] != 78 * i)
+ abort ();
+ if (r != (10000 / 78) * (10000 / 78 + 1) / 2 * 78 * 3)
+ abort ();
+ r = foo (87, p);
+ for (i = 0; i < 10000 / 87; i++)
+ if (p[i] != 87 * i)
+ abort ();
+ if (r != (10000 / 87) * (10000 / 87 + 1) / 2 * 87 * 3)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-19.c b/gcc/testsuite/gcc.dg/vect/vect-simd-19.c
new file mode 100644
index 0000000..a71dfa6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-19.c
@@ -0,0 +1,40 @@
+/* { dg-additional-options "-fopenmp-simd -fno-tree-vectorize" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "tree-vect.h"
+
+__attribute__((noipa)) int
+foo (int s, int m, int n, int *p)
+{
+ int r = 0, l = 0, i;
+ #pragma omp simd reduction (+:r) linear(l)
+ for (i = m; i < n; i += s)
+ {
+ p[l++] = i;
+ r += i * 3;
+ }
+ return r;
+}
+
+int p[10000 / 78];
+
+int
+main ()
+{
+ int i, r;
+ check_vect ();
+ r = foo (78, 0, 10000, p);
+ for (i = 0; i < 10000 / 78; i++)
+ if (p[i] != 78 * i)
+ abort ();
+ if (r != (10000 / 78) * (10000 / 78 + 1) / 2 * 78 * 3)
+ abort ();
+ r = foo (87, 0, 10000, p);
+ for (i = 0; i < 10000 / 87; i++)
+ if (p[i] != 87 * i)
+ abort ();
+ if (r != (10000 / 87) * (10000 / 87 + 1) / 2 * 87 * 3)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-simd-20.c b/gcc/testsuite/gcc.dg/vect/vect-simd-20.c
new file mode 100644
index 0000000..c85f05f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/vect-simd-20.c
@@ -0,0 +1,43 @@
+/* { dg-additional-options "-fopenmp-simd -fno-tree-vectorize" } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+/* { dg-final { scan-tree-dump "vectorized 1 loops" "vect" { target i?86-*-* x86_64-*-* } } } */
+
+#include "tree-vect.h"
+
+__attribute__((noipa)) int
+foo (int s, int m, int n, int *p)
+{
+ int r = 0, l = 0, i, j;
+ #pragma omp simd reduction (+:r) linear(l) collapse(2)
+ for (j = 0; j < 7; j++)
+ for (i = m; i < n; i += s)
+ {
+ p[l++] = i;
+ r += i * 3;
+ }
+ return r;
+}
+
+int p[10000 / 78 * 7];
+
+int
+main ()
+{
+ int i, j, r;
+ check_vect ();
+ r = foo (78, 0, 10000, p);
+ for (j = 0; j < 7; j++)
+ for (i = 0; i < 10000 / 78; i++)
+ if (p[j * (10000 / 78 + 1) + i] != 78 * i)
+ abort ();
+ if (r != (10000 / 78) * (10000 / 78 + 1) / 2 * 78 * 3 * 7)
+ abort ();
+ r = foo (87, 0, 10000, p);
+ for (j = 0; j < 7; j++)
+ for (i = 0; i < 10000 / 87; i++)
+ if (p[j * (10000 / 87 + 1) + i] != 87 * i)
+ abort ();
+ if (r != (10000 / 87) * (10000 / 87 + 1) / 2 * 87 * 3 * 7)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/vect/vect-version-2.c b/gcc/testsuite/gcc.dg/vect/vect-version-2.c
index 0ea39e3..7d3fb72 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-version-2.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-version-2.c
@@ -17,4 +17,8 @@ void foo (double *x, double *y, int m, int n, int o, int p)
}
}
-/* { dg-final { scan-tree-dump "reusing loop version created by if conversion" "vect" } } */
+/* Vectorization using partial vectors has zero versioning_threshold with
+ either usage 1 or usage 2, the cond_expr replies on the computation in
+ outer loop, so it doesn't need to reuse the loop version created by if
+ conversion. */
+/* { dg-final { scan-tree-dump "reusing loop version created by if conversion" "vect" {target {! vect_partial_vectors } } } } */
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c
index e91e8ce..76180a3 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul-2.c
@@ -62,5 +62,11 @@ void test (int n0)
int n = n0 < n1 ? n1 : n0;
- sink (strnlen (c + n, n + 1)); /* { dg-warning "specified bound \\\[5, \[0-9\]+] may exceed the size of at most 4 of unterminated array" } */
+ /* N is at least 4 and c[4] is out-of-bounds. This could trigger
+ either -Warray-bounds or -Wstringop-overread. -Warray-bounds
+ only diagnoses past-the-end accesses by modifying functions
+ (in gimple-ssa-warn-restrict.c) and even for those, either
+ -Wstringop-overflow or -Wstringop-overread would be more
+ appropriate. */
+ sink (strnlen (c + n, n + 1)); /* { dg-warning "specified bound \\\[5, \[0-9\]+] exceeds the size of at most 4 of unterminated array" } */
}
diff --git a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
index 09a527e..02f6f3d 100644
--- a/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
+++ b/gcc/testsuite/gcc.dg/warn-strnlen-no-nul.c
@@ -35,7 +35,7 @@ T (&a[1], asz - 1);
T (&a[v0], asz); /* { dg-warning "specified bound 5 may exceed the size of at most 5 of unterminated array" } */
T (&a[v0] + 1, asz); /* { dg-warning "specified bound 5 may exceed the size of at most 5 of unterminated array" } */
-T (a, asz + 1); /* { dg-warning "specified bound 6 exceeds the size 5 " } */
+T (a, asz + 1); /* { dg-warning "specified bound 6 exceeds the size 5 of unterminated array" } */
T (&a[0], asz + 1); /* { dg-warning "unterminated" } */
T (&a[0] + 1, asz - 1);
T (&a[0] + 1, asz + 1); /* { dg-warning "unterminated" } */
@@ -110,7 +110,7 @@ T (&b[3][1] + i1, bsz); /* { dg-warning "unterminated" } */
T (&b[3][1] + i1, bsz - i1); /* { dg-warning "unterminated" } */
T (&b[3][1] + i1, bsz - i2);
T (&b[3][v0], bsz);
-T (&b[3][1] + v0, bsz); /* { dg-warning "specified bound 5 may exceed the size of at most 4 of unterminated array" } */
+T (&b[3][1] + v0, bsz); /* { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" } */
T (&b[3][v0] + v1, bsz); /* { dg-warning "specified bound 5 may exceed the size of at most 4 of unterminated array" "pr?????" { xfail *-*-* } } */
T (&b[3][1], bsz + 1); /* { dg-warning "unterminated" } */
@@ -124,7 +124,7 @@ T (&b[i3][i1], bsz); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + 1, bsz); /* { dg-warning "unterminated" } */
T (&b[i3][i1] + i1, bsz); /* { dg-warning "specified bound 5 exceeds the size 3 of unterminated array" } */
T (&b[i3][v0], bsz);
-T (&b[i3][i1] + v0, bsz); /* { dg-warning "specified bound 5 may exceed the size of at most 4 of unterminated array" } */
+T (&b[i3][i1] + v0, bsz); /* { dg-warning "specified bound 5 exceeds the size of at most 4 of unterminated array" } */
T (&b[i3][v0] + v1, bsz);
T (&b[i3][i1], bsz + 1); /* { dg-warning "unterminated" } */
@@ -212,10 +212,10 @@ T (&s.a[i1] + v0, asz);
T (s.a, asz + 1);
T (&s.a[0], asz + 1);
T (&s.a[0] + 1, asz + 1);
-T (&s.a[0] + v0, asz + 1);
+T (&s.a[0] + v0, asz + 1); /* { dg-warning "specified bound 6 exceeds source size 5 " } */
T (&s.a[1], asz + 1);
T (&s.a[1] + 1, asz + 1);
-T (&s.a[1] + v0, asz + 1);
+T (&s.a[1] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" "pr95794" { xfail *-*-* } } */
T (&s.a[i0], asz + 1);
T (&s.a[i0] + i1, asz + 1);
@@ -266,10 +266,10 @@ const struct B ba[] = {
T (ba[0].a[0].a, asz + 1);
T (&ba[0].a[0].a[0], asz + 1);
T (&ba[0].a[0].a[0] + 1, asz + 1);
-T (&ba[0].a[0].a[0] + v0, asz + 1);
+T (&ba[0].a[0].a[0] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (&ba[0].a[0].a[1], asz + 1);
T (&ba[0].a[0].a[1] + 1, asz + 1);
-T (&ba[0].a[0].a[1] + v0, asz + 1);
+T (&ba[0].a[0].a[1] + v0, asz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (ba[0].a[0].b, bsz);
T (&ba[0].a[0].b[0], bsz);
@@ -302,10 +302,10 @@ T (&ba[0].a[1].a[1] + v0, asz + 1); /* { dg-warning "unterminated" } */
T (ba[0].a[1].b, bsz + 1);
T (&ba[0].a[1].b[0], bsz + 1);
T (&ba[0].a[1].b[0] + 1, bsz + 1);
-T (&ba[0].a[1].b[0] + v0, bsz + 1);
+T (&ba[0].a[1].b[0] + v0, bsz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (&ba[0].a[1].b[1], bsz + 1);
T (&ba[0].a[1].b[1] + 1, bsz + 1);
-T (&ba[0].a[1].b[1] + v0, bsz + 1);
+T (&ba[0].a[1].b[1] + v0, bsz + 1); /* { dg-bogus "specified bound 6 exceeds source size 5" pr95794" { xfail *-*-* } } */
T (ba[1].a[0].a, asz);
T (&ba[1].a[0].a[0], asz);