From 55f6a7d949abc708d1c6ebc01eb3053f96d1472b Mon Sep 17 00:00:00 2001 From: benjamin priour Date: Sun, 27 Aug 2023 14:36:14 +0200 Subject: analyzer: Move gcc.dg/analyzer tests to c-c++-common (1) [PR96395] First batch of moving tests from under gcc.dg/analyzer into c-c++-common/analyzer. C builtins are not recognized as such by C++, therefore this patch no longer uses tree.h:fndecl_built_in_p to recognize a builtin function, but rather the function names. Thus functions named as C builtins - such as calloc, sprintf ... - are recognized as such both in C and C++ sources by the analyzer. For user-declared functions named after builtins, the latters' function_decl tree are now preferred over the function_decl the user declared, even when the FE consider their declaration to mismatch (Wbuiltin-declaration-mismatch emitted). This mainly comes into account in the handling of these function attributes : the analyzer uses the builtin's attributes defined in gcc/builtins.def. Signed-off-by: benjamin priour gcc/analyzer/ChangeLog: PR analyzer/96395 * analyzer.h (class known_function): Add virtual casts to builtin_known_function. (class builtin_known_function): New subclass of known_function for builtins. * kf.cc (class kf_alloca): Now derived from builtin_known_function. (class kf_calloc): Likewise. (class kf_free): Likewise. (class kf_malloc): Likewise. (class kf_memcpy_memmove): Likewise. (class kf_memset): Likewise. (class kf_realloc): Likewise. (class kf_strchr): Likewise. (class kf_sprintf): Likewise. (class kf_strcat): Likewise. (class kf_strcpy): Likewise. (class kf_strdup): Likewise. (class kf_strlen): Likewise. (class kf_strndup): Likewise. (register_known_functions): Builtins are now registered as known_functions by name rather than by their BUILTIN_CODE. * known-function-manager.cc (get_normal_builtin): New overload. * known-function-manager.h: New overload declaration. * region-model.cc (region_model::get_builtin_kf): New function. * region-model.h (class region_model): Add declaration of get_builtin_kf. * sm-fd.cc: For called recognized as builtins, use the attributes of that builtin as defined in gcc/builtins.def rather than the user's. * sm-malloc.cc (malloc_state_machine::on_stmt): Likewise. gcc/testsuite/ChangeLog: PR analyzer/96395 * gcc.dg/analyzer/aliasing-3.c: Moved to... * c-c++-common/analyzer/aliasing-3.c: ...here. * gcc.dg/analyzer/aliasing-pr106473.c: Moved to... * c-c++-common/analyzer/aliasing-pr106473.c: ...here. * gcc.dg/analyzer/asm-x86-dyndbg-2.c: Moved to... * c-c++-common/analyzer/asm-x86-dyndbg-2.c: ...here. * gcc.dg/analyzer/asm-x86-lp64-2.c: Moved to... * c-c++-common/analyzer/asm-x86-lp64-2.c: ...here. * gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c: Moved to... * c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c: ...here. * gcc.dg/analyzer/atomic-builtins-qemu-sockets.c: Moved to... * c-c++-common/analyzer/atomic-builtins-qemu-sockets.c: ...here. * gcc.dg/analyzer/attr-malloc-6.c: Moved to... * c-c++-common/analyzer/attr-malloc-6.c: ...here. * gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c: Moved to... * c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c: ...here. * gcc.dg/analyzer/attr-tainted_args-1.c: Moved to... * c-c++-common/analyzer/attr-tainted_args-1.c: ...here. * gcc.dg/analyzer/call-summaries-pr107158.c: Moved to... * c-c++-common/analyzer/call-summaries-pr107158.c: ...here. * gcc.dg/analyzer/calloc-1.c: Moved to... * c-c++-common/analyzer/calloc-1.c: ...here. * gcc.dg/analyzer/compound-assignment-5.c: Moved to... * c-c++-common/analyzer/compound-assignment-5.c: ...here. * gcc.dg/analyzer/coreutils-cksum-pr108664.c: Moved to... * c-c++-common/analyzer/coreutils-cksum-pr108664.c: ...here. * gcc.dg/analyzer/coreutils-sum-pr108666.c: Moved to... * c-c++-common/analyzer/coreutils-sum-pr108666.c: ...here. * gcc.dg/analyzer/deref-before-check-pr108455-1.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr108455-1.c: ...here. * gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c: ...here. * gcc.dg/analyzer/deref-before-check-pr108475-1.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr108475-1.c: ...here. * gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c: ...here. * gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c: ...here. * gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c: ...here. * gcc.dg/analyzer/deref-before-check-pr77425.c: Moved to... * c-c++-common/analyzer/deref-before-check-pr77425.c: ...here. * gcc.dg/analyzer/exec-1.c: Moved to... * c-c++-common/analyzer/exec-1.c: ...here. * gcc.dg/analyzer/feasibility-3.c: Moved to... * c-c++-common/analyzer/feasibility-3.c: ...here. * gcc.dg/analyzer/fields.c: Moved to... * c-c++-common/analyzer/fields.c: ...here. * gcc.dg/analyzer/function-ptr-5.c: Moved to... * c-c++-common/analyzer/function-ptr-5.c: ...here. * gcc.dg/analyzer/infinite-recursion-pr108524-1.c: Moved to... * c-c++-common/analyzer/infinite-recursion-pr108524-1.c: ...here. * gcc.dg/analyzer/infinite-recursion-pr108524-2.c: Moved to... * c-c++-common/analyzer/infinite-recursion-pr108524-2.c: ...here. * gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c: Moved to... * c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c: ...here. * gcc.dg/analyzer/init.c: Moved to... * c-c++-common/analyzer/init.c: ...here. * gcc.dg/analyzer/inlining-3-multiline.c: Moved to... * c-c++-common/analyzer/inlining-3-multiline.c: ...here. * gcc.dg/analyzer/inlining-3.c: Moved to... * c-c++-common/analyzer/inlining-3.c: ...here. * gcc.dg/analyzer/inlining-4-multiline.c: Moved to... * c-c++-common/analyzer/inlining-4-multiline.c: ...here. * gcc.dg/analyzer/inlining-4.c: Moved to... * c-c++-common/analyzer/inlining-4.c: ...here. * gcc.dg/analyzer/leak-pr105906.c: Moved to... * c-c++-common/analyzer/leak-pr105906.c: ...here. * gcc.dg/analyzer/leak-pr108045-with-call-summaries.c: Moved to... * c-c++-common/analyzer/leak-pr108045-with-call-summaries.c: ...here. * gcc.dg/analyzer/leak-pr108045-without-call-summaries.c: Moved to... * c-c++-common/analyzer/leak-pr108045-without-call-summaries.c: ...here. * gcc.dg/analyzer/leak-pr109059-1.c: Moved to... * c-c++-common/analyzer/leak-pr109059-1.c: ...here. * gcc.dg/analyzer/leak-pr109059-2.c: Moved to... * c-c++-common/analyzer/leak-pr109059-2.c: ...here. * gcc.dg/analyzer/malloc-2.c: Moved to... * c-c++-common/analyzer/malloc-2.c: ...here. * gcc.dg/analyzer/memcpy-2.c: Moved to... * c-c++-common/analyzer/memcpy-2.c: ...here. * gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c: Moved to... * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c: ...here. * gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c: Moved to... * c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c: ...here. * gcc.dg/analyzer/null-deref-pr108806-qemu.c: Moved to... * c-c++-common/analyzer/null-deref-pr108806-qemu.c: ...here. * gcc.dg/analyzer/null-deref-pr108830.c: Moved to... * c-c++-common/analyzer/null-deref-pr108830.c: ...here. * gcc.dg/analyzer/pr101962.c: Moved to... * c-c++-common/analyzer/pr101962.c: ...here. * gcc.dg/analyzer/pr103217-2.c: Moved to... * c-c++-common/analyzer/pr103217-2.c: ...here. * gcc.dg/analyzer/pr103217.c: Moved to... * c-c++-common/analyzer/pr103217.c: ...here. * gcc.dg/analyzer/pr104029.c: Moved to... * c-c++-common/analyzer/pr104029.c: ...here. * gcc.dg/analyzer/pr104062.c: Moved to... * c-c++-common/analyzer/pr104062.c: ...here. * gcc.dg/analyzer/pr105783.c: Moved to... * c-c++-common/analyzer/pr105783.c: ...here. * gcc.dg/analyzer/pr107345.c: Moved to... * c-c++-common/analyzer/pr107345.c: ...here. * gcc.dg/analyzer/pr93695-1.c: Moved to... * c-c++-common/analyzer/pr93695-1.c: ...here. * gcc.dg/analyzer/pr94596.c: Moved to... * c-c++-common/analyzer/pr94596.c: ...here. * gcc.dg/analyzer/pr94839.c: Moved to... * c-c++-common/analyzer/pr94839.c: ...here. * gcc.dg/analyzer/pr95152-4.c: C only. * gcc.dg/analyzer/pr95152-5.c: C only. * gcc.dg/analyzer/pr95240.c: Moved to... * c-c++-common/analyzer/pr95240.c: ...here. * gcc.dg/analyzer/pr96639.c: Moved to... * c-c++-common/analyzer/pr96639.c: ...here. * gcc.dg/analyzer/pr96653.c: Moved to... * c-c++-common/analyzer/pr96653.c: ...here. * gcc.dg/analyzer/pr96792.c: Moved to... * c-c++-common/analyzer/pr96792.c: ...here. * gcc.dg/analyzer/pr96841.c: Moved to... * c-c++-common/analyzer/pr96841.c: ...here. * gcc.dg/analyzer/pr98564.c: Moved to... * c-c++-common/analyzer/pr98564.c: ...here. * gcc.dg/analyzer/pr98628.c: Moved to... * c-c++-common/analyzer/pr98628.c: ...here. * gcc.dg/analyzer/pr98969.c: Moved to... * c-c++-common/analyzer/pr98969.c: ...here. * gcc.dg/analyzer/pr99193-2.c: Moved to... * c-c++-common/analyzer/pr99193-2.c: ...here. * gcc.dg/analyzer/pr99193-3.c: Moved to... * c-c++-common/analyzer/pr99193-3.c: ...here. * gcc.dg/analyzer/pr99716-1.c: Moved to... * c-c++-common/analyzer/pr99716-1.c: ...here. * gcc.dg/analyzer/pr99774-1.c: Moved to... * c-c++-common/analyzer/pr99774-1.c: ...here. * gcc.dg/analyzer/realloc-1.c: Moved to... * c-c++-common/analyzer/realloc-1.c: ...here. * gcc.dg/analyzer/realloc-2.c: Moved to... * c-c++-common/analyzer/realloc-2.c: ...here. * gcc.dg/analyzer/realloc-3.c: Moved to... * c-c++-common/analyzer/realloc-3.c: ...here. * gcc.dg/analyzer/realloc-4.c: Moved to... * c-c++-common/analyzer/realloc-4.c: ...here. * gcc.dg/analyzer/realloc-5.c: Moved to... * c-c++-common/analyzer/realloc-5.c: ...here. * gcc.dg/analyzer/realloc-pr110014.c: Moved to... * c-c++-common/analyzer/realloc-pr110014.c: ...here. * gcc.dg/analyzer/snprintf-concat.c: Moved to... * c-c++-common/analyzer/snprintf-concat.c: ...here. * gcc.dg/analyzer/sock-1.c: Moved to... * c-c++-common/analyzer/sock-1.c: ...here. * gcc.dg/analyzer/sprintf-concat.c: Moved to... * c-c++-common/analyzer/sprintf-concat.c: ...here. * gcc.dg/analyzer/string-ops-concat-pair.c: Moved to... * c-c++-common/analyzer/string-ops-concat-pair.c: ...here. * gcc.dg/analyzer/string-ops-dup.c: Moved to... * c-c++-common/analyzer/string-ops-dup.c: ...here. * gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c: Moved to... * c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c: ...here. * gcc.dg/analyzer/symbolic-12.c: Moved to... * c-c++-common/analyzer/symbolic-12.c: ...here. * gcc.dg/analyzer/uninit-alloca.c: Moved to... * c-c++-common/analyzer/uninit-alloca.c: ...here. * gcc.dg/analyzer/untracked-2.c: Moved to... * c-c++-common/analyzer/untracked-2.c: ...here. * gcc.dg/analyzer/vasprintf-1.c: Moved to... * c-c++-common/analyzer/vasprintf-1.c: ...here. * gcc.dg/analyzer/write-to-const-1.c: Moved to... * c-c++-common/analyzer/write-to-const-1.c: ...here. * gcc.dg/analyzer/write-to-function-1.c: C only. * gcc.dg/analyzer/write-to-string-literal-1.c: Moved to... * c-c++-common/analyzer/write-to-string-literal-1.c: ...here. * gcc.dg/analyzer/write-to-string-literal-4-disabled.c: Moved to... * c-c++-common/analyzer/write-to-string-literal-4-disabled.c: ...here. * gcc.dg/analyzer/write-to-string-literal-5.c: Moved to... * c-c++-common/analyzer/write-to-string-literal-5.c: ...here. * g++.dg/analyzer/analyzer.exp: Now also run tests under c-c++-common/analyzer. * gcc.dg/analyzer/analyzer-decls.h: Add NULL definition. * gcc.dg/analyzer/analyzer.exp: Now also run tests under c-c++-common/analyzer. * gcc.dg/analyzer/pr104369-1.c: C only. * gcc.dg/analyzer/pr104369-2.c: Likewise. * gcc.dg/analyzer/pr93355-localealias-feasibility-2.c: Likewise. * gcc.dg/analyzer/sprintf-1.c: Split into C-only and C++-friendly bits. * gcc.dg/analyzer/allocation-size-multiline-1.c: Removed. * gcc.dg/analyzer/allocation-size-multiline-2.c: Removed. * gcc.dg/analyzer/allocation-size-multiline-3.c: Removed. * gcc.dg/analyzer/data-model-11.c: Removed. * gcc.dg/analyzer/pr61861.c: C only. * gcc.dg/analyzer/pr93457.c: Removed. * gcc.dg/analyzer/pr97568.c: Removed. * gcc.dg/analyzer/write-to-string-literal-4.c: Removed. * c-c++-common/analyzer/allocation-size-multiline-1.c: New test. * c-c++-common/analyzer/allocation-size-multiline-2.c: New test. * c-c++-common/analyzer/allocation-size-multiline-3.c: New test. * c-c++-common/analyzer/data-model-11.c: New test. * c-c++-common/analyzer/pr93457.c: New test. * c-c++-common/analyzer/pr97568.c: New test. * c-c++-common/analyzer/sprintf-2.c: C++-friendly bit of previous gcc.dg/analyzer/sprintf-1.c. * c-c++-common/analyzer/write-to-string-literal-4.c: New test. --- gcc/analyzer/analyzer.h | 22 + gcc/analyzer/kf.cc | 210 +++- gcc/analyzer/known-function-manager.cc | 7 + gcc/analyzer/known-function-manager.h | 2 + gcc/analyzer/region-model.cc | 56 + gcc/analyzer/region-model.h | 4 + gcc/analyzer/sm-fd.cc | 25 +- gcc/analyzer/sm-malloc.cc | 133 ++- gcc/testsuite/c-c++-common/analyzer/aliasing-3.c | 73 ++ .../c-c++-common/analyzer/aliasing-pr106473.c | 5 + .../analyzer/allocation-size-multiline-1.c | 96 ++ .../analyzer/allocation-size-multiline-2.c | 98 ++ .../analyzer/allocation-size-multiline-3.c | 68 ++ .../c-c++-common/analyzer/asm-x86-dyndbg-2.c | 79 ++ .../c-c++-common/analyzer/asm-x86-lp64-2.c | 36 + .../analyzer/atomic-builtins-haproxy-proxy.c | 55 + .../analyzer/atomic-builtins-qemu-sockets.c | 18 + .../c-c++-common/analyzer/attr-malloc-6.c | 228 ++++ .../analyzer/attr-malloc-CVE-2019-19078-usb-leak.c | 225 ++++ .../c-c++-common/analyzer/attr-tainted_args-1.c | 88 ++ .../analyzer/call-summaries-pr107158.c | 83 ++ gcc/testsuite/c-c++-common/analyzer/calloc-1.c | 24 + .../c-c++-common/analyzer/compound-assignment-5.c | 136 +++ .../analyzer/coreutils-cksum-pr108664.c | 88 ++ .../c-c++-common/analyzer/coreutils-sum-pr108666.c | 98 ++ .../c-c++-common/analyzer/data-model-11.c | 6 + .../analyzer/deref-before-check-pr108455-1.c | 36 + ...deref-before-check-pr108455-git-pack-revindex.c | 133 +++ .../analyzer/deref-before-check-pr108475-1.c | 52 + .../deref-before-check-pr108475-haproxy-tcpcheck.c | 171 +++ .../deref-before-check-pr109060-haproxy-cfgparse.c | 92 ++ .../deref-before-check-pr109239-linux-bus.c | 154 +++ .../analyzer/deref-before-check-pr77425.c | 45 + gcc/testsuite/c-c++-common/analyzer/exec-1.c | 49 + .../c-c++-common/analyzer/feasibility-3.c | 138 +++ gcc/testsuite/c-c++-common/analyzer/fields.c | 41 + .../c-c++-common/analyzer/function-ptr-5.c | 42 + .../analyzer/infinite-recursion-pr108524-1.c | 147 +++ .../analyzer/infinite-recursion-pr108524-2.c | 113 ++ ...finite-recursion-pr108524-qobject-json-parser.c | 324 ++++++ gcc/testsuite/c-c++-common/analyzer/init.c | 136 +++ .../c-c++-common/analyzer/inlining-3-multiline.c | 99 ++ gcc/testsuite/c-c++-common/analyzer/inlining-3.c | 34 + .../c-c++-common/analyzer/inlining-4-multiline.c | 117 +++ gcc/testsuite/c-c++-common/analyzer/inlining-4.c | 30 + .../c-c++-common/analyzer/leak-pr105906.c | 33 + .../analyzer/leak-pr108045-with-call-summaries.c | 106 ++ .../leak-pr108045-without-call-summaries.c | 107 ++ .../c-c++-common/analyzer/leak-pr109059-1.c | 46 + .../c-c++-common/analyzer/leak-pr109059-2.c | 42 + gcc/testsuite/c-c++-common/analyzer/malloc-2.c | 23 + gcc/testsuite/c-c++-common/analyzer/memcpy-2.c | 9 + ...-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c | 99 ++ ...ull-deref-pr108251-smp_fetch_ssl_fc_has_early.c | 98 ++ .../analyzer/null-deref-pr108806-qemu.c | 105 ++ .../c-c++-common/analyzer/null-deref-pr108830.c | 94 ++ gcc/testsuite/c-c++-common/analyzer/pr101962.c | 51 + gcc/testsuite/c-c++-common/analyzer/pr103217-2.c | 54 + gcc/testsuite/c-c++-common/analyzer/pr103217.c | 44 + gcc/testsuite/c-c++-common/analyzer/pr104029.c | 115 ++ gcc/testsuite/c-c++-common/analyzer/pr104062.c | 13 + gcc/testsuite/c-c++-common/analyzer/pr105783.c | 30 + gcc/testsuite/c-c++-common/analyzer/pr107345.c | 18 + gcc/testsuite/c-c++-common/analyzer/pr93457.c | 12 + gcc/testsuite/c-c++-common/analyzer/pr93695-1.c | 53 + gcc/testsuite/c-c++-common/analyzer/pr94596.c | 100 ++ gcc/testsuite/c-c++-common/analyzer/pr94839.c | 20 + gcc/testsuite/c-c++-common/analyzer/pr95240.c | 27 + gcc/testsuite/c-c++-common/analyzer/pr96639.c | 10 + gcc/testsuite/c-c++-common/analyzer/pr96653.c | 1104 ++++++++++++++++++++ gcc/testsuite/c-c++-common/analyzer/pr96792.c | 39 + gcc/testsuite/c-c++-common/analyzer/pr96841.c | 21 + gcc/testsuite/c-c++-common/analyzer/pr97568.c | 31 + gcc/testsuite/c-c++-common/analyzer/pr98564.c | 6 + gcc/testsuite/c-c++-common/analyzer/pr98628.c | 18 + gcc/testsuite/c-c++-common/analyzer/pr98969.c | 26 + gcc/testsuite/c-c++-common/analyzer/pr99193-2.c | 68 ++ gcc/testsuite/c-c++-common/analyzer/pr99193-3.c | 50 + gcc/testsuite/c-c++-common/analyzer/pr99716-1.c | 46 + gcc/testsuite/c-c++-common/analyzer/pr99774-1.c | 61 ++ gcc/testsuite/c-c++-common/analyzer/realloc-1.c | 96 ++ gcc/testsuite/c-c++-common/analyzer/realloc-2.c | 80 ++ gcc/testsuite/c-c++-common/analyzer/realloc-3.c | 82 ++ gcc/testsuite/c-c++-common/analyzer/realloc-4.c | 84 ++ gcc/testsuite/c-c++-common/analyzer/realloc-5.c | 45 + .../c-c++-common/analyzer/realloc-pr110014.c | 25 + .../c-c++-common/analyzer/snprintf-concat.c | 35 + gcc/testsuite/c-c++-common/analyzer/sock-1.c | 114 ++ gcc/testsuite/c-c++-common/analyzer/sprintf-2.c | 59 ++ .../c-c++-common/analyzer/sprintf-concat.c | 35 + .../c-c++-common/analyzer/string-ops-concat-pair.c | 68 ++ .../c-c++-common/analyzer/string-ops-dup.c | 61 ++ .../analyzer/switch-enum-pr105273-git-vreportf-2.c | 40 + gcc/testsuite/c-c++-common/analyzer/symbolic-12.c | 106 ++ .../c-c++-common/analyzer/uninit-alloca.c | 7 + gcc/testsuite/c-c++-common/analyzer/untracked-2.c | 7 + gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c | 58 + .../c-c++-common/analyzer/write-to-const-1.c | 29 + .../analyzer/write-to-string-literal-1.c | 67 ++ .../analyzer/write-to-string-literal-4-disabled.c | 28 + .../analyzer/write-to-string-literal-4.c | 26 + .../analyzer/write-to-string-literal-5.c | 34 + gcc/testsuite/g++.dg/analyzer/analyzer.exp | 3 + gcc/testsuite/gcc.dg/analyzer/aliasing-3.c | 75 -- gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c | 5 - .../gcc.dg/analyzer/allocation-size-multiline-1.c | 59 -- .../gcc.dg/analyzer/allocation-size-multiline-2.c | 62 -- .../gcc.dg/analyzer/allocation-size-multiline-3.c | 44 - gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h | 12 + gcc/testsuite/gcc.dg/analyzer/analyzer.exp | 3 + gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c | 77 -- gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c | 34 - .../analyzer/atomic-builtins-haproxy-proxy.c | 55 - .../gcc.dg/analyzer/atomic-builtins-qemu-sockets.c | 18 - gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c | 228 ---- .../analyzer/attr-malloc-CVE-2019-19078-usb-leak.c | 222 ---- .../gcc.dg/analyzer/attr-tainted_args-1.c | 88 -- .../gcc.dg/analyzer/call-summaries-pr107158.c | 83 -- gcc/testsuite/gcc.dg/analyzer/calloc-1.c | 27 - .../gcc.dg/analyzer/compound-assignment-5.c | 142 --- .../gcc.dg/analyzer/coreutils-cksum-pr108664.c | 83 -- .../gcc.dg/analyzer/coreutils-sum-pr108666.c | 98 -- gcc/testsuite/gcc.dg/analyzer/data-model-11.c | 6 - .../analyzer/deref-before-check-pr108455-1.c | 36 - ...deref-before-check-pr108455-git-pack-revindex.c | 133 --- .../analyzer/deref-before-check-pr108475-1.c | 51 - .../deref-before-check-pr108475-haproxy-tcpcheck.c | 169 --- .../deref-before-check-pr109060-haproxy-cfgparse.c | 92 -- .../deref-before-check-pr109239-linux-bus.c | 153 --- .../gcc.dg/analyzer/deref-before-check-pr77425.c | 43 - gcc/testsuite/gcc.dg/analyzer/exec-1.c | 43 - gcc/testsuite/gcc.dg/analyzer/feasibility-3.c | 133 --- gcc/testsuite/gcc.dg/analyzer/fields.c | 41 - gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c | 42 - .../analyzer/infinite-recursion-pr108524-1.c | 145 --- .../analyzer/infinite-recursion-pr108524-2.c | 113 -- ...finite-recursion-pr108524-qobject-json-parser.c | 322 ------ gcc/testsuite/gcc.dg/analyzer/init.c | 136 --- .../gcc.dg/analyzer/inlining-3-multiline.c | 64 -- gcc/testsuite/gcc.dg/analyzer/inlining-3.c | 30 - .../gcc.dg/analyzer/inlining-4-multiline.c | 72 -- gcc/testsuite/gcc.dg/analyzer/inlining-4.c | 27 - gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c | 32 - .../analyzer/leak-pr108045-with-call-summaries.c | 106 -- .../leak-pr108045-without-call-summaries.c | 107 -- gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c | 46 - gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c | 42 - gcc/testsuite/gcc.dg/analyzer/malloc-2.c | 23 - gcc/testsuite/gcc.dg/analyzer/memcpy-2.c | 8 - ...-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c | 99 -- ...ull-deref-pr108251-smp_fetch_ssl_fc_has_early.c | 98 -- .../gcc.dg/analyzer/null-deref-pr108806-qemu.c | 105 -- .../gcc.dg/analyzer/null-deref-pr108830.c | 94 -- gcc/testsuite/gcc.dg/analyzer/pr101962.c | 52 - gcc/testsuite/gcc.dg/analyzer/pr103217-2.c | 54 - gcc/testsuite/gcc.dg/analyzer/pr103217.c | 44 - gcc/testsuite/gcc.dg/analyzer/pr104029.c | 115 -- gcc/testsuite/gcc.dg/analyzer/pr104062.c | 13 - gcc/testsuite/gcc.dg/analyzer/pr104369-1.c | 7 +- gcc/testsuite/gcc.dg/analyzer/pr104369-2.c | 7 +- gcc/testsuite/gcc.dg/analyzer/pr105783.c | 26 - gcc/testsuite/gcc.dg/analyzer/pr107345.c | 17 - gcc/testsuite/gcc.dg/analyzer/pr61861.c | 3 +- .../analyzer/pr93355-localealias-feasibility-2.c | 1 - gcc/testsuite/gcc.dg/analyzer/pr93457.c | 10 - gcc/testsuite/gcc.dg/analyzer/pr93695-1.c | 53 - gcc/testsuite/gcc.dg/analyzer/pr94596.c | 97 -- gcc/testsuite/gcc.dg/analyzer/pr94839.c | 20 - gcc/testsuite/gcc.dg/analyzer/pr95152-4.c | 4 +- gcc/testsuite/gcc.dg/analyzer/pr95152-5.c | 1 + gcc/testsuite/gcc.dg/analyzer/pr95240.c | 27 - gcc/testsuite/gcc.dg/analyzer/pr96639.c | 10 - gcc/testsuite/gcc.dg/analyzer/pr96653.c | 1104 -------------------- gcc/testsuite/gcc.dg/analyzer/pr96792.c | 39 - gcc/testsuite/gcc.dg/analyzer/pr96841.c | 21 - gcc/testsuite/gcc.dg/analyzer/pr97568.c | 29 - gcc/testsuite/gcc.dg/analyzer/pr98564.c | 6 - gcc/testsuite/gcc.dg/analyzer/pr98628.c | 18 - gcc/testsuite/gcc.dg/analyzer/pr98969.c | 25 - gcc/testsuite/gcc.dg/analyzer/pr99193-2.c | 68 -- gcc/testsuite/gcc.dg/analyzer/pr99193-3.c | 50 - gcc/testsuite/gcc.dg/analyzer/pr99716-1.c | 45 - gcc/testsuite/gcc.dg/analyzer/pr99774-1.c | 61 -- gcc/testsuite/gcc.dg/analyzer/realloc-1.c | 95 -- gcc/testsuite/gcc.dg/analyzer/realloc-2.c | 82 -- gcc/testsuite/gcc.dg/analyzer/realloc-3.c | 83 -- gcc/testsuite/gcc.dg/analyzer/realloc-4.c | 85 -- gcc/testsuite/gcc.dg/analyzer/realloc-5.c | 46 - gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c | 25 - gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c | 35 - gcc/testsuite/gcc.dg/analyzer/sock-1.c | 112 -- gcc/testsuite/gcc.dg/analyzer/sprintf-1.c | 53 +- gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c | 35 - .../gcc.dg/analyzer/string-ops-concat-pair.c | 67 -- gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c | 61 -- .../analyzer/switch-enum-pr105273-git-vreportf-2.c | 40 - gcc/testsuite/gcc.dg/analyzer/symbolic-12.c | 106 -- gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c | 7 - gcc/testsuite/gcc.dg/analyzer/untracked-2.c | 7 - gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c | 57 - gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c | 29 - .../gcc.dg/analyzer/write-to-function-1.c | 2 + .../gcc.dg/analyzer/write-to-string-literal-1.c | 58 - .../analyzer/write-to-string-literal-4-disabled.c | 28 - .../gcc.dg/analyzer/write-to-string-literal-4.c | 23 - .../gcc.dg/analyzer/write-to-string-literal-5.c | 32 - 206 files changed, 7811 insertions(+), 7294 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/analyzer/aliasing-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/calloc-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/data-model-11.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/exec-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/feasibility-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/fields.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/init.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-4.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/malloc-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/memcpy-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr101962.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr103217-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr103217.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr104029.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr104062.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr105783.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr107345.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr93457.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr93695-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr94596.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr94839.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr95240.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr96639.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr96653.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr96792.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr96841.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr97568.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr98564.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr98628.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr98969.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr99193-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr99193-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr99716-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr99774-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-3.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-4.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-5.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/sock-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/sprintf-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/symbolic-12.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/untracked-2.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4.c create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/aliasing-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/calloc-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/coreutils-cksum-pr108664.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/data-model-11.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/exec-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/feasibility-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/fields.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/init.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-4.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/malloc-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/memcpy-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr101962.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr103217-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr103217.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr104029.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr104062.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr105783.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr107345.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93457.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93695-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr94596.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr94839.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr95240.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96639.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96653.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96792.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr96841.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr97568.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr98564.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr98628.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr98969.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99193-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99193-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99716-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr99774-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-3.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-4.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-5.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/sock-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/symbolic-12.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/untracked-2.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c (limited to 'gcc') diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h index 93a28b4..9b351b5 100644 --- a/gcc/analyzer/analyzer.h +++ b/gcc/analyzer/analyzer.h @@ -128,6 +128,10 @@ struct interesting_t; class feasible_node; +class known_function; + class builtin_known_function; + class internal_known_function; + /* Forward decls of functions. */ extern void dump_tree (pretty_printer *pp, tree t); @@ -279,6 +283,24 @@ public: { return; } + + virtual const builtin_known_function * + dyn_cast_builtin_kf () const { return NULL; } +}; + +/* Subclass of known_function for builtin functions. */ + +class builtin_known_function : public known_function +{ +public: + virtual enum built_in_function builtin_code () const = 0; + tree builtin_decl () const { + gcc_assert (builtin_code () < END_BUILTINS); + return builtin_info[builtin_code ()].decl; + } + + const builtin_known_function * + dyn_cast_builtin_kf () const final override { return this; } }; /* Subclass of known_function for IFN_* functions. */ diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc index 36d9d10..333ffd9 100644 --- a/gcc/analyzer/kf.cc +++ b/gcc/analyzer/kf.cc @@ -53,13 +53,17 @@ impl_call_pre (const call_details &cd) const /* Handler for "alloca". */ -class kf_alloca : public known_function +class kf_alloca : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override { return cd.num_args () == 1; } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_ALLOCA; + } void impl_call_pre (const call_details &cd) const final override; }; @@ -322,7 +326,7 @@ public: /* Handler for "calloc". */ -class kf_calloc : public known_function +class kf_calloc : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override @@ -331,6 +335,11 @@ public: && cd.arg_is_size_p (0) && cd.arg_is_size_p (1)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_CALLOC; + } + void impl_call_pre (const call_details &cd) const final override; }; @@ -462,12 +471,16 @@ public: all pointers to the region to the "freed" state together, regardless of casts. */ -class kf_free : public known_function +class kf_free : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override { - return (cd.num_args () == 0 && cd.arg_is_pointer_p (0)); + return (cd.num_args () == 1 && cd.arg_is_pointer_p (0)); + } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_FREE; } void impl_call_post (const call_details &cd) const final override; }; @@ -488,7 +501,7 @@ kf_free::impl_call_post (const call_details &cd) const /* Handle the on_call_pre part of "malloc". */ -class kf_malloc : public known_function +class kf_malloc : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override @@ -496,6 +509,10 @@ public: return (cd.num_args () == 1 && cd.arg_is_size_p (0)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_MALLOC; + } void impl_call_pre (const call_details &cd) const final override; }; @@ -520,9 +537,18 @@ kf_malloc::impl_call_pre (const call_details &cd) const /* TODO: complain about overlapping src and dest for the memcpy variants. */ -class kf_memcpy_memmove : public known_function +class kf_memcpy_memmove : public builtin_known_function { public: + enum kf_memcpy_memmove_variant + { + KF_MEMCPY, + KF_MEMCPY_CHK, + KF_MEMMOVE, + KF_MEMMOVE_CHK, + }; + kf_memcpy_memmove (enum kf_memcpy_memmove_variant variant) + : m_variant (variant) {}; bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == 3 @@ -530,7 +556,25 @@ public: && cd.arg_is_pointer_p (1) && cd.arg_is_size_p (2)); } + enum built_in_function builtin_code () const final override + { + switch (m_variant) + { + case KF_MEMCPY: + return BUILT_IN_MEMCPY; + case KF_MEMCPY_CHK: + return BUILT_IN_MEMCPY_CHK; + case KF_MEMMOVE: + return BUILT_IN_MEMMOVE; + case KF_MEMMOVE_CHK: + return BUILT_IN_MEMMOVE_CHK; + default: + gcc_unreachable (); + } + } void impl_call_pre (const call_details &cd) const final override; +private: + const enum kf_memcpy_memmove_variant m_variant; }; void @@ -557,15 +601,21 @@ kf_memcpy_memmove::impl_call_pre (const call_details &cd) const /* Handler for "memset" and "__builtin_memset". */ -class kf_memset : public known_function +class kf_memset : public builtin_known_function { public: + kf_memset (bool chk_variant) : m_chk_variant (chk_variant) {} bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == 3 && cd.arg_is_pointer_p (0)); } - + enum built_in_function builtin_code () const final override + { + return m_chk_variant ? BUILT_IN_MEMSET_CHK : BUILT_IN_MEMSET; + } void impl_call_pre (const call_details &cd) const final override; +private: + const bool m_chk_variant; }; void @@ -747,7 +797,7 @@ public: Each of these has a custom_edge_info subclass, which updates the region_model and sm-state of the destination state. */ -class kf_realloc : public known_function +class kf_realloc : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override @@ -756,6 +806,12 @@ public: && cd.arg_is_pointer_p (0) && cd.arg_is_size_p (1)); } + + enum built_in_function builtin_code () const final override + { + return BUILT_IN_REALLOC; + } + void impl_call_post (const call_details &cd) const final override; }; @@ -968,7 +1024,7 @@ kf_realloc::impl_call_post (const call_details &cd) const /* Handler for "strchr" and "__builtin_strchr". */ -class kf_strchr : public known_function +class kf_strchr : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override @@ -979,6 +1035,11 @@ public: { cd.check_for_null_terminated_string_arg (0); } + + enum built_in_function builtin_code () const final override + { + return BUILT_IN_STRCHR; + } void impl_call_post (const call_details &cd) const final override; }; @@ -1055,7 +1116,7 @@ kf_strchr::impl_call_post (const call_details &cd) const int sprintf(char *str, const char *format, ...); */ -class kf_sprintf : public known_function +class kf_sprintf : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override @@ -1065,6 +1126,11 @@ public: && cd.arg_is_pointer_p (1)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_SPRINTF; + } + void impl_call_pre (const call_details &cd) const final override { /* For now, merely assume that the destination buffer gets set to a @@ -1108,10 +1174,12 @@ public: /* Handler for "strcat" and "__builtin_strcat_chk". */ -class kf_strcat : public known_function +class kf_strcat : public builtin_known_function { public: - kf_strcat (unsigned int num_args) : m_num_args (num_args) {} + kf_strcat (unsigned int num_args, bool chk_variant) + : m_num_args (num_args), + m_chk_variant (chk_variant) {} bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == m_num_args @@ -1119,6 +1187,11 @@ public: && cd.arg_is_pointer_p (1)); } + enum built_in_function builtin_code () const final override + { + return m_chk_variant ? BUILT_IN_STRCAT_CHK : BUILT_IN_STRCAT; + } + void impl_call_pre (const call_details &cd) const final override { region_model *model = cd.get_model (); @@ -1159,25 +1232,32 @@ public: private: unsigned int m_num_args; + const bool m_chk_variant; }; /* Handler for "strcpy" and "__builtin_strcpy_chk". */ -class kf_strcpy : public known_function +class kf_strcpy : public builtin_known_function { public: - kf_strcpy (unsigned int num_args) : m_num_args (num_args) {} + kf_strcpy (unsigned int num_args, bool chk_variant) + : m_num_args (num_args), + m_chk_variant (chk_variant) {} bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == m_num_args && cd.arg_is_pointer_p (0) && cd.arg_is_pointer_p (1)); } - + enum built_in_function builtin_code () const final override + { + return m_chk_variant ? BUILT_IN_STRCPY_CHK : BUILT_IN_STRCPY; + } void impl_call_pre (const call_details &cd) const final override; private: unsigned int m_num_args; + const bool m_chk_variant; }; void @@ -1207,13 +1287,17 @@ kf_strcpy::impl_call_pre (const call_details &cd) const /* Handler for "strdup" and "__builtin_strdup". */ -class kf_strdup : public known_function +class kf_strdup : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == 1 && cd.arg_is_pointer_p (0)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_STRDUP; + } void impl_call_pre (const call_details &cd) const final override { region_model *model = cd.get_model (); @@ -1234,13 +1318,18 @@ public: /* Handler for "strlen" and for "__analyzer_get_strlen". */ -class kf_strlen : public known_function +class kf_strlen : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == 1 && cd.arg_is_pointer_p (0)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_STRLEN; + } + void impl_call_pre (const call_details &cd) const final override { if (const svalue *strlen_sval @@ -1266,13 +1355,17 @@ make_kf_strlen () /* Handler for "strndup" and "__builtin_strndup". */ -class kf_strndup : public known_function +class kf_strndup : public builtin_known_function { public: bool matches_call_types_p (const call_details &cd) const final override { return (cd.num_args () == 2 && cd.arg_is_pointer_p (0)); } + enum built_in_function builtin_code () const final override + { + return BUILT_IN_STRNDUP; + } void impl_call_pre (const call_details &cd) const final override { region_model *model = cd.get_model (); @@ -1445,44 +1538,73 @@ register_known_functions (known_function_manager &kfm) kfm.add (IFN_UBSAN_BOUNDS, make_unique ()); } - /* Built-ins the analyzer has known_functions for. */ + /* GCC built-ins that do not correspond to a function + in the standard library. */ { - kfm.add (BUILT_IN_ALLOCA, make_unique ()); - kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, make_unique ()); - kfm.add (BUILT_IN_CALLOC, make_unique ()); kfm.add (BUILT_IN_EXPECT, make_unique ()); kfm.add (BUILT_IN_EXPECT_WITH_PROBABILITY, make_unique ()); - kfm.add (BUILT_IN_FREE, make_unique ()); - kfm.add (BUILT_IN_MALLOC, make_unique ()); - kfm.add (BUILT_IN_MEMCPY, make_unique ()); - kfm.add (BUILT_IN_MEMCPY_CHK, make_unique ()); - kfm.add (BUILT_IN_MEMMOVE, make_unique ()); - kfm.add (BUILT_IN_MEMMOVE_CHK, make_unique ()); - kfm.add (BUILT_IN_MEMSET, make_unique ()); - kfm.add (BUILT_IN_MEMSET_CHK, make_unique ()); - kfm.add (BUILT_IN_REALLOC, make_unique ()); - kfm.add (BUILT_IN_SPRINTF, make_unique ()); + kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, make_unique ()); kfm.add (BUILT_IN_STACK_RESTORE, make_unique ()); kfm.add (BUILT_IN_STACK_SAVE, make_unique ()); - kfm.add (BUILT_IN_STRCAT, make_unique (2)); - kfm.add (BUILT_IN_STRCAT_CHK, make_unique (3)); - kfm.add (BUILT_IN_STRCHR, make_unique ()); - kfm.add (BUILT_IN_STRCPY, make_unique (2)); - kfm.add (BUILT_IN_STRCPY_CHK, make_unique (3)); - kfm.add (BUILT_IN_STRDUP, make_unique ()); - kfm.add (BUILT_IN_STRNDUP, make_unique ()); - kfm.add (BUILT_IN_STRLEN, make_kf_strlen ()); register_atomic_builtins (kfm); register_varargs_builtins (kfm); } - /* Known builtins and C standard library functions. */ + /* Known builtins and C standard library functions + the analyzer has known functions for. */ { - kfm.add ("memset", make_unique ()); - kfm.add ("strcat", make_unique (2)); + kfm.add ("alloca", make_unique ()); + kfm.add ("__builtin_alloca", make_unique ()); + kfm.add ("calloc", make_unique ()); + kfm.add ("__builtin_calloc", make_unique ()); + kfm.add ("free", make_unique ()); + kfm.add ("__builtin_free", make_unique ()); + kfm.add ("malloc", make_unique ()); + kfm.add ("__builtin_malloc", make_unique ()); + kfm.add ("memcpy", + make_unique (kf_memcpy_memmove::KF_MEMCPY)); + kfm.add ("__builtin_memcpy", + make_unique (kf_memcpy_memmove::KF_MEMCPY)); + kfm.add ("__memcpy_chk", make_unique + (kf_memcpy_memmove::KF_MEMCPY_CHK)); + kfm.add ("__builtin___memcpy_chk", make_unique + (kf_memcpy_memmove::KF_MEMCPY_CHK)); + kfm.add ("memmove", + make_unique (kf_memcpy_memmove::KF_MEMMOVE)); + kfm.add ("__builtin_memmove", + make_unique (kf_memcpy_memmove::KF_MEMMOVE)); + kfm.add ("__memmove_chk", make_unique + (kf_memcpy_memmove::KF_MEMMOVE_CHK)); + kfm.add ("__builtin___memmove_chk", make_unique + (kf_memcpy_memmove::KF_MEMMOVE_CHK)); + kfm.add ("memset", make_unique (false)); + kfm.add ("__builtin_memset", make_unique (false)); + kfm.add ("__memset_chk", make_unique (true)); + kfm.add ("__builtin___memset_chk", make_unique (true)); + kfm.add ("realloc", make_unique ()); + kfm.add ("__builtin_realloc", make_unique ()); + kfm.add ("sprintf", make_unique ()); + kfm.add ("__builtin_sprintf", make_unique ()); + kfm.add ("strchr", make_unique ()); + kfm.add ("__builtin_strchr", make_unique ()); + kfm.add ("strcpy", make_unique (2, false)); + kfm.add ("__builtin_strcpy", make_unique (2, false)); + kfm.add ("__strcpy_chk", make_unique (3, true)); + kfm.add ("__builtin___strcpy_chk", make_unique (3, true)); + kfm.add ("strcat", make_unique (2, false)); + kfm.add ("__builtin_strcat", make_unique (2, false)); + kfm.add ("__strcat_chk", make_unique (3, true)); + kfm.add ("__builtin___strcat_chk", make_unique (3, true)); kfm.add ("strdup", make_unique ()); + kfm.add ("__builtin_strdup", make_unique ()); kfm.add ("strndup", make_unique ()); + kfm.add ("__builtin_strndup", make_unique ()); + kfm.add ("strlen", make_unique ()); + kfm.add ("__builtin_strlen", make_unique ()); + + register_atomic_builtins (kfm); + register_varargs_builtins (kfm); } /* Known POSIX functions, and some non-standard extensions. */ diff --git a/gcc/analyzer/known-function-manager.cc b/gcc/analyzer/known-function-manager.cc index 4a2cf52..615c495 100644 --- a/gcc/analyzer/known-function-manager.cc +++ b/gcc/analyzer/known-function-manager.cc @@ -137,6 +137,13 @@ known_function_manager::get_normal_builtin (enum built_in_function name) const return m_combined_fns_arr[name]; } +const known_function * +known_function_manager:: +get_normal_builtin (const builtin_known_function *builtin_kf) const +{ + return get_normal_builtin (builtin_kf->builtin_code ()); +} + /* Get any known_function matching IDENTIFIER, without type-checking. Return NULL if there isn't one. */ diff --git a/gcc/analyzer/known-function-manager.h b/gcc/analyzer/known-function-manager.h index 1432e54..04f49ce 100644 --- a/gcc/analyzer/known-function-manager.h +++ b/gcc/analyzer/known-function-manager.h @@ -54,6 +54,8 @@ private: DISABLE_COPY_AND_ASSIGN (known_function_manager); const known_function *get_normal_builtin (enum built_in_function name) const; + const known_function * + get_normal_builtin (const builtin_known_function *builtin_kf) const; const known_function *get_by_identifier (tree identifier) const; /* Map from identifier to known_function instance. diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc index 02c073c..4f31a6d 100644 --- a/gcc/analyzer/region-model.cc +++ b/gcc/analyzer/region-model.cc @@ -1514,6 +1514,62 @@ region_model::get_known_function (enum internal_fn ifn) const return known_fn_mgr->get_internal_fn (ifn); } +/* Get any builtin_known_function for CALL and emit any warning to CTXT + if not NULL. + + The call must match all assumptions made by the known_function (such as + e.g. "argument 1's type must be a pointer type"). + + Return NULL if no builtin_known_function is found, or it does + not match the assumption(s). + + Internally calls get_known_function to find a known_function and cast it + to a builtin_known_function. + + For instance, calloc is a C builtin, defined in gcc/builtins.def + by the DEF_LIB_BUILTIN macro. Such builtins are recognized by the + analyzer by their name, so that even in C++ or if the user redeclares + them but mismatch their signature, they are still recognized as builtins. + + Cases when a supposed builtin is not flagged as one by the FE: + + The C++ FE does not recognize calloc as a builtin if it has not been + included from a standard header, but the C FE does. Hence in C++ if + CALL comes from a calloc and stdlib is not included, + gcc/tree.h:fndecl_built_in_p (CALL) would be false. + + In C code, a __SIZE_TYPE__ calloc (__SIZE_TYPE__, __SIZE_TYPE__) user + declaration has obviously a mismatching signature from the standard, and + its function_decl tree won't be unified by + gcc/c-decl.cc:match_builtin_function_types. + + Yet in both cases the analyzer should treat the calls as a builtin calloc + so that extra attributes unspecified by the standard but added by GCC + (e.g. sprintf attributes in gcc/builtins.def), useful for the detection of + dangerous behavior, are indeed processed. + + Therefore for those cases when a "builtin flag" is not added by the FE, + builtins' kf are derived from builtin_known_function, whose method + builtin_known_function::builtin_decl returns the builtin's + function_decl tree as defined in gcc/builtins.def, with all the extra + attributes. */ + +const builtin_known_function * +region_model::get_builtin_kf (const gcall *call, + region_model_context *ctxt /* = NULL */) const +{ + region_model *mut_this = const_cast (this); + tree callee_fndecl = mut_this->get_fndecl_for_call (call, ctxt); + if (! callee_fndecl) + return NULL; + + call_details cd (call, mut_this, ctxt); + if (const known_function *kf = get_known_function (callee_fndecl, cd)) + return kf->dyn_cast_builtin_kf (); + + return NULL; +} + /* Update this model for the CALL stmt, using CTXT to report any diagnostics - the first half. diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h index 4025962..10b2a59 100644 --- a/gcc/analyzer/region-model.h +++ b/gcc/analyzer/region-model.h @@ -528,6 +528,10 @@ class region_model bool include_terminator, const svalue **out_sval); + const builtin_known_function * + get_builtin_kf (const gcall *call, + region_model_context *ctxt = NULL) const; + private: const region *get_lvalue_1 (path_var pv, region_model_context *ctxt) const; const svalue *get_rvalue_1 (path_var pv, region_model_context *ctxt) const; diff --git a/gcc/analyzer/sm-fd.cc b/gcc/analyzer/sm-fd.cc index c75744f..34bbd84 100644 --- a/gcc/analyzer/sm-fd.cc +++ b/gcc/analyzer/sm-fd.cc @@ -1294,8 +1294,19 @@ fd_state_machine::check_for_fd_attrs ( const gcall *call, const tree callee_fndecl, const char *attr_name, access_directions fd_attr_access_dir) const { - - tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (callee_fndecl)); + /* Handle interesting fd attributes of the callee_fndecl, + or prioritize those of the builtin that callee_fndecl is + expected to be. + Might want this to be controlled by a flag. */ + tree fndecl = callee_fndecl; + /* If call is recognized as a builtin known_function, + use that builtin's function_decl. */ + if (const region_model *old_model = sm_ctxt->get_old_region_model ()) + if (const builtin_known_function *builtin_kf + = old_model->get_builtin_kf (call)) + fndecl = builtin_kf->builtin_decl (); + + tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl)); attrs = lookup_attribute (attr_name, attrs); if (!attrs) return; @@ -1325,13 +1336,15 @@ fd_state_machine::check_for_fd_attrs ( // attributes { + /* Do use the fndecl that caused the warning so that the + misused attributes are printed and the user not confused. */ if (is_closed_fd_p (state)) { sm_ctxt->warn (node, stmt, arg, make_unique (*this, diag_arg, - callee_fndecl, attr_name, + fndecl, attr_name, arg_idx)); continue; } @@ -1343,7 +1356,7 @@ fd_state_machine::check_for_fd_attrs ( sm_ctxt->warn (node, stmt, arg, make_unique (*this, diag_arg, - callee_fndecl, attr_name, + fndecl, attr_name, arg_idx)); continue; } @@ -1361,7 +1374,7 @@ fd_state_machine::check_for_fd_attrs ( node, stmt, arg, make_unique (*this, diag_arg, DIRS_WRITE, - callee_fndecl, + fndecl, attr_name, arg_idx)); } @@ -1375,7 +1388,7 @@ fd_state_machine::check_for_fd_attrs ( node, stmt, arg, make_unique (*this, diag_arg, DIRS_READ, - callee_fndecl, + fndecl, attr_name, arg_idx)); } diff --git a/gcc/analyzer/sm-malloc.cc b/gcc/analyzer/sm-malloc.cc index ec76325..2ff777d 100644 --- a/gcc/analyzer/sm-malloc.cc +++ b/gcc/analyzer/sm-malloc.cc @@ -1965,71 +1965,88 @@ malloc_state_machine::on_stmt (sm_context *sm_ctxt, malloc_state_machine *mutable_this = const_cast (this); - /* Handle "__attribute__((malloc(FOO)))". */ - if (const deallocator_set *deallocators + /* Handle interesting attributes of the callee_fndecl, + or prioritize those of the builtin that callee_fndecl is expected + to be. + Might want this to be controlled by a flag. */ + { + tree fndecl = callee_fndecl; + /* If call is recognized as a builtin known_function, use that + builtin's function_decl. */ + if (const region_model *old_model = sm_ctxt->get_old_region_model ()) + if (const builtin_known_function *builtin_kf + = old_model->get_builtin_kf (call)) + fndecl = builtin_kf->builtin_decl (); + + /* Handle "__attribute__((malloc(FOO)))". */ + if (const deallocator_set *deallocators = mutable_this->get_or_create_custom_deallocator_set - (callee_fndecl)) + (fndecl)) + { + tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (fndecl)); + bool returns_nonnull + = lookup_attribute ("returns_nonnull", attrs); + on_allocator_call (sm_ctxt, call, deallocators, returns_nonnull); + } + { - tree attrs = TYPE_ATTRIBUTES (TREE_TYPE (callee_fndecl)); - bool returns_nonnull - = lookup_attribute ("returns_nonnull", attrs); - on_allocator_call (sm_ctxt, call, deallocators, returns_nonnull); + /* Handle "__attribute__((nonnull))". */ + tree fntype = TREE_TYPE (fndecl); + bitmap nonnull_args = get_nonnull_args (fntype); + if (nonnull_args) + { + for (unsigned i = 0; i < gimple_call_num_args (stmt); i++) + { + tree arg = gimple_call_arg (stmt, i); + if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE) + continue; + /* If we have a nonnull-args, and either all pointers, or + just the specified pointers. */ + if (bitmap_empty_p (nonnull_args) + || bitmap_bit_p (nonnull_args, i)) + { + state_t state = sm_ctxt->get_state (stmt, arg); + /* Can't use a switch as the states are non-const. */ + /* Do use the fndecl that caused the warning so that the + misused attributes are printed and the user not + confused. */ + if (unchecked_p (state)) + { + tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); + sm_ctxt->warn (node, stmt, arg, + make_unique + (*this, diag_arg, fndecl, i)); + const allocation_state *astate + = as_a_allocation_state (state); + sm_ctxt->set_next_state (stmt, arg, + astate->get_nonnull ()); + } + else if (state == m_null) + { + tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); + sm_ctxt->warn (node, stmt, arg, + make_unique + (*this, diag_arg, fndecl, i)); + sm_ctxt->set_next_state (stmt, arg, m_stop); + } + else if (state == m_start) + maybe_assume_non_null (sm_ctxt, arg, stmt); + } + } + BITMAP_FREE (nonnull_args); + } } - /* Handle "__attribute__((nonnull))". */ - { - tree fntype = TREE_TYPE (callee_fndecl); - bitmap nonnull_args = get_nonnull_args (fntype); - if (nonnull_args) + /* Check for this after nonnull, so that if we have both + then we transition to "freed", rather than "checked". */ + unsigned dealloc_argno = fndecl_dealloc_argno (fndecl); + if (dealloc_argno != UINT_MAX) { - for (unsigned i = 0; i < gimple_call_num_args (stmt); i++) - { - tree arg = gimple_call_arg (stmt, i); - if (TREE_CODE (TREE_TYPE (arg)) != POINTER_TYPE) - continue; - /* If we have a nonnull-args, and either all pointers, or just - the specified pointers. */ - if (bitmap_empty_p (nonnull_args) - || bitmap_bit_p (nonnull_args, i)) - { - state_t state = sm_ctxt->get_state (stmt, arg); - /* Can't use a switch as the states are non-const. */ - if (unchecked_p (state)) - { - tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - sm_ctxt->warn (node, stmt, arg, - make_unique - (*this, diag_arg, callee_fndecl, i)); - const allocation_state *astate - = as_a_allocation_state (state); - sm_ctxt->set_next_state (stmt, arg, - astate->get_nonnull ()); - } - else if (state == m_null) - { - tree diag_arg = sm_ctxt->get_diagnostic_tree (arg); - sm_ctxt->warn (node, stmt, arg, - make_unique - (*this, diag_arg, callee_fndecl, i)); - sm_ctxt->set_next_state (stmt, arg, m_stop); - } - else if (state == m_start) - maybe_assume_non_null (sm_ctxt, arg, stmt); - } - } - BITMAP_FREE (nonnull_args); + const deallocator *d + = mutable_this->get_or_create_deallocator (fndecl); + on_deallocator_call (sm_ctxt, node, call, d, dealloc_argno); } } - - /* Check for this after nonnull, so that if we have both - then we transition to "freed", rather than "checked". */ - unsigned dealloc_argno = fndecl_dealloc_argno (callee_fndecl); - if (dealloc_argno != UINT_MAX) - { - const deallocator *d - = mutable_this->get_or_create_deallocator (callee_fndecl); - on_deallocator_call (sm_ctxt, node, call, d, dealloc_argno); - } } /* Look for pointers explicitly being compared against zero diff --git a/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c new file mode 100644 index 0000000..30772dc --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c @@ -0,0 +1,73 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +struct s1 +{ + int f1; +}; + +static struct s1 *p1_glob = NULL; + +void test_1 (struct s1 **pp1, struct s1 *p1_parm) +{ + struct s1 *init_p1_glob = p1_glob; + + __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ + + if (!p1_glob) + return; + + __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ + __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */ + + *pp1 = p1_parm; + + /* The write through *pp1 can't have changed p1_glob, because + we never take a pointer to p1_glob (and it's static to this TU). */ + __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ + __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */ +} + +struct s2 +{ + int f1; +}; + +static struct s2 *p2_glob = NULL; + +void test_2 (struct s2 **pp2, struct s2 *p2_parm) +{ + /* Ensure that p2_glob is modified. */ + p2_glob = (struct s2 *) __builtin_malloc (sizeof (struct s2)); + if (!p2_glob) + return; + + __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */ + + *pp2 = p2_parm; + + /* The write through *pp2 can't have changed p2_glob, because + we never take a pointer to p2_glob (and it's static to this TU). */ + __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */ +} + +struct s3 +{ + int f1; +}; + +struct s3 *p3_glob = NULL; + +void test_3 (struct s3 **pp3, struct s3 *p3_parm) +{ + p3_glob = (struct s3 *) __builtin_malloc (sizeof (struct s3)); + if (!p3_glob) + return; + + __analyzer_eval (p3_glob != NULL); /* { dg-warning "TRUE" } */ + + *pp3 = p3_parm; + + /* The write through *pp3 could have changed p3_glob, because + another TU could take a pointer to p3_glob. */ + __analyzer_eval (p3_glob != NULL); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c b/gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c new file mode 100644 index 0000000..4affa27 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c @@ -0,0 +1,5 @@ +void foo(char **args[], int *argc) +{ + *argc = 1; + (*args)[0] = (char *) __builtin_malloc(42); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c new file mode 100644 index 0000000..de1a49c --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-1.c @@ -0,0 +1,96 @@ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +#include + +void test_constant_1 (void) +{ + int32_t *ptr = (int32_t *) __builtin_malloc (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + __builtin_free (ptr); +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (1); + ^~~~~~~~~~~~~~~~~~~~ + 'test_constant_1': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (1); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 1 byte here + | (2) assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (1); + ~~~~~~~~~~~~~~~~~^~~ + 'void test_constant_1()': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (1); + | ~~~~~~~~~~~~~~~~~^~~ + | | + | (1) allocated 1 byte here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_constant_2 (void) +{ + int32_t *ptr = (int32_t *) __builtin_malloc (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + __builtin_free (ptr); +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (2); + ^~~~~~~~~~~~~~~~~~~~ + 'test_constant_2': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (2); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 2 bytes here + | (2) assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (2); + ~~~~~~~~~~~~~~~~~^~~ + 'void test_constant_2()': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (2); + | ~~~~~~~~~~~~~~~~~^~~ + | | + | (1) allocated 2 bytes here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_symbolic (int n) +{ + int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ + __builtin_free (ptr); +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + ^~~~~~~~~~~~~~~~~~~~~~~~ + 'test_symbolic': event 1 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + | ^~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 'n * 2' bytes and assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + ~~~~~~~~~~~~~~~~~^~~~~~~ + 'void test_symbolic(int)': event 1 + | + | int32_t *ptr = (int32_t *) __builtin_malloc (n * 2); + | ~~~~~~~~~~~~~~~~~^~~~~~~ + | | + | (1) allocated '(n * 2)' bytes and assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c new file mode 100644 index 0000000..a5def27 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-2.c @@ -0,0 +1,98 @@ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-fine-grained" } */ +/* { dg-require-effective-target alloca } */ + +#include + +void test_constant_1 (void) +{ + int32_t *ptr = (int32_t *) __builtin_alloca (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (1); + ^~~~~~~~~~~~~~~~~~~~ + 'test_constant_1': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (1); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 1 byte here + | (2) assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (1); + ~~~~~~~~~~~~~~~~~^~~ + 'void test_constant_1()': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (1); + | ~~~~~~~~~~~~~~~~~^~~ + | | + | (1) allocated 1 byte here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_constant_2 (void) +{ + int32_t *ptr = (int32_t *) __builtin_alloca (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (2); + ^~~~~~~~~~~~~~~~~~~~ + 'test_constant_2': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (2); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 2 bytes here + | (2) assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (2); + ~~~~~~~~~~~~~~~~~^~~ + 'void test_constant_2()': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (2); + | ~~~~~~~~~~~~~~~~~^~~ + | | + | (1) allocated 2 bytes here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_symbolic (int n) +{ + int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + ^~~~~~~~~~~~~~~~~~~~~~~~ + 'test_symbolic': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + | ^~~~~~~~~~~~~~~~~~~~~~~~ + | | + | (1) allocated 'n * 2' bytes here + | (2) assigned to 'int32_t *' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + ~~~~~~~~~~~~~~~~~^~~~~~~ + 'void test_symbolic(int)': events 1-2 + | + | int32_t *ptr = (int32_t *) __builtin_alloca (n * 2); + | ~~~~~~~~~~~~~~~~~^~~~~~~ + | | + | (1) allocated '(n * 2)' bytes here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +/* FIXME: am getting a duplicate warning here for some reason + without -fanalyzer-fine-grained (PR PR analyzer/107851). */ + diff --git a/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c new file mode 100644 index 0000000..3cf7fb0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/allocation-size-multiline-3.c @@ -0,0 +1,68 @@ +/* Verify that we warn for incorrect uses of "alloca" (which may be in a + macro in a system header), and that the output looks correct. */ + +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-fine-grained" } */ +/* { dg-require-effective-target alloca } */ + +#include +#include "../../gcc.dg/analyzer/test-alloca.h" + +void test_constant_99 (void) +{ + int32_t *ptr = (int32_t *) alloca (99); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) alloca (99); + ^~~~~~ + 'test_constant_99': events 1-2 + | + | int32_t *ptr = (int32_t *) alloca (99); + | ^~~~~~ + | | + | (1) allocated 99 bytes here + | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) alloca (99); + ^~~~~~ + 'void test_constant_99()': events 1-2 + | + | int32_t *ptr = (int32_t *) alloca (99); + | ^~~~~~ + | | + | (1) allocated 99 bytes here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ + +void test_symbolic (int n) +{ + int32_t *ptr = (int32_t *) alloca (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ +} + +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) alloca (n * 2); + ^~~~~~ + 'test_symbolic': events 1-2 + | + | int32_t *ptr = (int32_t *) alloca (n * 2); + | ^~~~~~ + | | + | (1) allocated 'n * 2' bytes here + | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + int32_t *ptr = (int32_t *) alloca (n * 2); + ^~~~~~ + 'void test_symbolic(int)': events 1-2 + | + | int32_t *ptr = (int32_t *) alloca (n * 2); + | ^~~~~~ + | | + | (1) allocated '(n * 2)' bytes here + | (2) assigned to 'int32_t*' {aka '{re:long :re?}int*'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c b/gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c new file mode 100644 index 0000000..d5e748c --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c @@ -0,0 +1,79 @@ +/* Test reduced from use of dynamic_pr_debug on Linux kernel, to verify that + we treat the static struct _ddebug as not needing to be tracked by the + analyzer, thus optimizing away bloat in the analyzer's state tracking. */ + +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-additional-options "-fdump-analyzer-untracked" } */ + +/* Adapted from various files in the Linux kernel, all of which have: */ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef __cplusplus + typedef _Bool bool; + #define true 1 + #define false 0 +#endif + +typedef struct {} atomic_t; + +/* Adapted from include/linux/compiler_attributes.h */ +#define __always_inline inline __attribute__((__always_inline__)) + +/* Adapted from include/linux/compiler-gcc.h */ +#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) + +/* Adapted from include/linux/jump_label.h, which has: */ + +struct static_key {}; + +/* Adapted from arch/x86/include/asm/jump_label.h */ + +static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) +{ + asm_volatile_goto("1:" + : : "i" (key), "i" (branch) : : l_yes); + + return false; +l_yes: + return true; +} + +/* Adapted from include/linux/dynamic_debug.h */ + +struct _ddebug { + /* [...snip...] */ + const char *function; + const char *filename; + const char *format; + unsigned int lineno:18; + /* [...snip...] */ + unsigned int flags:8; + struct static_key key; +} __attribute__((aligned(8))); + +extern void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); + +static void expanded_dynamic_pr_debug(void) { + do { + static struct _ddebug __attribute__((__aligned__(8))) + __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = { /* { dg-warning "track '__UNIQUE_ID_ddebug277': no" } */ + .function = __func__, + .filename = __FILE__, + .format = ("hello world"), + .lineno = __LINE__, + .flags = 0}; + if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false)) + __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, + "hello world"); + } while (0); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c b/gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c new file mode 100644 index 0000000..37c487a --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c @@ -0,0 +1,36 @@ +/* { dg-do compile { target x86_64-*-* } } */ +/* { dg-require-effective-target lp64 } */ + +/* Adapted from Linux x86: page_ref_dec_and_test.c (GPL-2.0). */ + +#ifndef __cplusplus + typedef _Bool bool; +#endif + +typedef struct { + int counter; +} atomic_t; + +bool +arch_atomic_dec_and_test(atomic_t *v) { + return ({ + bool c; + asm volatile(".pushsection .smp_locks,\"a\"\n" + ".balign 4\n" + ".long 671f - .\n" + ".popsection\n" + "671:" + "\n\tlock; " + "decl" + " " + "%[var]" + "\n\t/* output condition code " + "e" + "*/\n" + : [ var ] "+m"(v->counter), "=@cc" + "e"(c) + : + : "memory"); + c; + }); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c new file mode 100644 index 0000000..fbe89f7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c @@ -0,0 +1,55 @@ +/* Reduced from haproxy-2.7.1's proxy.c */ + +/* { dg-require-effective-target sync_int_long_stack } */ +/* { dg-require-effective-target sync_int_long } */ + +typedef __SIZE_TYPE__ size_t; + +extern void* malloc(size_t __size) + __attribute__((__nothrow__, __leaf__, __malloc__, __alloc_size__(1))); + +extern void free(void* __ptr) __attribute__((__nothrow__, __leaf__)); + +struct error_snapshot +{ + /* [..snip...] */ +}; + +struct proxy +{ + /* [..snip...] */ + struct error_snapshot *invalid_req, *invalid_rep; + /* [..snip...] */ +}; + +extern unsigned int error_snapshot_id; + +void +proxy_capture_error(struct proxy* proxy, + int is_back) +{ + struct error_snapshot* es; + unsigned int ev_id; + + /* [...snip...] */ + + ev_id = __atomic_fetch_add(&error_snapshot_id, 1, 5); + + /* [...snip...] */ + + es = (struct error_snapshot *) malloc(sizeof(*es)); + if (!es) + return; + + /* [...snip...] */ + + if (is_back) { + es = __atomic_exchange_n(&proxy->invalid_rep, es, 4); /* { dg-bogus "leak" } */ + } else { + es = __atomic_exchange_n(&proxy->invalid_req, es, 4); /* { dg-bogus "leak" } */ + } + + /* [...snip...] */ + + free(es); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c new file mode 100644 index 0000000..05ac339 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c @@ -0,0 +1,18 @@ +struct foo { + char placeholder[5]; +}; + +void * +test (const char *str) +{ + struct foo *p = (struct foo *) __builtin_malloc(sizeof(struct foo)); + if (!p) + return p; + + __builtin_memset(p, 0, sizeof(*p)); + + static int s = 1; + __atomic_store_n(&s, 0, 0); + + return p; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c new file mode 100644 index 0000000..1665d41 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c @@ -0,0 +1,228 @@ +/* Adapted from gcc.dg/Wmismatched-dealloc.c. */ + +#define A(...) __attribute__ ((malloc (__VA_ARGS__))) + +typedef struct FILE FILE; +typedef __SIZE_TYPE__ size_t; + +void free (void*); +void* malloc (size_t); +void* realloc (void*, size_t); + +int fclose (FILE*); +FILE* freopen (const char*, const char*, FILE*); +int pclose (FILE*); + +A (fclose) A (freopen, 3) + FILE* fdopen (int); +A (fclose) A (freopen, 3) + FILE* fopen (const char*, const char*); +A (fclose) A (freopen, 3) + FILE* fmemopen(void *, size_t, const char *); +A (fclose) A (freopen, 3) + FILE* freopen (const char*, const char*, FILE*); +A (pclose) A (freopen, 3) + FILE* popen (const char*, const char*); +A (fclose) A (freopen, 3) + FILE* tmpfile (void); + +void sink (FILE*); + + + void release (void*); +A (release) FILE* acquire (void); + +void nowarn_fdopen (void) +{ + { + FILE *q = fdopen (0); + if (!q) + return; + + fclose (q); + } + + { + FILE *q = fdopen (0); + if (!q) + return; + + q = freopen ("1", "r", q); + fclose (q); + } + + { + FILE *q = fdopen (0); + if (!q) + return; + + sink (q); + } +} + + +void warn_fdopen (void) +{ + { + FILE *q = fdopen (0); // { dg-message "allocated here" } + release (q); // { dg-warning "'release' called on 'q' returned from a mismatched allocation function" } + } + { + FILE *q = fdopen (0); // { dg-message "allocated here" } + free (q); // { dg-warning "'free' called on 'q' returned from a mismatched allocation function" } + } + + { + FILE *q = fdopen (0); // { dg-message "allocated here" } + q = (FILE *) realloc (q, 7); // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" } + sink (q); + } +} + + +void nowarn_fopen (void) +{ + { + FILE *q = fopen ("1", "r"); + sink (q); + fclose (q); + } + + { + FILE *q = fopen ("2", "r"); + sink (q); + q = freopen ("3", "r", q); + sink (q); + fclose (q); + } + + { + FILE *q = fopen ("4", "r"); + sink (q); + } +} + + +void warn_fopen (void) +{ + { + FILE *q = fopen ("1", "r"); + release (q); // { dg-warning "'release' called on 'q' returned from a mismatched allocation function" } + fclose (q); + } + { + FILE *q = fdopen (0); + free (q); // { dg-warning "'free' called on 'q' returned from a mismatched allocation function" } + } + + { + FILE *q = fdopen (0); + q = (FILE *) realloc (q, 7); // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" } + sink (q); + } +} + + +void test_popen (void) +{ + { + FILE *p = popen ("1", "r"); + sink (p); + pclose (p); + } + + { + FILE *p; + p = popen ("2", "r"); // { dg-message "allocated here" } + fclose (p); // { dg-warning "'fclose' called on 'p' returned from a mismatched allocation function" } + } + + { + /* freopen() can close a stream open by popen() but pclose() can't + close the stream returned from freopen(). */ + FILE *p = popen ("2", "r"); + p = freopen ("3", "r", p); // { dg-message "allocated here" } + pclose (p); // { dg-warning "'pclose' called on 'p' returned from a mismatched allocation function" } + } +} + + +void test_tmpfile (void) +{ + { + FILE *p = tmpfile (); + fclose (p); + } + + { + FILE *p = tmpfile (); + p = freopen ("1", "r", p); + fclose (p); + } + + { + FILE *p = tmpfile (); // { dg-message "allocated here" } + pclose (p); // { dg-warning "'pclose' called on 'p' returned from a mismatched allocation function" } + } +} + + +void warn_malloc (void) +{ + { + FILE *p = (FILE *) malloc (100); // { dg-message "allocated here" } + fclose (p); // { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'fclose'" } + } + + { + FILE *p = (FILE *) malloc (100); // { dg-message "allocated here" } + p = freopen ("1", "r", p);// { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'freopen'" } + fclose (p); + } + + { + FILE *p = (FILE *) malloc (100); // { dg-message "allocated here" } + pclose (p); // { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'pclose'" } + } +} + + +void test_acquire (void) +{ + { + FILE *p = acquire (); + release (p); + } + + { + FILE *p = acquire (); + release (p); + } + + { + FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } + fclose (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'fclose'" } + } + + { + FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } + pclose (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'pclose'" } + } + + { + FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } + p = freopen ("1", "r", p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'freopen'" } + sink (p); + } + + { + FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } + free (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'free'" } + } + + { + FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } + p = (FILE *) realloc (p, 123); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'realloc'" } + sink (p); + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c new file mode 100644 index 0000000..24fb46b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c @@ -0,0 +1,225 @@ +/* Adapted from linux 5.3.11: drivers/net/wireless/ath/ath10k/usb.c + Reduced reproducer for CVE-2019-19078 (leak of struct urb). */ + +typedef unsigned char u8; +typedef unsigned short u16; + +#ifndef __cplusplus + typedef _Bool bool; +#endif + +#define ENOMEM 12 +#define EINVAL 22 + +/* The original file has this licence header. */ + +// SPDX-License-Identifier: ISC +/* + * Copyright (c) 2007-2011 Atheros Communications Inc. + * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. + * Copyright (c) 2016-2017 Erik Stromdahl + */ + +/* Adapted from include/linux/compiler_attributes.h. */ +#define __aligned(x) __attribute__((__aligned__(x))) +#define __printf(a, b) __attribute__((__format__(printf, a, b))) + +/* Possible macro for the new attribute. */ +#define __malloc(f) __attribute__((malloc(f))); + +/* From include/linux/types.h. */ + +typedef unsigned int gfp_t; + +/* Not the real value, which is in include/linux/gfp.h. */ +#define GFP_ATOMIC 32 + +/* From include/linux/usb.h. */ + +struct urb; +extern void usb_free_urb(struct urb *urb); +extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) + __malloc(usb_free_urb); +/* attribute added as part of testcase */ + +extern int usb_submit_urb(/*struct urb *urb, */gfp_t mem_flags); +extern void usb_unanchor_urb(struct urb *urb); + +/* From drivers/net/wireless/ath/ath10k/core.h. */ + +struct ath10k; + +struct ath10k { + /* [...many other fields removed...] */ + + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); +}; + +/* From drivers/net/wireless/ath/ath10k/debug.h. */ + +enum ath10k_debug_mask { + /* [...other values removed...] */ + ATH10K_DBG_USB_BULK = 0x00080000, +}; + +extern unsigned int ath10k_debug_mask; + +__printf(3, 4) void __ath10k_dbg(struct ath10k *ar, + enum ath10k_debug_mask mask, + const char *fmt, ...); + +/* Simplified for now, to avoid pulling in tracepoint code. */ +static inline +bool trace_ath10k_log_dbg_enabled(void) { return 0; } + +#define ath10k_dbg(ar, dbg_mask, fmt, ...) \ +do { \ + if ((ath10k_debug_mask & dbg_mask) || \ + trace_ath10k_log_dbg_enabled()) \ + __ath10k_dbg(ar, dbg_mask, fmt, ##__VA_ARGS__); \ +} while (0) + +/* From drivers/net/wireless/ath/ath10k/hif.h. */ + +struct ath10k_hif_sg_item { + /* [...other fields removed...] */ + void *transfer_context; /* NULL = tx completion callback not called */ +}; + +struct ath10k_hif_ops { + /* send a scatter-gather list to the target */ + int (*tx_sg)(struct ath10k *ar, u8 pipe_id, + struct ath10k_hif_sg_item *items, int n_items); + /* [...other fields removed...] */ +}; + +/* From drivers/net/wireless/ath/ath10k/usb.h. */ + +/* tx/rx pipes for usb */ +enum ath10k_usb_pipe_id { + /* [...other values removed...] */ + ATH10K_USB_PIPE_MAX = 8 +}; + +struct ath10k_usb_pipe { + /* [...all fields removed...] */ +}; + +/* usb device object */ +struct ath10k_usb { + /* [...other fields removed...] */ + struct ath10k_usb_pipe pipes[ATH10K_USB_PIPE_MAX]; +}; + +/* usb urb object */ +struct ath10k_urb_context { + /* [...other fields removed...] */ + struct ath10k_usb_pipe *pipe; + struct sk_buff *skb; +}; + +static inline struct ath10k_usb *ath10k_usb_priv(struct ath10k *ar) +{ + return (struct ath10k_usb *)ar->drv_priv; +} + +/* The source file. */ + +static void ath10k_usb_post_recv_transfers(struct ath10k *ar, + struct ath10k_usb_pipe *recv_pipe); + +struct ath10k_urb_context * +ath10k_usb_alloc_urb_from_pipe(struct ath10k_usb_pipe *pipe); + +void ath10k_usb_free_urb_to_pipe(struct ath10k_usb_pipe *pipe, + struct ath10k_urb_context *urb_context); + +static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id, + struct ath10k_hif_sg_item *items, int n_items) +{ + struct ath10k_usb *ar_usb = ath10k_usb_priv(ar); + struct ath10k_usb_pipe *pipe = &ar_usb->pipes[pipe_id]; + struct ath10k_urb_context *urb_context; + struct sk_buff *skb; + struct urb *urb; + int ret, i; + + for (i = 0; i < n_items; i++) { + urb_context = ath10k_usb_alloc_urb_from_pipe(pipe); + if (!urb_context) { + ret = -ENOMEM; + goto err; + } + + skb = (struct sk_buff *) items[i].transfer_context; + urb_context->skb = skb; + + urb = usb_alloc_urb(0, GFP_ATOMIC); /* { dg-message "allocated here" } */ + if (!urb) { + ret = -ENOMEM; + goto err_free_urb_to_pipe; + } + + /* TODO: these are disabled, otherwise we conservatively + assume that they could free urb. */ +#if 0 + usb_fill_bulk_urb(urb, + ar_usb->udev, + pipe->usb_pipe_handle, + skb->data, + skb->len, + ath10k_usb_transmit_complete, urb_context); + if (!(skb->len % pipe->max_packet_size)) { + /* hit a max packet boundary on this pipe */ + urb->transfer_flags |= URB_ZERO_PACKET; + } + + usb_anchor_urb(urb, &pipe->urb_submitted); +#endif + /* TODO: initial argument disabled, otherwise we conservatively + assume that it could free urb. */ + ret = usb_submit_urb(/*urb, */GFP_ATOMIC); + if (ret) { /* TODO: why doesn't it show this condition at default verbosity? */ + ath10k_dbg(ar, ATH10K_DBG_USB_BULK, + "usb bulk transmit failed: %d\n", ret); + + /* TODO: this is disabled, otherwise we conservatively + assume that it could free urb. */ +#if 0 + usb_unanchor_urb(urb); +#endif + + ret = -EINVAL; + /* Leak of urb happens here. */ + goto err_free_urb_to_pipe; + } + + usb_free_urb(urb); /* { dg-bogus "double-'usb_free_urb' of 'urb'" } */ + } + + return 0; + +err_free_urb_to_pipe: + ath10k_usb_free_urb_to_pipe(urb_context->pipe, urb_context); +err: + return ret; /* { dg-warning "leak of 'urb'" } */ +} + +static const struct ath10k_hif_ops ath10k_usb_hif_ops = { + .tx_sg = ath10k_usb_hif_tx_sg, +}; + +/* Simulate code to register the callback. */ +extern void callback_registration (const void *); +void ath10k_usb_probe(void) +{ + callback_registration(&ath10k_usb_hif_ops); +} + + +/* The original source file ends with: +MODULE_AUTHOR("Atheros Communications, Inc."); +MODULE_DESCRIPTION("Driver support for Qualcomm Atheros 802.11ac WLAN USB devices"); +MODULE_LICENSE("Dual BSD/GPL"); +*/ diff --git a/gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c b/gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c new file mode 100644 index 0000000..0ff3446 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c @@ -0,0 +1,88 @@ +// TODO: remove need for this option +/* { dg-additional-options "-fanalyzer-checker=taint" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +struct arg_buf +{ + int i; + int j; +}; + +/* Example of marking a function as tainted. */ + +void __attribute__((tainted_args)) +test_1 (int i, void *p, char *q) +{ + /* There should be a single enode, + for the "tainted" entry to the function. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + + __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", *q); /* { dg-warning "state: 'tainted'" } */ + + struct arg_buf *args = (struct arg_buf *) p; + __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'tainted'" } */ +} + +/* Example of marking a callback field as tainted. */ + +struct s2 +{ + void (*cb) (int, void *, char *) + __attribute__((tainted_args)); +}; + +/* Function not marked as tainted. */ + +void +test_2a (int i, void *p, char *q) +{ + /* There should be a single enode, + for the normal entry to the function. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + + __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'start'" } */ + __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'start'" } */ + __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'start'" } */ + + struct arg_buf *args = (struct arg_buf *) p; + __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'start'" } */ + __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'start'" } */ +} + +/* Function referenced via t2b.cb, marked as "tainted". */ + +void +test_2b (int i, void *p, char *q) +{ + /* There should be two enodes + for the direct call, and the "tainted" entry to the function. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ +} + +/* Callback used via t2c.cb, marked as "tainted". */ +void +__analyzer_test_2c (int i, void *p, char *q) +{ + /* There should be a single enode, + for the "tainted" entry to the function. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + + __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */ + __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */ +} + +struct s2 t2b = +{ + .cb = test_2b +}; + +struct s2 t2c = +{ + .cb = __analyzer_test_2c +}; diff --git a/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c new file mode 100644 index 0000000..d4cf079 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c @@ -0,0 +1,83 @@ +/* { dg-additional-options "-fanalyzer-call-summaries" } */ + +typedef __SIZE_TYPE__ size_t; +enum { _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)) }; +extern const unsigned short int **__ctype_b_loc(void) + __attribute__((__nothrow__, __leaf__, __const__)); +extern void *malloc(size_t __size) + __attribute__((__nothrow__, __leaf__, __malloc__, __alloc_size__(1))); +extern char *strcpy(char *__restrict __dest, const char *__restrict __src) + __attribute__((__nothrow__, __leaf__, __nonnull__(1, 2))); +extern size_t strlen(const char *__s) + __attribute__((__nothrow__, __leaf__, __pure__, __nonnull__(1))); + +struct mydata { + struct mydata *link; + char *name; + char *type; +}; + +static struct mydata *all_data; +static int line_no; + +__attribute__((__noreturn__)) void failed(const char *message); + +static char *string_dup(const char *string) { + char *buf; + + if ((buf = (char *) malloc(strlen(string) + 1)) == ((void *)0)) + failed("malloc() failed"); + + return strcpy(buf, string); +} + +static void store_data(const char *name, const char *type) { + struct mydata *p, *q; + + if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0)) + failed("malloc() failed"); + + p->link = (struct mydata *)((void *)0); + p->name = string_dup(name); + p->type = string_dup(type); + + if ((q = all_data) == ((void *)0)) + all_data = p; + else { + while (q->link != ((void *)0)) + q = q->link; + q->link = p; + } +} + +static void parse_tbl(char *buffer) { + char *s = buffer; + char *t = s + strlen(s); + + do { + t--; + if (((*__ctype_b_loc())[(int)(((int)*t))] & (unsigned short int)_ISspace)) + *t = '\0'; + else + break; + } while (t > s); + while (((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + s++; + buffer = s; + + line_no++; + if (*buffer != ';' && *buffer != '\0') { + if (*buffer == '#') { + store_data(buffer, ""); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } else { + + while (*s && !((*__ctype_b_loc())[(int)(((int)*s))] & + (unsigned short int)_ISspace)) + s++; + while ( + ((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) + *s++ = '\0'; + store_data(buffer, s); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ + } + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/calloc-1.c b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c new file mode 100644 index 0000000..6bd658e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c @@ -0,0 +1,24 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" +typedef __SIZE_TYPE__ size_t; + +extern void *calloc (size_t __nmemb, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1, 2))) ; + +char *test_1 (size_t sz) +{ + char *p; + + p = (char *) calloc (1, 3); + if (!p) + return NULL; + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ + + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ + + return p; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c new file mode 100644 index 0000000..3ce2b72 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c @@ -0,0 +1,136 @@ +#include "../../gcc.dg/analyzer/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_arr2[16]; + +void test_2 (void) +{ + struct coord arr[16]; + arr[3].x = 5; + arr[3].y = 6; + + glob_arr2[7] = arr[3]; + + __analyzer_eval (glob_arr2[7].x == 5); /* { dg-warning "TRUE" } */ + __analyzer_eval (glob_arr2[7].y == 6); /* { dg-warning "TRUE" } */ +} + +/* Copying from a partially initialized on-stack array to a global array. */ + +struct coord glob_arr3[16]; + +void test_3 (void) +{ + struct coord arr[16]; + arr[3].y = 6; + + glob_arr3[7] = arr[3]; // or should the uninit warning be here? + + __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */ + /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */ + __analyzer_eval (glob_arr3[7].y == 6); /* { dg-warning "TRUE" } */ +} + +/* Symbolic bindings: copying from one array to another. */ + +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 */ + +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. */ + +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. */ + +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. */ + +struct coord glob_arr6[16]; + +void test_6 (void) +{ + struct coord arr[16]; + arr[7] = glob_arr6[3]; + + __analyzer_eval (arr[7].x == 5); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (arr[7].y == 6); /* { dg-warning "UNKNOWN" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c b/gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c new file mode 100644 index 0000000..7ae4e6b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c @@ -0,0 +1,88 @@ +/* { dg-require-effective-target int32plus } */ +/* { dg-require-effective-target size24plus } */ + +/* Reduced from coreutils's cksum.c: cksum_slice8 */ + +typedef long unsigned int size_t; +typedef unsigned int __uint32_t; +typedef unsigned long int __uintmax_t; +typedef struct _IO_FILE FILE; + +#ifndef __cplusplus + typedef _Bool bool; +#endif + +extern size_t +fread_unlocked(void* __restrict __ptr, + size_t __size, + size_t __n, + FILE* __restrict __stream); +extern int +feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); +extern int +ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); +static __inline __uint32_t +__bswap_32(__uint32_t __bsx) +{ + + return __builtin_bswap32(__bsx); +} +typedef __uint32_t uint32_t; +typedef unsigned long int uint_fast32_t; +typedef __uintmax_t uintmax_t; +extern int* +__errno_location(void) __attribute__((__nothrow__, __leaf__)) +__attribute__((__const__)); +extern uint_fast32_t const crctab[8][256]; + +static bool +cksum_slice8(FILE* fp, uint_fast32_t* crc_out, uintmax_t* length_out) +{ + uint32_t buf[(1 << 16) / sizeof(uint32_t)]; + uint_fast32_t crc = 0; + uintmax_t length = 0; + size_t bytes_read; + + if (!fp || !crc_out || !length_out) + return 0; + + while ((bytes_read = fread_unlocked(buf, 1, (1 << 16), fp)) > 0) { + uint32_t* datap; + + if (length + bytes_read < length) { + + (*__errno_location()) = 75; + return 0; + } + length += bytes_read; + + if (bytes_read == 0) { + if (ferror_unlocked(fp)) + return 0; + } + + datap = (uint32_t*)buf; + while (bytes_read >= 8) { + uint32_t first = *datap++, second = *datap++; /* { dg-bogus "use of uninitialized value" "PR analyzer/108664" } */ + crc ^= __bswap_32(first); + second = __bswap_32(second); + crc = + (crctab[7][(crc >> 24) & 0xFF] ^ crctab[6][(crc >> 16) & 0xFF] ^ + crctab[5][(crc >> 8) & 0xFF] ^ crctab[4][(crc)&0xFF] ^ + crctab[3][(second >> 24) & 0xFF] ^ crctab[2][(second >> 16) & 0xFF] ^ + crctab[1][(second >> 8) & 0xFF] ^ crctab[0][(second)&0xFF]); + bytes_read -= 8; + } + + unsigned char* cp = (unsigned char*)datap; + while (bytes_read--) + crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ *cp++) & 0xFF]; + if (feof_unlocked(fp)) + break; + } + + *crc_out = crc; + *length_out = length; + + return 1; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c b/gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c new file mode 100644 index 0000000..5684d1b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c @@ -0,0 +1,98 @@ +/* Reduced from coreutils's sum.c: bsd_sum_stream */ + +typedef long unsigned int size_t; +typedef unsigned char __uint8_t; +typedef unsigned long int __uintmax_t; +typedef struct _IO_FILE FILE; +extern size_t +fread_unlocked(void* __restrict __ptr, + size_t __size, + size_t __n, + FILE* __restrict __stream); +extern int +feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); +extern int +ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); +extern void* +memcpy(void* __restrict __dest, const void* __restrict __src, size_t __n) + __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); +extern void +rpl_free(void*); +extern int* +__errno_location(void) __attribute__((__nothrow__, __leaf__)) +__attribute__((__const__)); +extern void* +malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) +__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); +typedef __uint8_t uint8_t; +typedef __uintmax_t uintmax_t; + +int +bsd_sum_stream(FILE* stream, void* resstream, uintmax_t* length) +{ + int ret = -1; + size_t sum, n; + int checksum = 0; + uintmax_t total_bytes = 0; + static const size_t buffer_length = 32768; + uint8_t* buffer = (uint8_t *) malloc(buffer_length); + + if (!buffer) + return -1; + + while (1) { + sum = 0; + + while (1) { + n = fread_unlocked(buffer + sum, 1, buffer_length - sum, stream); + sum += n; + + if (buffer_length == sum) + break; + + if (n == 0) { + if (ferror_unlocked(stream)) + goto cleanup_buffer; + goto final_process; + } + + if (feof_unlocked(stream)) + goto final_process; + } + + for (size_t i = 0; i < sum; i++) { + checksum = (checksum >> 1) + ((checksum & 1) << 15); + checksum += buffer[i]; /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */ + checksum &= 0xffff; + } + if (total_bytes + sum < total_bytes) { + + (*__errno_location()) = 75; + goto cleanup_buffer; + } + total_bytes += sum; + } + +final_process:; + + for (size_t i = 0; i < sum; i++) { + checksum = (checksum >> 1) + ((checksum & 1) << 15); + checksum += buffer[i]; /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */ + checksum &= 0xffff; + } + if (total_bytes + sum < total_bytes) { + + (*__errno_location()) = 75; + goto cleanup_buffer; + } + total_bytes += sum; + + memcpy(resstream, &checksum, sizeof checksum); + *length = total_bytes; + ret = 0; +cleanup_buffer: + + rpl_free(buffer); + return ret; +} + diff --git a/gcc/testsuite/c-c++-common/analyzer/data-model-11.c b/gcc/testsuite/c-c++-common/analyzer/data-model-11.c new file mode 100644 index 0000000..0e64e5b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/data-model-11.c @@ -0,0 +1,6 @@ +int test (void) +{ + const unsigned char *s = (const unsigned char *) "abc"; + const signed char *t = (const signed char *) "xyz"; + return s[1] + t[1]; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c new file mode 100644 index 0000000..5f2ca96 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c @@ -0,0 +1,36 @@ +extern int could_fail_1 (void); +extern void *could_fail_2 (int); +extern void cleanup (void *); + +struct header { + int signature; +}; + +int test_1 (void) { + int fd, ret = 0; + void *data = ((void *)0); + struct header *hdr; + + fd = could_fail_1 (); + + if (fd < 0) { + ret = -1; + goto cleanup; + } + + data = could_fail_2 (fd); + hdr = (struct header *) data; + + if (hdr->signature != 42) { + ret = -2; + goto cleanup; + } + +cleanup: + if (ret) { + if (data) /* { dg-bogus "check of 'data' for NULL after already dereferencing it" } */ + cleanup (data); + } + + return ret; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c new file mode 100644 index 0000000..7431bd1 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c @@ -0,0 +1,133 @@ +/* Reduced from git-2.39.0's pack-revindex.c */ + +typedef unsigned int __uint32_t; +typedef unsigned long int __uintmax_t; +typedef long int __off_t; +typedef long int __off64_t; +typedef __SIZE_TYPE__ size_t; +typedef __off64_t off_t; +typedef __uint32_t uint32_t; +typedef __uintmax_t uintmax_t; + +struct stat { + /* [...snip...] */ + __off_t st_size; + /* [...snip...] */ +}; + +extern int close(int __fd); +extern int fstat(int __fd, struct stat *__buf) + __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2))); +extern uint32_t default_swab32(uint32_t val); +extern uint32_t git_bswap32(uint32_t x); +__attribute__((__noreturn__)) void die(const char *err, ...) + __attribute__((format(printf, 1, 2))); +int error(const char *err, ...) __attribute__((format(printf, 1, 2))); +int error_errno(const char *err, ...) __attribute__((format(printf, 1, 2))); +static inline int const_error(void) { return -1; } +extern int munmap(void *__addr, size_t __len) + __attribute__((__nothrow__, __leaf__)); +extern size_t st_mult(size_t a, size_t b); +extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, + off_t offset); +extern size_t xsize_t(off_t len); + +extern char *gettext(const char *__msgid) __attribute__((__nothrow__, __leaf__)) +__attribute__((__format_arg__(1))); +static inline __attribute__((format_arg(1))) const char *_(const char *msgid) { + if (!*msgid) + return ""; + return gettext(msgid); +} + +struct repository { + /* [...snip...] */ + const struct git_hash_algo *hash_algo; + /* [...snip...] */ +}; +extern struct repository *the_repository; +struct git_hash_algo { + /* [...snip...] */ + size_t rawsz; + /* [...snip...] */ +}; + +int git_open_cloexec(const char *name, int flags); + +struct revindex_header { + uint32_t signature; + uint32_t version; + uint32_t hash_id; +}; + +int load_revindex_from_disk(char *revindex_name, uint32_t num_objects, + const uint32_t **data_p, size_t *len_p) { + int fd, ret = 0; + struct stat st; + void *data = ((void *)0); + size_t revindex_size; + struct revindex_header *hdr; + + fd = git_open_cloexec(revindex_name, 00); + + if (fd < 0) { + ret = -1; + goto cleanup; + } + if (fstat(fd, &st)) { + ret = (error_errno(_("failed to read %s"), revindex_name), const_error()); + goto cleanup; + } + + revindex_size = xsize_t(st.st_size); + + if (revindex_size < ((12) + (2 * the_repository->hash_algo->rawsz))) { + ret = (error(_("reverse-index file %s is too small"), revindex_name), + const_error()); + goto cleanup; + } + + if (revindex_size - ((12) + (2 * the_repository->hash_algo->rawsz)) != + st_mult(sizeof(uint32_t), num_objects)) { + ret = (error(_("reverse-index file %s is corrupt"), revindex_name), + const_error()); + goto cleanup; + } + + data = xmmap(((void *)0), revindex_size, 0x1, 0x02, fd, 0); + hdr = (struct revindex_header *) data; + + if (git_bswap32(hdr->signature) != 0x52494458) { + ret = + (error(_("reverse-index file %s has unknown signature"), revindex_name), + const_error()); + goto cleanup; + } + if (git_bswap32(hdr->version) != 1) { + ret = (error(_("reverse-index file %s has unsupported version %" + "u"), + revindex_name, git_bswap32(hdr->version)), + const_error()); + goto cleanup; + } + if (!(git_bswap32(hdr->hash_id) == 1 || git_bswap32(hdr->hash_id) == 2)) { + ret = (error(_("reverse-index file %s has unsupported hash id %" + "u"), + revindex_name, git_bswap32(hdr->hash_id)), + const_error()); + goto cleanup; + } + +cleanup: + if (ret) { + if (data) /* { dg-bogus "check of 'data' for NULL after already dereferencing it" } */ + munmap(data, revindex_size); + } else { + *len_p = revindex_size; + *data_p = (const uint32_t *)data; + } + + if (fd >= 0) + close(fd); + return ret; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c new file mode 100644 index 0000000..0d5edf8 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c @@ -0,0 +1,52 @@ +/* Reduced from haproxy-2.7.1: src/tcpcheck.c. */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +int +test_1 (char **args, int cur_arg) +{ + char *p = NULL; + + if (*args[cur_arg]) { + p = args[cur_arg]; + } + + if (p) { /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ + return 1; + } + return 0; +} + +int +test_2 (char **args, int cur_arg) +{ + char *p = NULL; + char *q = NULL; + + if (*args[cur_arg]) { + if (*args[cur_arg + 1]) { + p = args[cur_arg]; + } else { + q = args[cur_arg]; + } + } + + if (p) { /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ + return 1; + } + if (q) { /* { dg-bogus "check of 'q' for NULL after already dereferencing it" } */ + return 2; + } + return 0; +} + +int test_3 (void **pp, int flag) +{ + void *p = NULL; + if (*pp && flag) + p = pp; + if (p) /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ + return 1; + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c new file mode 100644 index 0000000..7123cf5 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c @@ -0,0 +1,171 @@ +/* Reduced from haproxy-2.7.1: src/tcpcheck.c. */ + +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +typedef __SIZE_TYPE__ size_t; + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +extern void *calloc(size_t __nmemb, size_t __size) + __attribute__((__nothrow__, __leaf__)) __attribute__((__malloc__)) + __attribute__((__alloc_size__(1, 2))); +extern char *strdup(const char *__s) __attribute__((__nothrow__, __leaf__)) +__attribute__((__malloc__)) __attribute__((__nonnull__(1))); +extern char *strstr(const char *__haystack, const char *__needle) + __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) + __attribute__((__nonnull__(1, 2))); +extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__)) +__attribute__((__pure__)) __attribute__((__nonnull__(1))); +struct list { + struct list *n; + struct list *p; +}; +struct buffer { + size_t size; + char *area; + size_t data; + size_t head; +}; +struct proxy; +struct ist { + char *ptr; + size_t len; +}; +static inline int isttest(const struct ist ist) { return ist.ptr != NULL; } + +enum http_meth_t { + HTTP_METH_OPTIONS, + /* [...snip...] */ +} __attribute__((packed)); + +struct http_meth { + enum http_meth_t meth; + struct buffer str; +}; +enum tcpcheck_send_type { + /* [...snip...] */ + TCPCHK_SEND_HTTP, +}; +enum tcpcheck_rule_type { + TCPCHK_ACT_SEND = 0, + /* [...snip...] */ +}; +struct tcpcheck_http_hdr { + struct ist name; + struct list value; + struct list list; +}; +struct tcpcheck_send { + enum tcpcheck_send_type type; + union { + /* [...snip...] */ + struct { + unsigned int flags; + struct http_meth meth; + union { + struct ist uri; + /* [...snip...] */ + }; + struct ist vsn; + struct list hdrs; + /* [...snip...] */ + } http; + }; +}; +struct tcpcheck_rule { + /* [...snip...] */ + enum tcpcheck_rule_type action; + /* [...snip...] */ + union { + /* [...snip...] */ + struct tcpcheck_send send; + /* [...snip...] */ + }; +}; +enum http_meth_t find_http_meth(const char *str, const int len); +void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool); +void free_tcpcheck_http_hdr(struct tcpcheck_http_hdr *hdr); + +#define ist(str) ({ \ + char *__x = (char *) ((void *)(str)); \ + (struct ist){ \ + .ptr = __x, \ + .len = __builtin_constant_p(str) ? \ + ((void *)str == (void *)0) ? 0 : \ + __builtin_strlen(__x) : \ + ({ \ + size_t __l = 0; \ + if (__x) for (__l--; __x[++__l]; ) ; \ + __l; \ + }) \ + }; \ +}) + +struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg, + struct proxy *px, char **errmsg) { + struct tcpcheck_rule *chk = NULL; + struct tcpcheck_http_hdr *hdr = NULL; + char *meth = NULL, *uri = NULL, *vsn = NULL; + char *hdrs, *body; + + hdrs = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2], "\r\n") : NULL); + body = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2], "\r\n\r\n") : NULL); + if (hdrs || body) { + /* [...snip...] */ + goto error; + } + + chk = (struct tcpcheck_rule *) calloc(1, sizeof(*chk)); + if (!chk) { + /* [...snip...] */ + goto error; + } + chk->action = TCPCHK_ACT_SEND; + chk->send.type = TCPCHK_SEND_HTTP; + chk->send.http.flags |= 0x0004; + chk->send.http.meth.meth = HTTP_METH_OPTIONS; + ((&chk->send.http.hdrs)->n = (&chk->send.http.hdrs)->p = + (&chk->send.http.hdrs)); + + if (*args[cur_arg]) { + if (!*args[cur_arg + 1]) + uri = args[cur_arg]; + else + meth = args[cur_arg]; + } + if (*args[cur_arg + 1]) + uri = args[cur_arg + 1]; + if (*args[cur_arg + 2]) + vsn = args[cur_arg + 2]; + + if (meth) { /* { dg-bogus "check of 'meth' for NULL after already dereferencing it" } */ + chk->send.http.meth.meth = find_http_meth(meth, strlen(meth)); + chk->send.http.meth.str.area = strdup(meth); + chk->send.http.meth.str.data = strlen(meth); + if (!chk->send.http.meth.str.area) { + /* [...snip...] */ + goto error; + } + } + if (uri) { + chk->send.http.uri = ist(strdup(uri)); + if (!isttest(chk->send.http.uri)) { + /* [...snip...] */ + goto error; + } + } + if (vsn) { /* { dg-bogus "check of 'vsn' for NULL after already dereferencing it" } */ + chk->send.http.vsn = ist(strdup(vsn)); + if (!isttest(chk->send.http.vsn)) { + /* [...snip...] */ + goto error; + } + } + return chk; + +error: + free_tcpcheck_http_hdr(hdr); + free_tcpcheck(chk, 0); + return NULL; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c new file mode 100644 index 0000000..1d28e10 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c @@ -0,0 +1,92 @@ +/* Reduced from haproxy-2.7.1's cfgparse.c. */ + +typedef __SIZE_TYPE__ size_t; + +extern int +strcmp(const char* __s1, const char* __s2) + __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) + __attribute__((__nonnull__(1, 2))); + +extern int +strncmp(const char* __s1, const char* __s2, size_t __n) + __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) + __attribute__((__nonnull__(1, 2))); + +enum +{ + /* [...snip...] */ + _ISdigit = ((3) < 8 ? ((1 << (3)) << 8) : ((1 << (3)) >> 8)), + /* [...snip...] */ +}; + +extern const unsigned short int** +__ctype_b_loc(void) __attribute__((__nothrow__, __leaf__)) + __attribute__((__const__)); + +unsigned int str2uic(const char* s); + +char* +memprintf(char** out, const char* format, ...) + __attribute__((format(printf, 2, 3))); + +int +parse_process_number(const char* arg, + unsigned long* proc, + int max, + int* autoinc, + char** err) +{ + if (autoinc) { + *autoinc = 0; + if (strncmp(arg, "auto:", 5) == 0) { + arg += 5; + *autoinc = 1; + } + } + + if (strcmp(arg, "all") == 0) /* { dg-bogus "pointer 'dash' is dereferenced here" } */ + *proc |= ~0UL; + else if (strcmp(arg, "odd") == 0) + *proc |= ~0UL / 3UL; + else if (strcmp(arg, "even") == 0) + *proc |= (~0UL / 3UL) << 1; + else { + const char *p, *dash = (const char *) ((void*)0); + unsigned int low, high; + + for (p = arg; *p; p++) { + if (*p == '-' && !dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */ + dash = p; + else if (!((*__ctype_b_loc())[(int)(((unsigned char)*p))] & + (unsigned short int)_ISdigit)) { + memprintf(err, "'%s' is not a valid number/range.", arg); + return -1; + } + } + + low = high = str2uic(arg); + if (dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */ + high = ((!*(dash + 1)) ? max : str2uic(dash + 1)); + + if (high < low) { + unsigned int swap = low; + low = high; + high = swap; + } + + if (low < 1 || low > max || high > max) { + memprintf(err, + "'%s' is not a valid number/range." + " It supports numbers from 1 to %d.\n", + arg, + max); + return 1; + } + + for (; low <= high; low++) + *proc |= 1UL << (low - 1); + } + *proc &= ~0UL >> (((unsigned int)sizeof(long) * 8) - max); + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c new file mode 100644 index 0000000..add7731 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c @@ -0,0 +1,154 @@ +/* Reduced from linux-5.10.162's drivers-base-bus.c */ +/* { dg-additional-options "-fno-delete-null-pointer-checks -O2" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +typedef unsigned int __kernel_size_t; +typedef int __kernel_ssize_t; +typedef __kernel_size_t size_t; +typedef __kernel_ssize_t ssize_t; + +struct list_head +{ + struct list_head *next, *prev; +}; + +struct kobject +{ + /* [...snip...] */ +}; + +struct attribute +{ + /* [...snip...] */ +}; + +static inline +void +sysfs_remove_file_ns(struct kobject* kobj, + const struct attribute* attr, + const void* ns) +{ +} + +static inline +void +sysfs_remove_file(struct kobject* kobj, const struct attribute* attr) +{ + sysfs_remove_file_ns(kobj, attr, NULL); +} + +extern struct kobject* +kobject_get(struct kobject* kobj); + +extern void +kobject_put(struct kobject* kobj); + +struct kset +{ + struct list_head list; + /* [...snip...] */ + struct kobject kobj; + /* [...snip...] */ +} __attribute__((__designated_init__)); + +static inline +struct kset* +to_kset(struct kobject* kobj) +{ + return kobj ? ({ + char* __mptr = (char*)(kobj); + ((struct kset*)(__mptr - __builtin_offsetof(struct kset, kobj))); + }) : NULL; +} + +static inline +struct kset* +kset_get(struct kset* k) +{ + return k ? to_kset(kobject_get(&k->kobj)) : NULL; +} + +static inline +void +kset_put(struct kset* k) +{ + kobject_put(&k->kobj); +} + +struct bus_type +{ + /* [...snip...] */ + struct device* dev_root; + /* [...snip...] */ + struct subsys_private* p; + /* [...snip...] */ +}; + +struct bus_attribute +{ + struct attribute attr; + /* [...snip...] */ +}; + +extern void +device_unregister(struct device* dev); + +struct subsys_private +{ + struct kset subsys; + /* [...snip...] */ +}; + +static struct bus_type* +bus_get(struct bus_type* bus) +{ + if (bus) { /* { dg-bogus "check of 'bus' for NULL after already dereferencing it" } */ + kset_get(&bus->p->subsys); + return bus; + } + return NULL; +} + +static void +bus_put(struct bus_type* bus) +{ + if (bus) + kset_put(&bus->p->subsys); +} + +void +bus_remove_file(struct bus_type* bus, struct bus_attribute* attr) +{ + if (bus_get(bus)) { + sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); + bus_put(bus); + } +} + +extern ssize_t +drivers_autoprobe_show(struct bus_type* bus, char* buf); + +extern ssize_t +drivers_autoprobe_store(struct bus_type* bus, const char* buf, size_t count); + +extern struct bus_attribute bus_attr_drivers_autoprobe; + +static void +remove_probe_files(struct bus_type* bus) +{ + bus_remove_file(bus, &bus_attr_drivers_autoprobe); + /* [...snip...] */ +} + +void +bus_unregister(struct bus_type* bus) +{ + /* [...snip...] */ + if (bus->dev_root) /* { dg-bogus "pointer 'bus' is dereferenced here" } */ + device_unregister(bus->dev_root); + /* [...snip...] */ + remove_probe_files(bus); + /* [...snip...] */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c new file mode 100644 index 0000000..c9be77c --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c @@ -0,0 +1,45 @@ +/* Fixed in r7-2945-g61f46d0e6dd568. + Simplified from gcc/ipa-devirt.c. */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +typedef struct odr_type_d { + /* .... */ + int id; + /* .... */ +} *odr_type; +static odr_type **odr_types_ptr; +#define odr_types (*odr_types_ptr) /* { dg-message "pointer 'odr_types_ptr' is dereferenced here" } */ + +int cond, other_cond; + +odr_type some_logic (); + +odr_type +get_odr_type (/* ... */) +{ + /* .... */ + odr_type val = NULL; + /* .... */ + + val = some_logic (); + + /* .... */ + if (cond) + { + /* .... */ + } + else if (other_cond) + { + odr_types[val->id] = 0; /* { dg-message "in expansion of macro 'odr_types'" } */ + /* .... */ + if (odr_types_ptr) /* { dg-warning "check of 'odr_types_ptr' for NULL after already dereferencing it" } */ + { + /* .... */ + val->id = 42; + } + /* .... */ + } + return val; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/exec-1.c b/gcc/testsuite/c-c++-common/analyzer/exec-1.c new file mode 100644 index 0000000..25b8899 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/exec-1.c @@ -0,0 +1,49 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +#ifdef __cplusplus + #define CONST_CAST(type) const_cast +#else + #define CONST_CAST(type) +#endif + +extern int execl(const char *pathname, const char *arg, ...); +extern int execlp(const char *file, const char *arg, ...); +extern int execle(const char *pathname, const char *arg, ...); +extern int execv(const char *pathname, char *const argv[]); +extern int execvp(const char *file, char *const argv[]); +extern int execvpe(const char *file, char *const argv[], char *const envp[]); + +int test_execl_ls_al () +{ + return execl ("/usr/bin/ls", "ls", "-al", NULL); +} + +int test_execlpl_ls_al () +{ + return execlp ("ls", "ls", "-al", NULL); +} + +int test_execle_ls_al () +{ + char * env[3] = {CONST_CAST(char *)("FOO=BAR"), CONST_CAST(char *)("BAZ"), NULL}; + return execl ("/usr/bin/ls", "ls", "-al", NULL, env); +} + +int test_execv_ls_al () +{ + char * argv[3] = {CONST_CAST(char *)("ls"), CONST_CAST(char *)("-al"), NULL}; + return execv ("/usr/bin/ls", argv); +} + +int test_execvp_ls_al () +{ + char *argv[3] = {CONST_CAST(char *)("ls"), CONST_CAST(char *)("-al"), NULL}; + return execvp ("ls", argv); +} + +int test_execvpe_ls_al () +{ + char *env[3] = {CONST_CAST(char *)("FOO=BAR"), CONST_CAST(char *)("BAZ"), NULL}; + char *argv[3] = {CONST_CAST(char *)("ls"), CONST_CAST(char *)("-al"), NULL}; + return execvpe ("ls", argv, env); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c new file mode 100644 index 0000000..2fcd064 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c @@ -0,0 +1,138 @@ +/* Reduced and adapted from Linux: fs/proc/inode.c: proc_reg_open + (GPL v2.0). */ + +/* Types. */ + +typedef unsigned char u8; +#ifndef __cplusplus +typedef _Bool bool; +#endif +typedef unsigned int gfp_t; + +struct file; +struct kmem_cache; +struct proc_dir_entry; + +struct inode { /* [...snip...] */ }; + +enum { + PROC_ENTRY_PERMANENT = 1U << 0, +}; + +struct proc_ops { + /* [...snip...] */ + int (*proc_open)(struct inode *, struct file *); + /* [...snip...] */ + int (*proc_release)(struct inode *, struct file *); + /* [...snip...] */ +}; + +struct proc_dir_entry { + /* [...snip...] */ + struct completion *pde_unload_completion; + /* [...snip...] */ + union { + const struct proc_ops *proc_ops; + const struct file_operations *proc_dir_ops; + }; + /* [...snip...] */ + u8 flags; + /* [...snip...] */ +}; + +struct pde_opener { + /* [...snip...] */ + struct file *file; + /* [...snip...] */ +}; + +struct proc_inode { + /* [...snip...] */ + struct proc_dir_entry *pde; + /* [...snip...] */ + struct inode vfs_inode; +}; + +/* Data. */ + +static struct kmem_cache *pde_opener_cache __attribute__((__section__(".data..ro_after_init"))); + +/* Functions. */ + +void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __attribute__((__malloc__)); +void kmem_cache_free(struct kmem_cache *, void *); + +static inline bool pde_is_permanent(const struct proc_dir_entry *pde) +{ + return pde->flags & PROC_ENTRY_PERMANENT; +} + +static inline struct proc_inode *PROC_I(const struct inode *inode) +{ + char *__mptr = (char *)(inode); + return ((struct proc_inode *)(__mptr - __builtin_offsetof(struct proc_inode, vfs_inode))); +} + +static inline struct proc_dir_entry *PDE(const struct inode *inode) +{ + return PROC_I(inode)->pde; +} + +/* We don't want to emit bogus use of uninitialized value 'pdeo' + warnings from -Wanalyzer-use-of-uninitialized-value in this function; + these would require following infeasible paths in which "release" is + first NULL (to avoid the initialization of "pdeo") and then is non-NULL + (to access "pdeo"). + + "release" is sufficiently complicated in this function to hit the + complexity limit for symbolic values during enode exploration. */ + +static int proc_reg_open(struct inode *inode, struct file *file) +{ + struct proc_dir_entry *pde = PDE(inode); + int rv = 0; + + + int (*open)(struct inode *, struct file *); + int (*release)(struct inode *, struct file *); + + struct pde_opener *pdeo; + + if (pde_is_permanent(pde)) { + open = pde->proc_ops->proc_open; + if (open) + rv = open(inode, file); + return rv; + } + + /* [...snip...] */ + + release = pde->proc_ops->proc_release; + if (release) { + pdeo = (struct pde_opener *) kmem_cache_alloc(pde_opener_cache, + ((( gfp_t)(0x400u|0x800u)) + | (( gfp_t)0x40u) + | (( gfp_t)0x80u))); + if (!pdeo) { + rv = -12; + goto out_unuse; + } + } + + open = pde->proc_ops->proc_open; + if (open) + rv = open(inode, file); + + if (release) { + if (rv == 0) { + + pdeo->file = file; /* { dg-bogus "uninit" } */ + /* [...snip...] */ + } else + kmem_cache_free(pde_opener_cache, pdeo); /* { dg-bogus "uninit" } */ + } + +out_unuse: + /* [...snip...] */ + return rv; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/fields.c b/gcc/testsuite/c-c++-common/analyzer/fields.c new file mode 100644 index 0000000..1859530 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/fields.c @@ -0,0 +1,41 @@ +typedef __SIZE_TYPE__ size_t; + +extern size_t strlen (const char *__s) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__pure__)) + __attribute__ ((__nonnull__ (1))); + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) ; + +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +typedef struct _krb5_data { + unsigned int length; + char *data; +} krb5_data; + +typedef struct _krb5_error { + krb5_data text; +} krb5_error; + +extern const char *error_message (int); + +int +recvauth_common (int problem) +{ + if (problem) { + krb5_error error; + const char *message = error_message(problem); + error.text.length = strlen(message) + 1; + if (!(error.text.data = (char *) malloc(error.text.length))) { + goto cleanup; + } + free(error.text.data); + } + + cleanup: + return problem; /* { dg-bogus "leak" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c new file mode 100644 index 0000000..2b83978 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c @@ -0,0 +1,42 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +void calling_null_fn_ptr_1 (void) +{ + void (*fn_ptr) (void) = NULL; + fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +int calling_null_fn_ptr_2 (void) +{ + int (*fn_ptr) (void) = NULL; + return fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +typedef void (*void_void_fn_ptr) (void); + +void calling_const_fn_ptr (void) +{ + void_void_fn_ptr fn_ptr = (void_void_fn_ptr)0xffd2; + return fn_ptr (); +} + +void skipping_init (int flag) +{ + void_void_fn_ptr fn_ptr = NULL; + if (flag) /* { dg-message "branch" } */ + fn_ptr = (void_void_fn_ptr)0xffd2; + fn_ptr (); /* { dg-warning "jump through null pointer" } */ +} + +struct callbacks +{ + void_void_fn_ptr on_redraw; + void_void_fn_ptr on_cleanup; +}; + +void test_callbacks (void) +{ + struct callbacks cb; + __builtin_memset (&cb, 0, sizeof (cb)); + cb.on_cleanup (); /* { dg-warning "jump through null pointer" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c new file mode 100644 index 0000000..26fc8d2 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c @@ -0,0 +1,147 @@ +/* Reduced from qemu-7.2.0's qobject/json-parser.c, which + is licensed under LGPLv2.1 or later. */ + +/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +typedef __builtin_va_list va_list; + +typedef struct _GQueue GQueue; +typedef struct Error Error; +typedef struct QList QList; +typedef struct QObject QObject; + +struct QObjectBase_ { + /* [...snip...] */ +}; + + +struct QObject { + struct QObjectBase_ base; +}; + +#define QOBJECT(obj) ((QObject *)obj) +#define qobject_unref(OBJ) /* [...snip...] */ + +typedef struct QTailQLink { + void *tql_next; + struct QTailQLink *tql_prev; +} QTailQLink; + +struct QList { + struct QObjectBase_ base; + union { + struct QListEntry *tqh_first; + QTailQLink tqh_circ; + } head; +}; +QList *qlist_new(void); +void qlist_append_obj(QList *qlist, QObject *obj); + +typedef enum json_token_type { + /* [...snip...] */ + JSON_LSQUARE, + JSON_RSQUARE, + /* [...snip...] */ + JSON_COMMA, + /* [...snip...] */ + JSON_KEYWORD, + /* [...snip...] */ +} JSONTokenType; +typedef struct JSONToken JSONToken; + +struct JSONToken { + JSONTokenType type; + int x; + int y; + char str[]; +}; + +typedef struct JSONParserContext { + Error *err; + JSONToken *current; + GQueue *buf; + va_list *ap; +} JSONParserContext; +static QObject *parse_value(JSONParserContext *ctxt); + +JSONToken *parser_context_pop_token(JSONParserContext *ctxt); +JSONToken *parser_context_peek_token(JSONParserContext *ctxt); + +static QObject *parse_array(JSONParserContext *ctxt) { + QList *list = NULL; + JSONToken *token, *peek; + + token = parser_context_pop_token(ctxt); + + list = qlist_new(); + + peek = parser_context_peek_token(ctxt); + if (peek == NULL) { + goto out; + } + + if (peek->type != JSON_RSQUARE) { + QObject *obj; + + obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ + if (obj == NULL) { + goto out; + } + + qlist_append_obj(list, obj); + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + goto out; + } + + while (token->type != JSON_RSQUARE) { + if (token->type != JSON_COMMA) { + goto out; + } + + obj = parse_value(ctxt); + if (obj == NULL) { + goto out; + } + + qlist_append_obj(list, obj); + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + goto out; + } + } + } else { + (void)parser_context_pop_token(ctxt); + } + + return QOBJECT(list); + +out: + qobject_unref(list); + return NULL; +} + +QObject *parse_keyword(JSONParserContext *ctxt); + +QObject *parse_value(JSONParserContext *ctxt) { + JSONToken *token; + + token = parser_context_peek_token(ctxt); + if (token == NULL) { + return NULL; + } + + switch (token->type) { + case JSON_LSQUARE: + return parse_array(ctxt); /* { dg-bogus "infinite recursion" } */ + case JSON_KEYWORD: + return parse_keyword(ctxt); + default: + return NULL; + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c new file mode 100644 index 0000000..d483d7e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c @@ -0,0 +1,113 @@ +struct st1; + +int foo (struct st1 *p); +int bar (struct st1 *p); + +void test_1 (struct st1 *p) +{ + test_1 (p); /* { dg-warning "infinite recursion" } */ +} + +void test_2_if (struct st1 *p) +{ + if (foo (p)) + test_2_if (p); /* { dg-bogus "infinite recursion" } */ +} + +void test_2_switch (struct st1 *p) +{ + switch (foo (p)) + { + case 0 ... 9: + test_2_switch (p); /* { dg-bogus "infinite recursion" } */ + break; + default: + break; + } +} + +void test_2_if_compound (struct st1 *p) +{ + if ((foo (p) + bar (p)) >= 0) + test_2_if_compound (p); /* { dg-bogus "infinite recursion" } */ +} + +void test_3 (struct st1 *p) +{ + foo (p); + test_3 (p); /* { dg-warning "infinite recursion" } */ + /* The content of *p never affects control flow, so we should + report this. */ +} + +struct st2 +{ + int i; +}; + +void test_4 (struct st2 *p) +{ + if (p->i > 0) + test_4 (p); /* { dg-warning "infinite recursion" } */ +} + +void test_5 (struct st2 *p) +{ + if (p->i-- > 0) + test_5 (p); /* { dg-bogus "infinite recursion" } */ +} + +/* Mixtures of heap allocation and recursion. It's not clear what we + should do for such cases, but make sure we don't ICE. */ + +void test_6 (struct st2 *p) +{ + struct st2 *q = (struct st2 *) __builtin_malloc (p->i); + if (!q) + return; + q->i = p->i; + test_6 (q); + __builtin_free (q); +} + +void test_7 (struct st2 *p) +{ + struct st2 *q = (struct st2 *) __builtin_malloc (p->i); + q->i = p->i; /* { dg-warning "dereference of possibly-NULL 'q'" } */ + test_7 (q); + __builtin_free (q); +} + +void test_switch_1 (int i) +{ + int j; + switch (i) + { + case 0: + j = 1066; + break; + case 1: + j = 1776; + break; + default: + j = 1492; + break; + } + test_switch_1 (j); /* { dg-warning "infinite recursion" "" { xfail *-*-* } } */ +} + +void test_switch_2 (int i) +{ + switch (i) + { + case 0: + test_switch_2 (1066); + break; + case 1: + test_switch_2 (1776); + break; + default: + test_switch_2 (1492); /* { dg-warning "infinite recursion" "" { xfail *-*-* } } */ + break; + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c new file mode 100644 index 0000000..64ea62e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c @@ -0,0 +1,324 @@ +/* Reduced from qemu-7.2.0's qobject/json-parser.c, which + is licensed under LGPLv2.1 or later. */ + +/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +typedef __builtin_va_list va_list; +typedef __SIZE_TYPE__ size_t; + +typedef struct _GString GString; +typedef struct _GQueue GQueue; +typedef struct Error Error; +typedef struct QDict QDict; +typedef struct QList QList; +typedef struct QObject QObject; +typedef struct QString QString; + +typedef enum QType { + /* [...snip...] */ + QTYPE_QSTRING, + /* [...snip...] */ +} QType; + +struct QObjectBase_ { + QType type; +}; + +struct QObject { + struct QObjectBase_ base; +}; + +#define QOBJECT(obj) ((QObject *)obj) +#define qobject_unref(OBJ) /* [...snip...] */ + +void qobject_ref_impl(QObject *obj); +QType qobject_type(const QObject *obj); +QObject *qobject_check_type(const QObject *obj, QType type); + +typedef struct QTailQLink { + void *tql_next; + struct QTailQLink *tql_prev; +} QTailQLink; + +typedef struct QDictEntry { + char *key; + QObject *value; + struct { + struct QDictEntry *le_next; + struct QDictEntry **le_prev; + } next; +} QDictEntry; + +struct QDict { + struct QObjectBase_ base; + size_t size; + struct { + struct QDictEntry *lh_first; + } table[512]; +}; + +QDict *qdict_new(void); +void qdict_put_obj(QDict *qdict, const char *key, QObject *value); +int qdict_haskey(const QDict *qdict, const char *key); +typedef struct QListEntry { + QObject *value; + union { + struct QListEntry *tqe_next; + QTailQLink tqe_circ; + } next; +} QListEntry; + +struct QList { + struct QObjectBase_ base; + union { + struct QListEntry *tqh_first; + QTailQLink tqh_circ; + } head; +}; +QList *qlist_new(void); +void qlist_append_obj(QList *qlist, QObject *obj); + +struct QString { + struct QObjectBase_ base; + const char *string; +}; +QString *qstring_from_str(const char *str); +const char *qstring_get_str(const QString *qstring); + +typedef enum json_token_type { + JSON_ERROR = 0, + + JSON_LCURLY = 100, + JSON_MIN = JSON_LCURLY, + JSON_RCURLY, + JSON_LSQUARE, + JSON_RSQUARE, + JSON_COLON, + JSON_COMMA, + JSON_INTEGER, + JSON_FLOAT, + JSON_KEYWORD, + JSON_STRING, + JSON_INTERP, + JSON_END_OF_INPUT, + JSON_MAX = JSON_END_OF_INPUT +} JSONTokenType; +typedef struct JSONToken JSONToken; + +struct JSONToken { + JSONTokenType type; + int x; + int y; + char str[]; +}; + +typedef struct JSONParserContext { + Error *err; + JSONToken *current; + GQueue *buf; + va_list *ap; +} JSONParserContext; +static QObject *parse_value(JSONParserContext *ctxt); + +void __attribute__((__format__(gnu_printf, 3, 4))) +parse_error(JSONParserContext *ctxt, JSONToken *token, const char *msg, ...); + +JSONToken *parser_context_pop_token(JSONParserContext *ctxt); +JSONToken *parser_context_peek_token(JSONParserContext *ctxt); + +static int parse_pair(JSONParserContext *ctxt, QDict *dict) { + QObject *key_obj = NULL; + QString *key; + QObject *value; + JSONToken *peek, *token; + + peek = parser_context_peek_token(ctxt); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + key_obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ + key = ((QString *)qobject_check_type(key_obj, QTYPE_QSTRING)); + if (!key) { + parse_error(ctxt, peek, "key is not a string in object"); + goto out; + } + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + if (token->type != JSON_COLON) { + parse_error(ctxt, token, "missing : in object pair"); + goto out; + } + + value = parse_value(ctxt); + if (value == NULL) { + parse_error(ctxt, token, "Missing value in dict"); + goto out; + } + + if (qdict_haskey(dict, qstring_get_str(key))) { + parse_error(ctxt, token, "duplicate key"); + goto out; + } + + qdict_put_obj(dict, qstring_get_str(key), value); + + qobject_unref(key_obj); + return 0; + +out: + qobject_unref(key_obj); + return -1; +} + +static QObject *parse_object(JSONParserContext *ctxt) { + QDict *dict = NULL; + JSONToken *token, *peek; + + token = parser_context_pop_token(ctxt); + + dict = qdict_new(); + + peek = parser_context_peek_token(ctxt); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + if (peek->type != JSON_RCURLY) { + if (parse_pair(ctxt, dict) == -1) { + goto out; + } + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + while (token->type != JSON_RCURLY) { + if (token->type != JSON_COMMA) { + parse_error(ctxt, token, "expected separator in dict"); + goto out; + } + + if (parse_pair(ctxt, dict) == -1) { + goto out; + } + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + } + } else { + (void)parser_context_pop_token(ctxt); + } + + return QOBJECT(dict); + +out: + qobject_unref (dict); + return NULL; +} + +static QObject *parse_array(JSONParserContext *ctxt) { + QList *list = NULL; + JSONToken *token, *peek; + + token = parser_context_pop_token(ctxt); + + list = qlist_new(); + + peek = parser_context_peek_token(ctxt); + if (peek == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + if (peek->type != JSON_RSQUARE) { + QObject *obj; + + obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ + if (obj == NULL) { + parse_error(ctxt, token, "expecting value"); + goto out; + } + + qlist_append_obj(list, obj); + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + + while (token->type != JSON_RSQUARE) { + if (token->type != JSON_COMMA) { + parse_error(ctxt, token, "expected separator in list"); + goto out; + } + + obj = parse_value(ctxt); + if (obj == NULL) { + parse_error(ctxt, token, "expecting value"); + goto out; + } + + qlist_append_obj(list, obj); + + token = parser_context_pop_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + goto out; + } + } + } else { + (void)parser_context_pop_token(ctxt); + } + + return QOBJECT(list); + +out: + qobject_unref(list); + return NULL; +} + +QObject *parse_keyword(JSONParserContext *ctxt); +QObject *parse_literal(JSONParserContext *ctxt); + +QObject *parse_value(JSONParserContext *ctxt) { + JSONToken *token; + + token = parser_context_peek_token(ctxt); + if (token == NULL) { + parse_error(ctxt, NULL, "premature EOI"); + return NULL; + } + + switch (token->type) { + case JSON_LCURLY: + return parse_object(ctxt); /* { dg-bogus "infinite recursion" } */ + case JSON_LSQUARE: + return parse_array(ctxt); /* { dg-bogus "infinite recursion" } */ + case JSON_INTEGER: + case JSON_FLOAT: + case JSON_STRING: + return parse_literal(ctxt); + case JSON_KEYWORD: + return parse_keyword(ctxt); + default: + parse_error(ctxt, token, "expecting value"); + return NULL; + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/init.c b/gcc/testsuite/c-c++-common/analyzer/init.c new file mode 100644 index 0000000..cd3c16f --- /dev/null +++ b/gcc/testsuite/c-c++-common/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 "../../gcc.dg/analyzer/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] = {{.x = 3, .y = 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_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/c-c++-common/analyzer/inlining-3-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c new file mode 100644 index 0000000..fbd20e9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c @@ -0,0 +1,99 @@ +/* As per inlining-3.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" +typedef __SIZE_TYPE__ size_t; + +struct input_file_st +{ + char inpname[1]; +}; + +typedef struct input_file_st input_file; + +static inline const char* +get_input_file_name (const input_file *inpf) +{ + if (inpf) + return inpf->inpname; + return NULL; +} + +size_t +test (const input_file *inpf) +{ + const char *f = get_input_file_name (inpf); + return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ +} + +/* { dg-begin-multiline-output "" } + return __builtin_strlen (f); + ^~~~~~~~~~~~~~~~~~~~ + 'test': events 1-2 (depth 1) + | + | test (const input_file *inpf) + | ^~~~ + | | + | (1) entry to 'test' + | + | const char *f = get_input_file_name (inpf); + | ~ + | | + | (2) inlined call to 'get_input_file_name' from 'test' + | + +--> 'get_input_file_name': event 3 (depth 2) + | + | if (inpf) + | ^ + | | + | (3) following 'false' branch (when 'inpf' is NULL)... + | + <------+ + | + 'test': events 4-5 (depth 1) + | + | return __builtin_strlen (f); + | ^~~~~~~~~~~~~~~~~~~~ + | | + | (4) ...to here + | (5) argument 1 ('') NULL where non-null expected + | + { dg-end-multiline-output "" { target c } } */ + + +/* { dg-begin-multiline-output "" } + return __builtin_strlen (f); + ~~~~~~~~~~~~~~~~~^~~ + 'size_t test(const input_file*)': events 1-2 (depth 1) + | + | test (const input_file *inpf) + | ^~~~ + | | + | (1) entry to 'test' + | + | const char *f = get_input_file_name (inpf); + | ~ + | | + | (2) inlined call to 'get_input_file_name' from 'test' + | + +--> 'const char* get_input_file_name(const input_file*)': event 3 (depth 2) + | + | if (inpf) + | ^~ + | | + | (3) following 'false' branch (when 'inpf' is NULL)... + | + <------+ + | + 'size_t test(const input_file*)': events 4-5 (depth 1) + | + | return __builtin_strlen (f); + | ~~~~~~~~~~~~~~~~~^~~ + | | + | (4) ...to here + | (5) argument 1 ('') NULL where non-null expected + | + { dg-end-multiline-output "" { target c++ } } */ \ No newline at end of file diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-3.c b/gcc/testsuite/c-c++-common/analyzer/inlining-3.c new file mode 100644 index 0000000..0345585b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-3.c @@ -0,0 +1,34 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" +typedef __SIZE_TYPE__ size_t; + + +struct input_file_st +{ + char inpname[1]; +}; + +typedef struct input_file_st input_file; + +static inline const char* +get_input_file_name (const input_file *inpf) +{ + if (inpf) + /* { dg-message "following 'false' branch \\(when 'inpf' is NULL\\)\\.\\.\\. \\(fndecl 'get_input_file_name', depth 2\\)" "" { target c } .-1 } */ + /* { dg-message "following 'false' branch \\(when 'inpf' is NULL\\)\\.\\.\\. \\(fndecl 'const char\\* get_input_file_name\\(const input_file\\*\\)', depth 2\\)" "" { target c++ } .-2 } */ + return inpf->inpname; + return NULL; +} + +size_t +test (const input_file *inpf) +{ + const char *f = get_input_file_name (inpf); + return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ + /* { dg-message "NULL where non-null expected \\(fndecl 'test', depth 1\\)" "message" { target c } .-1 } */ + /* { dg-message "NULL where non-null expected \\(fndecl 'size_t test\\(const input_file\\*\\)', depth 1\\)" "message" { target c++ } .-2 } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c new file mode 100644 index 0000000..c870a9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c @@ -0,0 +1,117 @@ +/* As per inlining-4.c, but testing how the ASCII art version of + the path looks. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ +/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +static inline const char* +inner (int flag) +{ + if (flag) + return NULL; + return "foo"; +} + +static inline const char* +middle (int flag) +{ + return inner (flag); +} + +char +outer (int flag) +{ + return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ +} + +/* { dg-begin-multiline-output "" } + return *middle (flag); + ^~~~~~~~~~~~~~ + 'outer': events 1-2 (depth 1) + | + | outer (int flag) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | return *middle (flag); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'middle': event 3 (depth 2) + | + | return inner (flag); + | ^ + | | + | (3) inlined call to 'inner' from 'middle' + | + +--> 'inner': event 4 (depth 3) + | + | if (flag) + | ^ + | | + | (4) following 'true' branch (when 'flag != 0')... + | + <-------------+ + | + 'outer': event 5 (depth 1) + | + |cc1: + | (5): ...to here + | + 'outer': event 6 (depth 1) + | + | return *middle (flag); + | ^~~~~~~~~~~~~~ + | | + | (6) dereference of NULL '' + | + { dg-end-multiline-output "" { target c } } */ +/* { dg-begin-multiline-output "" } + return *middle (flag); + ^ + 'char outer(int)': events 1-2 (depth 1) + | + | outer (int flag) + | ^~~~~ + | | + | (1) entry to 'outer' + | + | return *middle (flag); + | ~ + | | + | (2) inlined call to 'middle' from 'outer' + | + +--> 'const char* middle(int)': event 3 (depth 2) + | + | return inner (flag); + | ^ + | | + | (3) inlined call to 'inner' from 'middle' + | + +--> 'const char* inner(int)': event 4 (depth 3) + | + | if (flag) + | ^~ + | | + | (4) following 'true' branch (when 'flag != 0')... + | + <-------------+ + | + 'char outer(int)': event 5 (depth 1) + | + |cc1plus: + | (5): ...to here + | + 'char outer(int)': event 6 (depth 1) + | + | return *middle (flag); + | ^ + | | + | (6) dereference of NULL '' + | + { dg-end-multiline-output "" { target c++ } } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/inlining-4.c b/gcc/testsuite/c-c++-common/analyzer/inlining-4.c new file mode 100644 index 0000000..85b4244 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/inlining-4.c @@ -0,0 +1,30 @@ +/* Verify that we can reconstruct fndecl and stack depth information + after early inlining. */ + +/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +static inline const char* +inner (int flag) +{ + if (flag) + /* { dg-message "following 'true' branch \\(when 'flag != 0'\\)\\.\\.\\. \\(fndecl 'inner', depth 3\\)" "" { target c } .-1 } */ + /* { dg-message "following 'true' branch \\(when 'flag != 0'\\)\\.\\.\\. \\(fndecl 'const char\\* inner\\(int\\)', depth 3\\)" "" { target c++ } .-2 } */ + return NULL; + return "foo"; +} + +static inline const char* +middle (int flag) +{ + return inner (flag); +} + +char +outer (int flag) +{ + return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ + /* { dg-message "\\(fndecl 'outer', depth 1\\)" "message" { target c } .-1 } */ + /* { dg-message "\\(fndecl 'char outer\\(int\\)', depth 1\\)" "message" { target c++ } .-2 } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c new file mode 100644 index 0000000..a37aa59 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c @@ -0,0 +1,33 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +#define LEN 64 + +char ** +epystr_explode(const char *delim, char *str) +{ + char **out = NULL; + int i; + + if (str == NULL || delim == NULL) + return NULL; + + out = (char **) __builtin_malloc(LEN * sizeof(char *)); + if (out == NULL) + return NULL; + + for (i = 0; i < LEN; i++) { + out[i] = __builtin_strdup("bla"); + if (out[i] == NULL) /* { dg-bogus "leak" } */ + goto freem; + } + return out; + +freem: + while (--i >= 0) + __builtin_free(out[i]); + __builtin_free(out); + return NULL; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c new file mode 100644 index 0000000..e4be509 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c @@ -0,0 +1,106 @@ +/* { dg-additional-options "-fanalyzer-call-summaries" } */ + +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +/* data structures */ + +struct screen_s { + size_t rows; + size_t cols; + char **data; +}; + +struct context_s { + struct screen_s *scr; +}; + +/* global context variable */ + +static struct context_s *ctx; + +/* prototypes */ + +struct screen_s *screen_create(size_t cols, size_t rows); +void screen_destroy(struct screen_s *scr); +void resize_screen(size_t cols, size_t rows); + +/* functions */ + +struct screen_s *screen_create(size_t cols, size_t rows) +{ + struct screen_s *result = NULL; + + result = (struct screen_s *) __builtin_calloc(1, sizeof(*result)); + if (!result) + return NULL; + + result->cols = cols; + result->rows = rows; + + /* make one allocation which will be accessed like a 2D array */ + result->data = (char **) __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols); + if (!result->data) { + __builtin_free(result); + return NULL; + } + + /* obtain pointer to start of data area */ + char *ptr = (char *)(result->data + rows); + + /* setup pointers for each row of data to allow 2D array access */ + for (size_t row = 0; row < rows; row++) + result->data[row] = (ptr + row * cols); + /* array can now be accessed like data[row][col] */ + + return result; +} + +void screen_destroy(struct screen_s *scr) +{ + if (!scr) + return; + + __builtin_free(scr->data); + + scr->data = NULL; + scr->rows = 0; + scr->cols = 0; + + __builtin_free(scr); +} + +void resize_screen(size_t cols, size_t rows) +{ + /* create a new screen */ + struct screen_s *new_scr = NULL; + new_scr = screen_create(cols, rows); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */ + if (!new_scr) { + return; + } + + /* swap the old screen with the new one */ + struct screen_s *old_scr = ctx->scr; + ctx->scr = new_scr; + + /* omitted: copy the old screen contents to the new screen */ + + /* free the old screen */ + screen_destroy(old_scr); +} + +int main(void) +{ + ctx = (struct context_s *) __builtin_calloc(1, sizeof(*ctx)); + if (!ctx) + __builtin_abort(); + + ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */ + resize_screen(100, 20); + + /* tidy up and quit */ + screen_destroy(ctx->scr); + __builtin_free(ctx); + ctx = NULL; + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c new file mode 100644 index 0000000..3196e99 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c @@ -0,0 +1,107 @@ +/* { dg-additional-options "-fno-analyzer-call-summaries" } */ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +/* data structures */ + +struct screen_s { + size_t rows; + size_t cols; + char **data; +}; + +struct context_s { + struct screen_s *scr; +}; + +/* global context variable */ + +static struct context_s *ctx; + +/* prototypes */ + +struct screen_s *screen_create(size_t cols, size_t rows); +void screen_destroy(struct screen_s *scr); +void resize_screen(size_t cols, size_t rows); + +/* functions */ + +struct screen_s *screen_create(size_t cols, size_t rows) +{ + struct screen_s *result = NULL; + + result = (struct screen_s *) __builtin_calloc(1, sizeof(*result)); + if (!result) + return NULL; + + result->cols = cols; + result->rows = rows; + + /* make one allocation which will be accessed like a 2D array */ + result->data = (char **) __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols); + if (!result->data) { + __builtin_free(result); + return NULL; + } + + /* obtain pointer to start of data area */ + char *ptr = (char *)(result->data + rows); + + /* setup pointers for each row of data to allow 2D array access */ + for (size_t row = 0; row < rows; row++) + result->data[row] = (ptr + row * cols); + /* array can now be accessed like data[row][col] */ + + return result; +} + +void screen_destroy(struct screen_s *scr) +{ + if (!scr) + return; + + __builtin_free(scr->data); + + scr->data = NULL; + scr->rows = 0; + scr->cols = 0; + + __builtin_free(scr); /* { dg-bogus "leak" } */ +} + +void resize_screen(size_t cols, size_t rows) +{ + /* create a new screen */ + struct screen_s *new_scr = NULL; + new_scr = screen_create(cols, rows); /* { dg-bogus "leak" } */ + if (!new_scr) { + return; + } + + /* swap the old screen with the new one */ + struct screen_s *old_scr = ctx->scr; + ctx->scr = new_scr; + + /* omitted: copy the old screen contents to the new screen */ + + /* free the old screen */ + screen_destroy(old_scr); +} + +int main(void) +{ + ctx = (struct context_s *) __builtin_calloc(1, sizeof(*ctx)); + if (!ctx) + __builtin_abort(); + + ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" } */ + resize_screen(100, 20); + + /* tidy up and quit */ + screen_destroy(ctx->scr); + __builtin_free(ctx); + ctx = NULL; + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c new file mode 100644 index 0000000..ae196d7 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c @@ -0,0 +1,46 @@ +/* Reduced from haproxy-2.7.1's cfgparse.c. */ + +typedef __SIZE_TYPE__ size_t; + +extern void* +calloc(size_t __nmemb, size_t __size) + __attribute__((__nothrow__, __leaf__)) + __attribute__((__malloc__)) __attribute__((__alloc_size__(1, 2))); + +struct list +{ + struct list* n; + struct list* p; +}; + +struct cfg_postparser +{ + struct list list; + char* name; + int (*func)(); +}; + +extern struct list postparsers; + +int +cfg_register_postparser(char* name, int (*func)()) +{ + struct cfg_postparser* cp; + + cp = (struct cfg_postparser *) calloc(1, sizeof(*cp)); + if (!cp) { + /* [...snip...] */ + return 0; + } + cp->name = name; + cp->func = func; + + ({ + (&cp->list)->p = (&postparsers)->p; + (&cp->list)->p->n = (&postparsers)->p = (&cp->list); + (&cp->list)->n = (&postparsers); + (&cp->list); + }); + + return 1; /* { dg-bogus "leak of 'cp'" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c new file mode 100644 index 0000000..26329ff --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c @@ -0,0 +1,42 @@ +/* Reduced from haproxy-2.7.1's cfgparse.c. */ + +typedef __SIZE_TYPE__ size_t; + +extern void* +calloc(size_t __nmemb, size_t __size) + __attribute__((__nothrow__, __leaf__)) + __attribute__((__malloc__)) __attribute__((__alloc_size__(1, 2))); + +struct list +{ + struct list* n; + struct list* p; +}; + +struct cfg_postparser +{ + struct list list; + char* name; +}; + +extern struct list postparsers; + +int +test_1 (char* name) +{ + struct cfg_postparser* cp; + + cp = (struct cfg_postparser*) calloc(1, sizeof(*cp)); + if (!cp) { + /* [...snip...] */ + return 0; + } + cp->name = name; + + (&cp->list)->p = (&postparsers)->p; + (&postparsers)->p = (&cp->list); + (&cp->list)->p->n = (&postparsers)->p; + (&cp->list)->n = (&postparsers); + + return 1; /* { dg-bogus "leak of 'cp'" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/malloc-2.c b/gcc/testsuite/c-c++-common/analyzer/malloc-2.c new file mode 100644 index 0000000..ed68209 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/malloc-2.c @@ -0,0 +1,23 @@ +/* Tests for precision-of-wording within malloc warnings. */ + +typedef __SIZE_TYPE__ size_t; +extern void *malloc(size_t); +extern void free(void *); +extern char *strcpy(char *__restrict __dest, const char *__restrict __src) + __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); + +void test_1 (void) +{ + void *p = malloc (1024); /* { dg-message "\\(1\\) this call could return NULL" } */ + strcpy ((char *)p, "hello world"); /* { dg-warning "use of possibly-NULL 'p' where non-null expected" "warning" } */ + /* { dg-message "\\(2\\) argument 1 \\('p'\\) from \\(1\\) could be NULL where non-null expected" "event" { target *-*-* } .-1 } */ + free (p); +} + +int *test_2 (void) +{ + int *i = (int *) malloc (sizeof (int)); /* { dg-message "\\(1\\) this call could return NULL" } */ + *i = 42; /* { dg-warning "dereference of possibly-NULL 'i'" "warning" } */ + /* { dg-message "\\(2\\) 'i' could be NULL: unchecked value from \\(1\\)" "event" { target *-*-* } .-1 } */ + return i; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c new file mode 100644 index 0000000..25b0a5e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c @@ -0,0 +1,9 @@ +/* { dg-additional-options "-Wno-stringop-overflow -Wno-analyzer-out-of-bounds" } */ + +int +test (int c, void *v) +{ + static char a[] = ""; + __builtin_memcpy (v, a, -1); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c new file mode 100644 index 0000000..c46ffe9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c @@ -0,0 +1,99 @@ +/* Reduced from haproxy's src/ssl_sample.c */ + +/* { dg-require-effective-target ptr_eq_long } */ +/* { dg-additional-options "-O2" } */ + +union sample_value { + long long int sint; + /* [...snip...] */ +}; + +struct sample_data { + int type; + union sample_value u; +}; + +enum { + /* [...snip...] */ + SMP_T_BOOL, + /* [...snip...] */ +}; +struct sample { + unsigned int flags; + struct sample_data data; + /* [...snip...] */ + struct session *sess; + struct stream *strm; + /* [...snip...] */ +}; +struct arg { + /* [...snip...] */ +}; +enum obj_type { + OBJ_TYPE_NONE = 0, + /* [...snip...] */ + OBJ_TYPE_CONN, + /* [...snip...] */ + OBJ_TYPE_CHECK, + OBJ_TYPE_ENTRIES +}; +enum { + /* [...snip...] */ + CO_FL_EARLY_SSL_HS = 0x00004000, + CO_FL_EARLY_DATA = 0x00008000, + /* [...snip...] */ + CO_FL_SSL_WAIT_HS = 0x08000000, + /* [...snip...] */ +}; +struct connection { + enum obj_type obj_type; + unsigned char err_code; + /* [...snip...] */ + unsigned int flags; + /* [...snip...] */ +}; + +static inline enum obj_type obj_type(const enum obj_type *t) +{ + if (!t || *t >= OBJ_TYPE_ENTRIES) + return OBJ_TYPE_NONE; + return *t; +} +static inline struct connection *__objt_conn(enum obj_type *t) +{ + return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type))); +} +static inline struct connection *objt_conn(enum obj_type *t) +{ + if (!t || *t != OBJ_TYPE_CONN) + return (struct connection *)((void *)0); + return __objt_conn(t); +} +struct session { + /* [...snip...] */ + enum obj_type *origin; + /* [...snip...] */ +}; +typedef struct ssl_st SSL; +SSL *ssl_sock_get_ssl_object(struct connection *conn); + +/*****************************************************************************/ + +int +smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *Private) +{ + SSL *ssl; + struct connection *conn; + + conn = objt_conn(smp->sess->origin); + ssl = ssl_sock_get_ssl_object(conn); + if (!ssl) + return 0; + + smp->flags = 0; + smp->data.type = SMP_T_BOOL; + smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL" "PR analyzer/108251" { xfail *-*-*} } */ + (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0; + + return 1; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c new file mode 100644 index 0000000..ef34a76 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c @@ -0,0 +1,98 @@ +/* Reduced from haproxy's src/ssl_sample.c */ + +/* { dg-require-effective-target ptr_eq_long } */ + +union sample_value { + long long int sint; + /* [...snip...] */ +}; + +struct sample_data { + int type; + union sample_value u; +}; + +enum { + /* [...snip...] */ + SMP_T_BOOL, + /* [...snip...] */ +}; +struct sample { + unsigned int flags; + struct sample_data data; + /* [...snip...] */ + struct session *sess; + struct stream *strm; + /* [...snip...] */ +}; +struct arg { + /* [...snip...] */ +}; +enum obj_type { + OBJ_TYPE_NONE = 0, + /* [...snip...] */ + OBJ_TYPE_CONN, + /* [...snip...] */ + OBJ_TYPE_CHECK, + OBJ_TYPE_ENTRIES +}; +enum { + /* [...snip...] */ + CO_FL_EARLY_SSL_HS = 0x00004000, + CO_FL_EARLY_DATA = 0x00008000, + /* [...snip...] */ + CO_FL_SSL_WAIT_HS = 0x08000000, + /* [...snip...] */ +}; +struct connection { + enum obj_type obj_type; + unsigned char err_code; + /* [...snip...] */ + unsigned int flags; + /* [...snip...] */ +}; + +static inline enum obj_type obj_type(const enum obj_type *t) +{ + if (!t || *t >= OBJ_TYPE_ENTRIES) + return OBJ_TYPE_NONE; + return *t; +} +static inline struct connection *__objt_conn(enum obj_type *t) +{ + return ((struct connection *)(((char *)(t)) - ((long)&((struct connection *)0)->obj_type))); +} +static inline struct connection *objt_conn(enum obj_type *t) +{ + if (!t || *t != OBJ_TYPE_CONN) + return (struct connection *) ((void *)0); + return __objt_conn(t); +} +struct session { + /* [...snip...] */ + enum obj_type *origin; + /* [...snip...] */ +}; +typedef struct ssl_st SSL; +SSL *ssl_sock_get_ssl_object(struct connection *conn); + +/*****************************************************************************/ + +int +smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *Private) +{ + SSL *ssl; + struct connection *conn; + + conn = objt_conn(smp->sess->origin); + ssl = ssl_sock_get_ssl_object(conn); + if (!ssl) + return 0; + + smp->flags = 0; + smp->data.type = SMP_T_BOOL; + smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL 'conn'" "PR analyzer/108251" { xfail *-*-*} } */ + (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0; + + return 1; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c new file mode 100644 index 0000000..f7f6923 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c @@ -0,0 +1,105 @@ +/* Reduced from qemu-7.2.0's hw/intc/omap_intc.c */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef unsigned char __uint8_t; +typedef unsigned int __uint32_t; +typedef unsigned long int __uint64_t; +typedef __uint8_t uint8_t; +typedef __uint32_t uint32_t; +typedef __uint64_t uint64_t; +typedef uint64_t hwaddr; +typedef struct omap_intr_handler_s omap_intr_handler; + +struct omap_intr_handler_bank_s +{ + uint32_t irqs; + uint32_t inputs; + uint32_t mask; + uint32_t fiq; + uint32_t sens_edge; + uint32_t swi; + unsigned char priority[32]; +}; + +struct omap_intr_handler_s +{ + /* [...snip...] */ + unsigned char nbanks; + /* [...snip...] */ + int sir_intr[2]; + int autoidle; + uint32_t mask; + struct omap_intr_handler_bank_s bank[3]; +}; + +uint64_t +omap2_inth_read(struct omap_intr_handler_s* s, int offset) +{ + int bank_no, line_no; + struct omap_intr_handler_bank_s* bank = NULL; + + if ((offset & 0xf80) == 0x80) { + bank_no = (offset & 0x60) >> 5; + if (bank_no < s->nbanks) { + offset &= ~0x60; + bank = &s->bank[bank_no]; + } else { + return 0; + } + } + + switch (offset) { + case 0x10: + return (s->autoidle >> 2) & 1; + + case 0x14: + return 1; + + case 0x40: + return s->sir_intr[0]; + + case 0x44: + return s->sir_intr[1]; + + case 0x48: + return (!s->mask) << 2; + + case 0x4c: + return 0; + + case 0x50: + return s->autoidle & 3; + + case 0x80: + return bank->inputs; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ + + case 0x84: + return bank->mask; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ + + case 0x88: + case 0x8c: + return 0; + + case 0x90: + return bank->swi; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ + + case 0x94: + return 0; + + case 0x98: + return bank->irqs & ~bank->mask & ~bank->fiq; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ + + case 0x9c: + return bank->irqs & ~bank->mask & bank->fiq; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ + + case 0x100 ... 0x300: + bank_no = (offset - 0x100) >> 7; + if (bank_no > s->nbanks) + break; + bank = &s->bank[bank_no]; + line_no = (offset & 0x7f) >> 2; + return (bank->priority[line_no] << 2) | ((bank->fiq >> line_no) & 1); + } + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c new file mode 100644 index 0000000..0c95148 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c @@ -0,0 +1,94 @@ +/* Reduced from apr-1.7.0/tables/apr_hash.c: 'apr_hash_merge' */ + +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +extern void* +memset(void* __s, int __c, size_t __n) + __attribute__((__nothrow__, __leaf__, __nonnull__(1))); + +typedef struct apr_pool_t apr_pool_t; + +void* +apr_palloc(apr_pool_t* p, size_t size) + __attribute__((alloc_size(2), nonnull(1))); + +typedef struct apr_hash_t apr_hash_t; +typedef struct apr_hash_index_t apr_hash_index_t; +typedef unsigned int (*apr_hashfunc_t)(const char* key, size_t* klen); +typedef struct apr_hash_entry_t apr_hash_entry_t; + +struct apr_hash_entry_t +{ + apr_hash_entry_t* next; + unsigned int hash; + const void* key; + size_t klen; + const void* val; +}; + +struct apr_hash_t +{ + apr_pool_t* pool; + apr_hash_entry_t** array; + /* [...snip.../ */ + unsigned int count, max, seed; + apr_hashfunc_t hash_func; + apr_hash_entry_t* free; +}; + +static apr_hash_entry_t** +alloc_array(apr_hash_t* ht, unsigned int max) +{ + return (apr_hash_entry_t **) memset(apr_palloc(ht->pool, sizeof(*ht->array) * (max + 1)), + 0, + sizeof(*ht->array) * (max + 1)); +} + +apr_hash_t* +apr_hash_merge(apr_pool_t* p, + const apr_hash_t* overlay, + const apr_hash_t* base) +{ + apr_hash_t* res; + apr_hash_entry_t* new_vals = NULL; + apr_hash_entry_t* iter; + unsigned int i, j, k; + res = (apr_hash_t *) apr_palloc(p, sizeof(apr_hash_t)); + res->pool = p; + res->free = NULL; + res->hash_func = base->hash_func; + res->count = base->count; + res->max = (overlay->max > base->max) ? overlay->max : base->max; + if (base->count + overlay->count > res->max) { + res->max = res->max * 2 + 1; + } + res->seed = base->seed; + res->array = alloc_array(res, res->max); + if (base->count + overlay->count) { + new_vals = (apr_hash_entry_t *) + apr_palloc(p, sizeof(apr_hash_entry_t) * (base->count + overlay->count)); + } + j = 0; + for (k = 0; k <= base->max; k++) { + for (iter = base->array[k]; iter; iter = iter->next) { + i = iter->hash & res->max; + /* We should only warn for the first of these + (it's actually a false positive, but we don't have the + invariante to know that). */ + new_vals[j].klen = iter->klen; /* { dg-warning "dereference of NULL 'new_vals'" } */ + /* ...but not for subsequent ones: */ + new_vals[j].key = iter->key; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ + new_vals[j].val = iter->val; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ + new_vals[j].hash = iter->hash; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ + new_vals[j].next = res->array[i]; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ + res->array[i] = &new_vals[j]; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ + j++; + } + } + /* [...snip...] */ + return res; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr101962.c b/gcc/testsuite/c-c++-common/analyzer/pr101962.c new file mode 100644 index 0000000..32cef16 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr101962.c @@ -0,0 +1,51 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +/* Verify that the analyzer makes the simplifying assumption that we don't + hit NULL when incrementing pointers to non-NULL memory regions. */ + +static int * __attribute__((noinline)) +maybe_inc_int_ptr (int *ptr) +{ + if (!ptr) + return NULL; + return ++ptr; +} + +int +test_1 (void) +{ + int stack; + int *a = &stack; + a = maybe_inc_int_ptr (a); + a = maybe_inc_int_ptr (a); + __analyzer_eval (a == NULL); /* { dg-warning "FALSE" } */ + __analyzer_eval (a != NULL); /* { dg-warning "TRUE" } */ + return *a; /* { dg-line test_1 } */ + + /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test_1 } */ +} + +static const char * __attribute__((noinline)) +maybe_inc_char_ptr (const char *ptr) +{ + if (!ptr) + return NULL; + return ++ptr; +} + +void +test_s (void) +{ + const char *msg = "hello world"; + const char *a = msg; + __analyzer_eval (*a == 'h'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'e'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ + a = maybe_inc_char_ptr (a); + __analyzer_eval (*a == 'o'); /* { dg-warning "TRUE" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr103217-2.c b/gcc/testsuite/c-c++-common/analyzer/pr103217-2.c new file mode 100644 index 0000000..69ba645 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr103217-2.c @@ -0,0 +1,54 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +typedef __SIZE_TYPE__ size_t; + +extern void *calloc (size_t __nmemb, size_t __size) + __attribute__ ((__nothrow__ , __leaf__, __malloc__, __alloc_size__ (1, 2))); + +extern char *strdup (const char *__s) + __attribute__ ((__nothrow__ , __leaf__, __malloc__, __nonnull__ (1))); + +extern void abort (void) + __attribute__ ((__nothrow__ , __leaf__, __noreturn__)); + +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __attribute__ ((__nothrow__ , __leaf__, __nonnull__ (2, 3))); +extern char *optarg; + +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +char *xstrdup(const char *src) { + char *val = strdup(src); + if (!val) + abort(); + return val; +} + +struct test { + char *one, *two; +}; + +int main(int argc, char *argv[]) { + struct test *options = (struct test *) calloc(1, sizeof(*options)); + int rc; + if (!options) + abort(); + + while ((rc = getopt(argc, argv, "a:b:")) != -1) { + switch (rc) { + case 'a': + free(options->one); + options->one = xstrdup(optarg); + break; + case 'b': + free(options->two); + options->two = xstrdup(optarg); + break; + } + } + free(options->one); + free(options->two); + free(options); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr103217.c b/gcc/testsuite/c-c++-common/analyzer/pr103217.c new file mode 100644 index 0000000..ae298cc --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr103217.c @@ -0,0 +1,44 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +extern char *strdup (const char *__s) + __attribute__ ((__nothrow__ , __leaf__, __malloc__, __nonnull__ (1))); + +extern void abort (void) + __attribute__ ((__nothrow__ , __leaf__, __noreturn__)); + +extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) + __attribute__ ((__nothrow__ , __leaf__, __nonnull__ (2, 3))); +extern char *optarg; + +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +char *xstrdup(const char *src) { + char *val = strdup(src); + if (!val) + abort(); + return val; +} + +int main(int argc, char *argv[]) { + char *one = NULL, *two = NULL; + int rc; + + while ((rc = getopt(argc, argv, "a:b:")) != -1) { + switch (rc) { + case 'a': + free(one); + one = xstrdup(optarg); + break; + case 'b': + free(two); + two = xstrdup(optarg); + break; + } + } + free(one); + free(two); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr104029.c b/gcc/testsuite/c-c++-common/analyzer/pr104029.c new file mode 100644 index 0000000..873f0eb --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr104029.c @@ -0,0 +1,115 @@ +// TODO: remove need for this option +/* { dg-additional-options "-fanalyzer-checker=taint" } */ + +typedef __SIZE_TYPE__ size_t; +typedef const void *t_comptype; +typedef int (*t_compfunc)(t_comptype, t_comptype); + +extern int *__errno_location(void) + __attribute__((__nothrow__, __leaf__,__const__)); +extern void free(void *__ptr) + __attribute__((__nothrow__, __leaf__)); +extern void *my_malloc1(const char *file, int line, size_t size); + +int heapsort(void *vbase, size_t nmemb, size_t size, t_compfunc compar) { + char tmp, *tmp1, *tmp2, *abase, *k, *p, *t; + size_t cnt, i, j, l; + + if (nmemb <= 1) + return (0); + + if (!size) { + (*__errno_location()) = 22; + return (-1); + } + + k = (char *) my_malloc1(__FILE__, __LINE__, size); + + abase = (char *)vbase - size; + + for (l = nmemb / 2 + 1; --l;) { + for (i = l; (j = i * 2) <= nmemb; i = j) { + p = abase + j * size; + if (j < nmemb && compar(p, p + size) < 0) { + p += size; + ++j; + } + t = abase + i * size; + if (compar(p, t) <= 0) + break; + { + cnt = size; + do { + tmp = *t; + *t++ = *p; + *p++ = tmp; + } while (--cnt); + }; + } + }; + + while (nmemb > 1) { + { + cnt = size; + tmp1 = k; + tmp2 = abase + nmemb * size; + do { + *tmp1++ = *tmp2++; + } while (--cnt); + }; + { + cnt = size; + tmp1 = abase + nmemb * size; + tmp2 = abase + size; + do { + *tmp1++ = *tmp2++; + } while (--cnt); + }; + --nmemb; + { + for (i = 1; (j = i * 2) <= nmemb; i = j) { + p = abase + j * size; + if (j < nmemb && compar(p, p + size) < 0) { + p += size; + ++j; + } + t = abase + i * size; + { + cnt = size; + tmp1 = t; + tmp2 = p; + do { + *tmp1++ = *tmp2++; + } while (--cnt); + }; + } + for (;;) { + j = i; + i = j / 2; + p = abase + j * size; + t = abase + i * size; + if (j == 1 || compar(k, t) < 0) { + { + cnt = size; + tmp1 = p; + tmp2 = k; + do { + *tmp1++ = *tmp2++; + } while (--cnt); + }; + break; + } + { + cnt = size; + tmp1 = p; + tmp2 = t; + do { + *tmp1++ = *tmp2++; + } while (--cnt); + }; + } + }; + } + free(k); + return (0); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr104062.c b/gcc/testsuite/c-c++-common/analyzer/pr104062.c new file mode 100644 index 0000000..9b44893 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr104062.c @@ -0,0 +1,13 @@ +void * +calloc (__SIZE_TYPE__, __SIZE_TYPE__); + +void * +realloc (void *, __SIZE_TYPE__); + +void +foo (void) +{ + int *ap5 = (int *) calloc (4, sizeof *ap5); + int *ap7 = (int *) realloc (ap5, sizeof *ap5); +} /* { dg-warning "leak of 'ap5'" "leak of ap5" } */ +/* { dg-warning "leak of 'ap7'" "leak of ap7" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/pr105783.c b/gcc/testsuite/c-c++-common/analyzer/pr105783.c new file mode 100644 index 0000000..f175194 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr105783.c @@ -0,0 +1,30 @@ +/* { dg-additional-options "-O" } */ + +#ifndef __cplusplus +typedef _Bool bool; +#endif + +struct ss_s { + union out_or_counting_u { + char *newstr; + unsigned long long cnt; + } uu; + bool counting; +}; + +struct ss_s ss_init(void) { + struct ss_s rr = { .counting = 1 }; + return rr; +} + +void ss_out(struct ss_s *t, char cc) { + if (!t->counting) { + *t->uu.newstr++ = cc; + } +} + +int main() { + struct ss_s ss = ss_init(); + ss_out(&ss, 'a'); +} + diff --git a/gcc/testsuite/c-c++-common/analyzer/pr107345.c b/gcc/testsuite/c-c++-common/analyzer/pr107345.c new file mode 100644 index 0000000..ea1925b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr107345.c @@ -0,0 +1,18 @@ +/* Ensure the analyzer treats (NULL == &e) as being false for this case, + where the logic is sufficiently complicated to not be optimized away. */ + +#include + +int main() { + int e = 10086; + int *f = &e; + int g = 0; + int *h[2][1]; + h[1][0] = f; + if (g == (h[1][0])) { /* { dg-warning "comparison between pointer and integer" "" { target c } } */ + /* { dg-error "ISO C\\+\\+ forbids comparison between pointer and integer" "" { target c++ } .-1 } */ + unsigned int *i = 0; + } + printf("NPD_FLAG: %d\n ", *f); + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr93457.c b/gcc/testsuite/c-c++-common/analyzer/pr93457.c new file mode 100644 index 0000000..71b3962 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr93457.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ + +void +p5 (const void *); + +void +s5 (const void *cl) +{ + p5 (&cl[1]); /* { dg-warning "dereferencing 'void \\*' pointer" "" { target c } } */ + /* { dg-warning "pointer of type 'void \\*' used in arithmetic" "" { target c++ } .-1 } */ + /* { dg-error "'const void\\*' is not a pointer-to-object type" "" { target c++ } .-2 } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr93695-1.c b/gcc/testsuite/c-c++-common/analyzer/pr93695-1.c new file mode 100644 index 0000000..529c601 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr93695-1.c @@ -0,0 +1,53 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ +/* TODO: remove the need for this option (PR analyzer/93695). */ + +#define NELEMS 10 +#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0])) + +void +test_1 (void) +{ + int *p[NELEMS]; + int i; + + for (i = 0; i < ARRAY_SIZE (p); ++i) + p[i] = (int *) __builtin_malloc (sizeof (i)); + + for (i = 0; i < ARRAY_SIZE (p); ++i) + __builtin_free (p [i]); +} + +void +test_2 (int n) +{ + int **p; + int i; + + p = (int **)__builtin_malloc (sizeof (int *) * n); + if (!p) + return; + + for (i = 0; i < n; ++i) + p[i] = (int *) __builtin_malloc (sizeof (i)); + + for (i = 0; i < n; ++i) + __builtin_free (p [i]); + + __builtin_free (p); +} + +void +test_3 (int **p, int n) +{ + int i; + for (i = 0; i < n; ++i) + p[i] = (int *) __builtin_malloc (sizeof (i)); +} + +void +test_4 (void **p, int n) +{ + int i; + for (i = 0; i < n; ++i) + __builtin_free (p[i]); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr94596.c b/gcc/testsuite/c-c++-common/analyzer/pr94596.c new file mode 100644 index 0000000..10ea549 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr94596.c @@ -0,0 +1,100 @@ +/* Minimized/hacked up from openvswitch lib/conntrack.c, which had this license + header: */ +/* + * Copyright (c) 2015-2019 Nicira, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" +typedef __SIZE_TYPE__ size_t; + +#ifndef __cplusplus +#define false 0 +#endif + +#define OBJECT_OFFSETOF(OBJECT, MEMBER)\ + __builtin_offsetof(struct zone_limit, MEMBER) + +#define OBJECT_CONTAINING(POINTER, OBJECT, MEMBER) \ + ((struct zone_limit *) (void *) \ + ((char *) (POINTER) - OBJECT_OFFSETOF(OBJECT, MEMBER))) + +#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \ + ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), (void) 0) + +#define INIT_CONTAINER(OBJECT, POINTER, MEMBER) \ + ((OBJECT) = NULL, ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER)) + +#define HMAP_FOR_EACH_POP(NODE, MEMBER, HMAP) \ + for (size_t bucket__ = 0; \ + INIT_CONTAINER(NODE, hmap_pop_helper__(HMAP, &bucket__), MEMBER), \ + (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \ + || ((NODE = NULL), false);) + +struct hmap { + struct hmap_node **buckets; + struct hmap_node *one; + size_t mask; + size_t n; +}; + +struct hmap_node { + size_t hash; + struct hmap_node *next; +}; + +static inline void hmap_remove(struct hmap *, struct hmap_node *); + +struct hmap_node * +hmap_pop_helper__(struct hmap *hmap, size_t *bucket) { + + for (; *bucket <= hmap->mask; (*bucket)++) { + struct hmap_node *node = hmap->buckets[*bucket]; + + if (node) { + hmap_remove(hmap, node); + return node; + } + } + + return NULL; +} + +static inline void +hmap_remove(struct hmap *hmap, struct hmap_node *node) +{ + struct hmap_node **bucket = &hmap->buckets[node->hash & hmap->mask]; + while (*bucket != node) { + bucket = &(*bucket)->next; + } + *bucket = node->next; + hmap->n--; +} + +struct conntrack { + struct hmap zone_limits; +}; + +struct zone_limit { + struct hmap_node node; +}; + +void +conntrack_destroy(struct conntrack *ct) +{ + struct zone_limit *zl; + HMAP_FOR_EACH_POP (zl, node, &ct->zone_limits) { + __builtin_free(zl); + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr94839.c b/gcc/testsuite/c-c++-common/analyzer/pr94839.c new file mode 100644 index 0000000..26e7e61 --- /dev/null +++ b/gcc/testsuite/c-c++-common/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 = (int *) __builtin_calloc(sz, sizeof(int)); + if (!bm->vec) + return (-12); + return 0; /* { dg-bogus "leak" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr95240.c b/gcc/testsuite/c-c++-common/analyzer/pr95240.c new file mode 100644 index 0000000..afd831b --- /dev/null +++ b/gcc/testsuite/c-c++-common/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 = (char *) 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/c-c++-common/analyzer/pr96639.c b/gcc/testsuite/c-c++-common/analyzer/pr96639.c new file mode 100644 index 0000000..b95217d --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr96639.c @@ -0,0 +1,10 @@ +void *calloc (__SIZE_TYPE__, __SIZE_TYPE__); + +int +x7 (void) +{ + int **md = (int **) calloc (1, sizeof (void *)); + + return md[0][0]; /* { dg-warning "possibly-NULL" "unchecked deref" } */ + /* { dg-warning "leak of 'md'" "leak" { target *-*-* } .-1 } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr96653.c b/gcc/testsuite/c-c++-common/analyzer/pr96653.c new file mode 100644 index 0000000..75f3d23 --- /dev/null +++ b/gcc/testsuite/c-c++-common/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 (const char *) ((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 = (enum v4l2_ctrl_type) 0x0103; + break; + case ((0x00990000 | 0x900) + 251): + *type = (enum v4l2_ctrl_type) 0x0104; + break; + case ((0x00990000 | 0x900) + 292): + *type = (enum v4l2_ctrl_type) 0x0105; + break; + case ((0x00990000 | 0x900) + 1000): + *type = (enum v4l2_ctrl_type) 0x0110; + break; + case ((0x00990000 | 0x900) + 1001): + *type = (enum v4l2_ctrl_type) 0x0111; + break; + case ((0x00990000 | 0x900) + 1002): + *type = (enum v4l2_ctrl_type) 0x0112; + break; + case ((0x00990000 | 0x900) + 1003): + *type = (enum v4l2_ctrl_type) 0x0113; + break; + case ((0x00990000 | 0x900) + 1004): + *type = (enum v4l2_ctrl_type) 0x0114; + break; + case ((0x00990000 | 0x900) + 2000): + *type = (enum v4l2_ctrl_type) 0x301; + break; + case ((0x00990000 | 0x900) + 1008): + *type = (enum v4l2_ctrl_type) 0x0120; + break; + case ((0x00990000 | 0x900) + 1009): + *type = (enum v4l2_ctrl_type) 0x0121; + break; + case ((0x00990000 | 0x900) + 1010): + *type = (enum v4l2_ctrl_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/c-c++-common/analyzer/pr96792.c b/gcc/testsuite/c-c++-common/analyzer/pr96792.c new file mode 100644 index 0000000..accaf22 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr96792.c @@ -0,0 +1,39 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +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/c-c++-common/analyzer/pr96841.c b/gcc/testsuite/c-c++-common/analyzer/pr96841.c new file mode 100644 index 0000000..b2951a0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr96841.c @@ -0,0 +1,21 @@ +/* { dg-additional-options "-O1 -Wno-builtin-declaration-mismatch -Wno-analyzer-too-complex" } */ + +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]); + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr97568.c b/gcc/testsuite/c-c++-common/analyzer/pr97568.c new file mode 100644 index 0000000..da97b9d --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr97568.c @@ -0,0 +1,31 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +extern int *const p1; + +int *const p2 = NULL; + +int v3; +extern int *const p3 = &v3; /* { dg-warning "'p3' initialized and declared 'extern'" "C FE warning" { target c } } */ + +int v4; +int *const p4 = &v4; + +int main (void) +{ + __analyzer_describe (0, p1); /* { dg-message "INIT_VAL\\(p1\\)" "" { target c } } */ + /* { dg-message "INIT_VAL\\(int\\* const p1\\)" "" { target c++ } .-1 } */ + __analyzer_eval (p1 == NULL); /* { dg-message "UNKNOWN" } */ + + __analyzer_eval (p2 == NULL); /* { dg-message "TRUE" } */ + + __analyzer_describe (0, p3); /* { dg-message "&v3" "" { target c } } */ + /* { dg-message "&int v3" "" { target c++ } .-1 } */ + __analyzer_eval (p3 == NULL); /* { dg-message "FALSE" } */ + + __analyzer_describe (0, p4); /* { dg-message "&v4" "" { target c } } */ + /* { dg-message "&int v4" "" { target c++ } .-1 } */ + __analyzer_eval (p4 == NULL); /* { dg-message "FALSE" } */ + + return p1[0]; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr98564.c b/gcc/testsuite/c-c++-common/analyzer/pr98564.c new file mode 100644 index 0000000..a404e35 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr98564.c @@ -0,0 +1,6 @@ +void *calloc (__SIZE_TYPE__, __SIZE_TYPE__); + +void test_1 (void) +{ + int *p = (int *) calloc (0, 1); /* { dg-message "allocated here" } */ +} /* { dg-warning "leak of 'p'" } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/pr98628.c b/gcc/testsuite/c-c++-common/analyzer/pr98628.c new file mode 100644 index 0000000..f339c49 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr98628.c @@ -0,0 +1,18 @@ +/* { dg-additional-options "-O1" } */ + +void foo(void *); +struct chanset_t { + struct chanset_t *next; + char dname[]; +}; +struct chanset_t help_subst_chan; +struct chanset_t *help_subst_chan_0_0; +void help_subst(char *writeidx) { + for (;; help_subst_chan = *help_subst_chan_0_0) { + foo(help_subst_chan.next->dname); + if (help_subst_chan_0_0) { + writeidx++; + *writeidx++ = ' '; + } + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr98969.c b/gcc/testsuite/c-c++-common/analyzer/pr98969.c new file mode 100644 index 0000000..4fe7601 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr98969.c @@ -0,0 +1,26 @@ +struct foo +{ + char *expr; +}; + +void +test_1 (__UINTPTR_TYPE__ i) +{ + struct foo *f = (struct foo *)i; + f->expr = (char *) __builtin_malloc (1024); +} /* { dg-bogus "leak" } */ + +void +test_2 (__UINTPTR_TYPE__ i) +{ + __builtin_free (((struct foo *)i)->expr); + __builtin_free (((struct foo *)i)->expr); /* { dg-warning "double-'free' of '\\*\\(\\(struct foo \\*\\)i\\)\\.expr'" "" { target c } } */ + /* { dg-warning "double-'free' of '\\*\\(\\(foo\\*\\)i\\)\\.foo::expr'" "" { target c++ } .-1 } */ +} + +void +test_3 (void *p) +{ + void **q = (void **)p; + *q = __builtin_malloc (1024); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c new file mode 100644 index 0000000..791b857 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c @@ -0,0 +1,68 @@ +/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation + on realloc(3). + Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/df/main.c#L404 + which is GPLv2 or later. */ + +typedef __SIZE_TYPE__ size_t; +typedef __builtin_va_list va_list; + +#define NULL ((void *)0) + +extern void free (void *); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +char *strdup (const char *) + __attribute__((malloc (free))); + +extern void error (int __status, int __errnum, const char *__format, ...) + __attribute__ ((__format__ (__printf__, 3, 4))); + +extern int errno; + +struct drv +{ + struct drv *next; +}; + +#define EXIT_FAILURE 1 + +static char * +single_drive_display_name (struct drv *) +{ + char *result = strdup ("placeholder"); + if (!result) + __builtin_abort (); + return result; +} + +char * +make_display_name (struct drv *drvs) +{ + char *ret; + + if (drvs->next == NULL) + ret = single_drive_display_name (drvs); + else { + size_t pluses = 0; + size_t i, len; + + while (drvs->next != NULL) { + drvs = drvs->next; + pluses++; + } + + ret = single_drive_display_name (drvs); + len = __builtin_strlen (ret); + + ret = (char *) realloc (ret, len + pluses + 1); /* { dg-bogus "'free'" } */ + if (ret == NULL) + error (EXIT_FAILURE, errno, "realloc"); + for (i = len; i < len + pluses; ++i) + ret[i] = '+'; + ret[i] = '\0'; + } + + return ret; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99193-3.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-3.c new file mode 100644 index 0000000..696ded0 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-3.c @@ -0,0 +1,50 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation + on realloc(3). + Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/debug.c#L115 + which is GPLv2 or later. */ + +typedef __SIZE_TYPE__ size_t; +typedef __builtin_va_list va_list; + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +extern void free (void *); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern char *strdup (const char *) + __attribute__((malloc (free))); +extern char *strcat (char *__restrict __dest, const char *__restrict __src) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__nonnull__ (1, 2))); + +static char * +debug_help (const char **cmds, size_t argc, char *const *const argv) +{ + size_t len, i; + char *r, *p; + + r = strdup ("Commands supported:"); + if (!r) { + return NULL; + } + + len = __builtin_strlen (r); + for (i = 0; cmds[i] != NULL; ++i) { + len += __builtin_strlen (cmds[i]) + 1; + p = (char *) realloc (r, len + 1); /* { dg-bogus "'free'" } */ + if (p == NULL) { + free (r); + return NULL; + } + r = p; + + strcat (r, " "); + strcat (r, cmds[i]); + } + + return r; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99716-1.c b/gcc/testsuite/c-c++-common/analyzer/pr99716-1.c new file mode 100644 index 0000000..41be8ca --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr99716-1.c @@ -0,0 +1,46 @@ +typedef struct FILE FILE; + +FILE* fopen (const char*, const char*); +int fclose (FILE*); +int fprintf (FILE *, const char *, ...); + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +void +test_1 (void) +{ + int i; + + for (i = 0; i < 2; ++i) { + FILE *fp = fopen ("/tmp/test", "w"); + fprintf (fp, "hello:%s ", "world"); + fclose (fp); /* { dg-bogus "double 'fclose'" } */ + } +} + +void +test_2 (void) +{ + int i; + + for (i = 0; i < 2; ++i) { + FILE *fp = fopen ("/tmp/test", "w"); + fprintf (fp, "hello"); + } +} /* { dg-warning "leak of FILE 'fp'" } */ + +FILE *fp3; + +void +test_3 (FILE **fpp) +{ + int i; + + for (i = 0; i < 2; ++i) { + *fpp = fopen ("/tmp/test", "w"); + fprintf (*fpp, "hello"); + fclose (*fpp); /* { dg-bogus "double 'fclose'" } */ + *fpp = NULL; + } +} diff --git a/gcc/testsuite/c-c++-common/analyzer/pr99774-1.c b/gcc/testsuite/c-c++-common/analyzer/pr99774-1.c new file mode 100644 index 0000000..184baee --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/pr99774-1.c @@ -0,0 +1,61 @@ +/* Reproducer for report from -Wanalyzer-malloc-leak + Reduced from + https://git.qemu.org/?p=qemu.git;a=blob;f=subprojects/libvhost-user/libvhost-user.c;h=fab7ca17ee1fb27bcfc338527d1aeb9f923aade5;hb=HEAD#l1184 + which is licensed under GNU GPLv2 or later. */ + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned long uint64_t; +typedef unsigned long uint64_t; +typedef __SIZE_TYPE__ size_t; + +extern void *calloc(size_t __nmemb, size_t __size) + __attribute__((__nothrow__, __leaf__)) + __attribute__((__malloc__)) + __attribute__((__alloc_size__(1, 2))) + __attribute__((__warn_unused_result__)); + +typedef struct VuDescStateSplit { + uint8_t inflight; + uint64_t counter; +} VuDescStateSplit; + +typedef struct VuVirtqInflight { + uint16_t desc_num; + VuDescStateSplit desc[]; +} VuVirtqInflight; + +typedef struct VuVirtqInflightDesc { + uint16_t index; + uint64_t counter; +} VuVirtqInflightDesc; + +typedef struct VuVirtq { + VuVirtqInflight *inflight; + VuVirtqInflightDesc *resubmit_list; + uint16_t resubmit_num; + uint64_t counter; + int inuse; +} VuVirtq; + +int vu_check_queue_inflights(VuVirtq *vq) { + int i = 0; + + if (vq->inuse) { + vq->resubmit_list = (VuVirtqInflightDesc *) calloc(vq->inuse, sizeof(VuVirtqInflightDesc)); + if (!vq->resubmit_list) { + return -1; + } + + for (i = 0; i < vq->inflight->desc_num; i++) { + if (vq->inflight->desc[i].inflight) { + vq->resubmit_list[vq->resubmit_num].index = i; /* { dg-bogus "leak" } */ + vq->resubmit_list[vq->resubmit_num].counter = + vq->inflight->desc[i].counter; + vq->resubmit_num++; + } + } + } + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-1.c b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c new file mode 100644 index 0000000..75e0b10e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c @@ -0,0 +1,96 @@ +/* { dg-additional-options "-Wno-free-nonheap-object" } */ + +typedef __SIZE_TYPE__ size_t; + +#define NULL ((void *)0) + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +void *test_1 (void *ptr) +{ + return realloc (ptr, 1024); +} + +void test_2 (void *ptr) +{ + void *p = malloc (1024); /* { dg-message "allocated here" } */ + p = realloc (p, 4096); /* { dg-message "when 'realloc' fails" } */ + free (p); +} /* { dg-warning "leak of 'p'" } */ // ideally this would be on the realloc stmt + +void test_3 (void *ptr) +{ + void *p = malloc (1024); + void *q = realloc (p, 4096); + if (q) + free (q); + else + free (p); +} + +void *test_4 (void) +{ + return realloc (NULL, 1024); +} + +int *test_5 (int *p) +{ + *p = 42; + int *q = (int *) realloc (p, sizeof(int) * 4); /* { dg-message "when 'realloc' fails" } */ + *q = 43; /* { dg-warning "dereference of NULL 'q'" } */ + return q; +} + +void test_6 (size_t sz) +{ + void *p = realloc (NULL, sz); +} /* { dg-warning "leak of 'p'" } */ + +/* The analyzer should complain about realloc of non-heap. */ + +void *test_7 (size_t sz) +{ + char buf[100]; /* { dg-message "region created on stack here" } */ + void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '& ?buf' which points to memory on the stack" } */ + return p; +} + +/* Mismatched allocator. */ + +struct foo +{ + int m_int; +}; + +extern void foo_release (struct foo *); +extern struct foo *foo_acquire (void) + __attribute__ ((malloc (foo_release))); + +void test_8 (void) +{ + struct foo *p = foo_acquire (); + void *q = realloc (p, 1024); /* { dg-warning "'p' should have been deallocated with 'foo_release' but was deallocated with 'realloc'" } */ +} + +/* We should complain about realloc on a freed pointer. */ + +void test_9 (void *p) +{ + free (p); + void *q = realloc (p, 1024); /* { dg-warning "double-'free' of 'p'" } */ +} + +void test_10 (char *s, int n) +{ + __builtin_realloc(s, n); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" "" { target c } } */ + /* { dg-warning "ignoring return value of 'void\\* __builtin_realloc\\(void\\*, (long )?unsigned int\\)' declared with attribute 'warn_unused_result'" "" { target c++ } .-1 } */ +} /* { dg-warning "leak" } */ diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-2.c b/gcc/testsuite/c-c++-common/analyzer/realloc-2.c new file mode 100644 index 0000000..e608e0e --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-2.c @@ -0,0 +1,80 @@ +/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +char *test_8 (size_t sz) +{ + char *p, *q; + + p = (char *) malloc (3); + if (!p) + return NULL; + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ + + p[0] = 'a'; + p[1] = 'b'; + p[2] = 'c'; + + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + + q = (char *) realloc (p, 6); + + /* We should have 3 nodes, corresponding to "failure", + "success without moving", and "success with moving". */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ + + if (q) + { + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(size_t\\)6'" } */ + q[3] = 'd'; + q[4] = 'e'; + q[5] = 'f'; + if (q == p) + { + /* "realloc" success, growing the buffer in-place. */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + // TODO + } + else + { + /* "realloc" success, moving the buffer (and thus freeing "p"). */ + __analyzer_eval (q[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[2] == 'c'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ + } + __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" failure. p should be unchanged. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + return p; + } + + return q; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-3.c b/gcc/testsuite/c-c++-common/analyzer/realloc-3.c new file mode 100644 index 0000000..b380135 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-3.c @@ -0,0 +1,82 @@ +/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + + +extern void *calloc (size_t __nmemb, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1, 2))) ; +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +/* realloc of calloc buffer. */ + +char *test_8 (size_t sz) +{ + char *p, *q; + + p = (char *) calloc (1, 3); + if (!p) + return NULL; + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ + + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ + + q = (char *) realloc (p, 6); + + /* We should have 3 nodes, corresponding to "failure", + "success without moving", and "success with moving". */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ + + if (q) + { + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ + q[3] = 'd'; + q[4] = 'e'; + q[5] = 'f'; + if (q == p) + { + /* "realloc" success, growing the buffer in-place. */ + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" success, moving the buffer (and thus freeing "p"). */ + __analyzer_eval (q[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[2] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ + } + __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" failure. p should be unchanged. */ + __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ + __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ + return p; + } + + return q; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-4.c b/gcc/testsuite/c-c++-common/analyzer/realloc-4.c new file mode 100644 index 0000000..7e9a8ed --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-4.c @@ -0,0 +1,84 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + + +extern void *calloc (size_t __nmemb, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1, 2))) ; +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); + +/* realloc where we don't know the original size of the region. */ + +char *test_8 (char *p, size_t sz) +{ + char *q; + + __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(\[^\n\r\]*\\)'" } */ + + p[0] = 'a'; + p[1] = 'b'; + p[2] = 'c'; + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + + q = (char *) realloc (p, 6); + + /* We should have 3 nodes, corresponding to "failure", + "success without moving", and "success with moving". */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ + + if (q) + { + q[3] = 'd'; + q[4] = 'e'; + q[5] = 'f'; + if (q == p) + { + /* "realloc" success, growing the buffer in-place. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ + __analyzer_eval (q[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[2] == 'c'); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" success, moving the buffer (and thus freeing "p"). */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ + /* We don't know how much of the buffer is copied. */ + __analyzer_eval (q[0] == 'a'); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (q[1] == 'b'); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (q[2] == 'c'); /* { dg-warning "UNKNOWN" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ + /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ + } + __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ + __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ + } + else + { + /* "realloc" failure. p should be unchanged. */ + __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ + __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(\[^\n\r\]*\\)'" } */ + __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ + __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ + return p; + } + + return q; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-5.c b/gcc/testsuite/c-c++-common/analyzer/realloc-5.c new file mode 100644 index 0000000..d469ae9 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-5.c @@ -0,0 +1,45 @@ +/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + + +extern void *malloc (size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__malloc__)) + __attribute__ ((__alloc_size__ (1))); +extern void *realloc (void *__ptr, size_t __size) + __attribute__ ((__nothrow__ , __leaf__)) + __attribute__ ((__warn_unused_result__)) + __attribute__ ((__alloc_size__ (2))); +extern void free (void *__ptr) + __attribute__ ((__nothrow__ , __leaf__)); +extern void *memset (void *__ptr, int __value, size_t __size); + +/* realloc where the region shrinks on success_with_move. */ + +void test_1 () +{ + char *p = (char *) malloc (16); + if (!p) + return; + memset (p, 1, 16); + + char *q = (char *) realloc (p, 8); + if (!q) + { + free (p); + return; + } + else if (p != q) + { + __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)8'" } */ + __analyzer_eval (q[8] == 1); /* { dg-line eval } */ + + /* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */ + /* { dg-warning "heap-based buffer over-read" "warning" { target *-*-* } eval } */ + } + + free (q); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c b/gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c new file mode 100644 index 0000000..e25722a --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c @@ -0,0 +1,25 @@ +void *realloc (void *, unsigned long) + __attribute__((__nothrow__, __leaf__)) + __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__ (2))); + +long * +slurp (long *buffer, unsigned long file_size) +{ + unsigned long cc; + if (!__builtin_add_overflow (file_size - file_size % sizeof (long), + 2 * sizeof (long), &cc)) + buffer = (long *) realloc (buffer, cc); + return buffer; +} + +long * +slurp1 (long *buffer, unsigned long file_size) +{ + return (long *) realloc (buffer, file_size - file_size % sizeof (long)); +} + +long * +slurp2 (long *buffer, unsigned long file_size) +{ + return (long *) realloc (buffer, (file_size / sizeof (long)) * sizeof (long)); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c b/gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c new file mode 100644 index 0000000..c40440c --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c @@ -0,0 +1,35 @@ +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +extern size_t +strlen(const char* __s) __attribute__((__nothrow__, __leaf__)) +__attribute__((__pure__)) __attribute__((__nonnull__(1))); + +extern void* +malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) +__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); + +extern int +snprintf(char* __restrict __s, size_t size, const char* __restrict, ...) + __attribute__((__nothrow__)); + +char * +test_1 (const char *a, const char *b) +{ + size_t sz = strlen (a) + strlen (b) + 2; + char *p = (char *) malloc (sz); + if (!p) + return NULL; + snprintf (p, sz, "%s/%s", a, b); + return p; +} + +void +test_2 (const char *a, const char *b) +{ + size_t sz = strlen (a) + strlen (b) + 2; + char *p = (char *) malloc (sz); /* { dg-message "allocated here" "PR 107017" { xfail *-*-* } } */ + if (!p) + return; + snprintf (p, sz, "%s/%s", a, b); /* { dg-warning "leak of 'p'" "PR 107017" { xfail *-*-* } } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/sock-1.c b/gcc/testsuite/c-c++-common/analyzer/sock-1.c new file mode 100644 index 0000000..e5e2f23b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/sock-1.c @@ -0,0 +1,114 @@ +typedef unsigned int __u32; +__extension__ typedef __signed__ long long __s64; +__extension__ typedef unsigned long long __u64; +typedef __u32 u32; +typedef __s64 s64; +typedef __u64 u64; +typedef long long __kernel_time64_t; +#ifndef __cplusplus +typedef _Bool bool; +#endif +typedef __s64 time64_t; +struct __kernel_timespec { + __kernel_time64_t tv_sec; + long long tv_nsec; +}; +struct timespec64 { + time64_t tv_sec; + long tv_nsec; +}; + +extern struct timespec64 ns_to_timespec64(const s64 nsec); +int put_timespec64(const struct timespec64 *ts, + struct __kernel_timespec *uts); + +/* [...snip...] */ + +extern int put_old_timespec32(const struct timespec64 *, void *); + +/* [...snip...] */ + +/* [...snip...] */ + +typedef s64 ktime_t; + +/* [...snip...] */ + +extern void ktime_get_real_ts64(struct timespec64 *tv); + +/* [...snip...] */ + +enum tk_offsets { + TK_OFFS_REAL, + TK_OFFS_BOOT, + TK_OFFS_TAI, + TK_OFFS_MAX, +}; + +extern ktime_t ktime_get(void); +extern ktime_t ktime_get_with_offset(enum tk_offsets offs); +extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs); +extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs); +extern ktime_t ktime_get_raw(void); +extern u32 ktime_get_resolution_ns(void); + + +static ktime_t ktime_get_real(void) +{ + return ktime_get_with_offset(TK_OFFS_REAL); +} + +/* [...snip...] */ + +struct socket { + /* [...snip...] */ + struct sock *sk; + /* [...snip...] */ +}; + +/* [...snip...] */ + +struct sock { + /* [...snip...] */ + ktime_t sk_stamp; + /* [...snip...] */ +}; + +/* [...snip...] */ + +static ktime_t sock_read_timestamp(struct sock *sk) +{ + return *(const volatile ktime_t *)&(sk->sk_stamp); +} + +static void sock_write_timestamp(struct sock *sk, ktime_t kt) +{ + *(volatile ktime_t *)&(sk->sk_stamp) = kt; +} + +/* [...snip...] */ + +int sock_gettstamp(struct socket *sock, void *userstamp, + bool timeval, bool time32) +{ + struct sock *sk = sock->sk; + struct timespec64 ts; + + /* [...snip...] */ + ts = ns_to_timespec64((sock_read_timestamp(sk))); + if (ts.tv_sec == -1) + return -2; + if (ts.tv_sec == 0) { + ktime_t kt = ktime_get_real(); + sock_write_timestamp(sk, kt); + ts = ns_to_timespec64((kt)); + } + + if (timeval) + ts.tv_nsec /= 1000; + + + if (time32) + return put_old_timespec32(&ts, userstamp); + return put_timespec64(&ts, (struct __kernel_timespec *) userstamp); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/sprintf-2.c b/gcc/testsuite/c-c++-common/analyzer/sprintf-2.c new file mode 100644 index 0000000..4e10130 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-2.c @@ -0,0 +1,59 @@ +/* See e.g. https://en.cppreference.com/w/c/io/fprintf + and https://www.man7.org/linux/man-pages/man3/sprintf.3.html */ + +extern int +sprintf(char* dst, const char* fmt, ...) + __attribute__((__nothrow__)); + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +int +test_passthrough (char* dst, const char* fmt) +{ + /* This assumes that fmt doesn't have any arguments. */ + return sprintf (dst, fmt); +} + +void +test_known (void) +{ + char buf[10]; + int res = sprintf (buf, "foo"); + /* TODO: ideally we would know the value of "res" is 3, + and known the content and strlen of "buf" after the call */ +} + +int +test_null_dst (void) +{ + return sprintf (NULL, "hello world"); /* { dg-warning "use of NULL where non-null expected" } */ +} + +int +test_null_fmt (char *dst) +{ + return sprintf (dst, NULL); /* { dg-warning "use of NULL where non-null expected" } */ +} + +int +test_uninit_dst (void) +{ + char *dst; + return sprintf (dst, "hello world"); /* { dg-warning "use of uninitialized value 'dst'" } */ +} + +int +test_uninit_fmt_ptr (char *dst) +{ + const char *fmt; + return sprintf (dst, fmt); /* { dg-warning "use of uninitialized value 'fmt'" } */ +} + +void +test_strlen_1 (void) +{ + char buf[10]; + sprintf (buf, "msg: %s\n", "abc"); + __analyzer_eval (__builtin_strlen (buf) == 8); /* { dg-warning "UNKNOWN" } */ + // TODO: ideally would be TRUE +} diff --git a/gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c b/gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c new file mode 100644 index 0000000..ad74458 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c @@ -0,0 +1,35 @@ +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +extern size_t +strlen(const char* __s) __attribute__((__nothrow__, __leaf__)) +__attribute__((__pure__)) __attribute__((__nonnull__(1))); + +extern void* +malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) +__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); + +extern int +sprintf(char* __restrict __s, const char* __restrict, ...) + __attribute__((__nothrow__)); + +char * +test_1 (const char *a, const char *b) +{ + size_t sz = strlen (a) + strlen (b) + 2; + char *p = (char *) malloc (sz); + if (!p) + return NULL; + sprintf (p, "%s/%s", a, b); + return p; +} + +void +test_2 (const char *a, const char *b) +{ + size_t sz = strlen (a) + strlen (b) + 2; + char *p = (char *) malloc (sz); /* { dg-message "allocated here" } */ + if (!p) + return; + sprintf (p, "%s/%s", a, b); /* { dg-warning "leak of 'p' " } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c b/gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c new file mode 100644 index 0000000..254730b --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c @@ -0,0 +1,68 @@ +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +/* Concatenating a pair of strings. */ + +/* Correct but poor implementation with repeated __builtin_strlen calls. */ + +char * +alloc_dup_of_concatenated_pair_1_correct (const char *x, const char *y) +{ + size_t sz = __builtin_strlen (x) + __builtin_strlen (y) + 1; + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); + result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; + return result; +} + +/* Incorrect version: forgetting to add space for terminator. */ + +char * +alloc_dup_of_concatenated_pair_1_incorrect (const char *x, const char *y) +{ + /* Forgetting to add space for the terminator here. */ + size_t sz = __builtin_strlen (x) + __builtin_strlen (y); + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); + result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ + return result; +} + +/* As above, but only calling __builtin_strlen once on each input. */ + +char * +alloc_dup_of_concatenated_pair_2_correct (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t len_y = __builtin_strlen (y); + size_t sz = len_x + len_y + 1; + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + __builtin_memcpy (result + len_x, y, len_y); + result[len_x + len_y] = '\0'; + return result; +} + +char * +alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t len_y = __builtin_strlen (y); + size_t sz = len_x + len_y; /* Forgetting to add space for the terminator. */ + char *result = (char *) __builtin_malloc (sz); /* { dg-message "capacity: 'len_x \\+ len_y' bytes" "" { target c } } */ + /* { dg-message "capacity: '\\(len_x \\+ len_y\\)' bytes" "" { target c++ } .-1 } */ + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + __builtin_memcpy (result + len_x, y, len_y); + result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return result; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c b/gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c new file mode 100644 index 0000000..d7ec088 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c @@ -0,0 +1,61 @@ +typedef __SIZE_TYPE__ size_t; +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +/* Duplicating a string. */ + +/* Correct but poor implementation with repeated __builtin_strlen calls. */ + +char * +alloc_dup_1_correct (const char *x) +{ + size_t sz = __builtin_strlen (x) + 1; + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + result[__builtin_strlen(x)] = '\0'; + return result; +} + +/* Incorrect version: forgetting to add space for terminator. */ + +char * +alloc_dup_1_incorrect (const char *x, const char *y) +{ + /* Forgetting to add space for the terminator here. */ + size_t sz = __builtin_strlen (x) + 1; + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, __builtin_strlen (x)); + result[__builtin_strlen(x)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ + return result; +} + +/* As above, but only calling __builtin_strlen once. */ + +char * +alloc_dup_2_correct (const char *x) +{ + size_t len_x = __builtin_strlen (x); + size_t sz = len_x + 1; + char *result = (char *) __builtin_malloc (sz); + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + result[len_x] = '\0'; + return result; +} + +char * +alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) +{ + size_t len_x = __builtin_strlen (x); + size_t sz = len_x; /* Forgetting to add space for the terminator. */ + char *result = (char *) __builtin_malloc (sz); /* { dg-message "capacity: 'len_x' bytes" } */ + if (!result) + return NULL; + __builtin_memcpy (result, x, len_x); + result[len_x] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ + return result; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c b/gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c new file mode 100644 index 0000000..bb1ef085 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c @@ -0,0 +1,40 @@ +/* Currently the warning only fires at -O0 + (needs to inline the call without optimizing the + implicit default of the switch). */ + +/* { dg-additional-options "-O0" } */ + +typedef __SIZE_TYPE__ size_t; +int snprintf(char *str, size_t size, const char *format, ...); + +enum usage_kind { + USAGE_ERROR, + USAGE_BUG, +}; + +static void __analyzer_vreportf(enum usage_kind kind) +{ + char buf[256]; + const char *pfx; + + switch (kind) { /* { dg-message "following 'default:' branch" } */ + case USAGE_ERROR: + pfx = "error: "; + break; + case USAGE_BUG: + pfx = "BUG: "; + break; + } + + if (kind == USAGE_BUG) + snprintf(buf, sizeof(buf), "%s%s:%d: ", pfx, "file", 123); + else + snprintf(buf, sizeof(buf), "%s", pfx); /* { dg-warning "uninitialized" } */ +} + +int main(void) +{ + __analyzer_vreportf((enum usage_kind) 42); + + return 0; +} diff --git a/gcc/testsuite/c-c++-common/analyzer/symbolic-12.c b/gcc/testsuite/c-c++-common/analyzer/symbolic-12.c new file mode 100644 index 0000000..26d9d1d --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/symbolic-12.c @@ -0,0 +1,106 @@ +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +void external_fn(void); + +struct st_1 +{ + char *name; + unsigned size; +}; + +void test_1a (void *p, unsigned next_off) +{ + struct st_1 *r = (struct st_1 *) p; + + external_fn(); + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1b (void *p, unsigned next_off) +{ + struct st_1 *r = (struct st_1 *) p; + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1c (struct st_1 *r, unsigned next_off) +{ + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1d (struct st_1 *r, unsigned next_off) +{ + external_fn(); + + if (next_off >= r->size) + return; + + if (next_off >= r->size) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_1e (void *p, unsigned next_off) +{ + struct st_1 *r = (struct st_1 *) p; + + while (1) + { + external_fn(); + + if (next_off >= r->size) + return; + + __analyzer_dump_path (); /* { dg-message "path" } */ + } +} + +struct st_2 +{ + char *name; + unsigned arr[10]; +}; + +void test_2a (void *p, unsigned next_off) +{ + struct st_2 *r = (struct st_2 *) p; + + external_fn(); + + if (next_off >= r->arr[5]) + return; + + if (next_off >= r->arr[5]) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} + +void test_2b (void *p, unsigned next_off, int idx) +{ + struct st_2 *r = (struct st_2 *) p; + + external_fn(); + + if (next_off >= r->arr[idx]) + return; + + if (next_off >= r->arr[idx]) + /* We should have already returned if this is the case. */ + __analyzer_dump_path (); /* { dg-bogus "path" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c b/gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c new file mode 100644 index 0000000..d8c8421 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c @@ -0,0 +1,7 @@ +/* { dg-require-effective-target alloca } */ + +int test_1 (void) +{ + int *p = (int *) __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */ + return *p; /* { dg-warning "use of uninitialized value '\\*p'" } */ +} diff --git a/gcc/testsuite/c-c++-common/analyzer/untracked-2.c b/gcc/testsuite/c-c++-common/analyzer/untracked-2.c new file mode 100644 index 0000000..8c6d9d6 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/untracked-2.c @@ -0,0 +1,7 @@ +typedef unsigned char u8; +extern int foo(const u8 *key, unsigned int keylen); +int test (void) +{ + static const u8 default_salt[64] = {}; + return foo(default_salt, 64); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c b/gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c new file mode 100644 index 0000000..5e8ee9f --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c @@ -0,0 +1,58 @@ +/* { dg-additional-options "-Wno-analyzer-too-complex" } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + + +extern int printf (const char *__restrict __format, ...); +extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, + __builtin_va_list __arg) + __attribute__ ((__nothrow__, __format__ (__printf__, 2, 0))) ; +extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); + +static char * __attribute__ ((__format__ (__printf__, 1, 2))) +zasprintf (const char *format, ...) +{ + char *resultp; + __builtin_va_list args; + __builtin_va_start (args, format); + int r = vasprintf (&resultp, format, args); + __builtin_va_end (args); + return r < 0 ? NULL : resultp; +} + +int run_test() { + char *buf = NULL; + char *bar = NULL; + char *baz = NULL; + int i = 1232; + + printf("static function check\n"); + + buf = zasprintf("i = %d", i); + if (buf) { + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + bar = zasprintf("i = %d - %d", i, i - 13); + if (bar) { + printf("bar = %s\nbar = %p\n", bar, bar); + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + baz = zasprintf("No i's here"); + if (baz) { + printf("baz = %s\nbaz = %p\n", baz, baz); + printf("bar = %s\nbar = %p\n", bar, bar); + printf("buf = %s\nbuf = %p\n", buf, buf); + } + + free(buf); + free(bar); + free(baz); + + return 1; +} + +int main(int argc, char **argv) { + return run_test(); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c new file mode 100644 index 0000000..c74442a --- /dev/null +++ b/gcc/testsuite/c-c++-common/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/c-c++-common/analyzer/write-to-string-literal-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1.c new file mode 100644 index 0000000..46e907a --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1.c @@ -0,0 +1,67 @@ +#include + +#ifdef __cplusplus +#define CONST_CAST(type) const_cast +#else +#define CONST_CAST(type) +#endif + +/* PR analyzer/95007. */ + +void test_1 (void) +{ + char *s = CONST_CAST(char *)("foo"); + s[0] = 'g'; /* { dg-warning "write to string literal" } */ +} + +/* PR c/83347. */ + +void test_2 (void) +{ + // Technically irrelevant for C++ as fpermissive will warn about invalid conversion. + memcpy (CONST_CAST(char *)("abc"), "def", 3); /* { dg-warning "write to string literal" } */ +} + +/* PR c/83347. */ + +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/c-c++-common/analyzer/write-to-string-literal-4-disabled.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c new file mode 100644 index 0000000..868c393 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c @@ -0,0 +1,28 @@ +/* Verify that we can disable warnings that have notes added to them via + region_model_context_decorator::add_note. */ + +/* { dg-additional-options "-Wno-analyzer-write-to-string-literal" } */ + +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-bogus "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void test (int flag) +{ + char *buf; + + if (flag) + buf = (char *) __builtin_malloc (1024); + else + buf = (char *)""; /* { dg-bogus "here" } */ + + if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-bogus "write to string literal" } */ + __builtin_printf("%s\n", buf); + + if (flag) + __builtin_free (buf); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4.c new file mode 100644 index 0000000..971e8f3 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4.c @@ -0,0 +1,26 @@ +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, /* { dg-line getrandom } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +/* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" "" { target c} getrandom } */ +/* { dg-message "parameter 1 of 'int getrandom\\(void\\*, size_t, unsigned int\\)' marked with attribute 'access \\(write_only, 1, 2\\)'" "" { target c++ } getrandom } */ + +#define GRND_RANDOM 0x02 + +void test (int flag) +{ + char *buf; + + if (flag) + buf = (char *) __builtin_malloc (1024); + else + buf = (char *)""; /* { dg-message "here" } */ + + if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-warning "write to string literal" } */ + __builtin_printf("%s\n", buf); + + if (flag) + __builtin_free (buf); +} diff --git a/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c new file mode 100644 index 0000000..a949f15 --- /dev/null +++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c @@ -0,0 +1,34 @@ +/* Verify that deduplication of -Wanalyzer-write-to-string-literal (and their + notes) works. */ + +/* { dg-additional-options "-fanalyzer-show-duplicate-count" } */ +/* { dg-require-effective-target alloca } */ + +#include "../../gcc.dg/analyzer/analyzer-decls.h" + +typedef __SIZE_TYPE__ size_t; + +int getrandom (void *__buffer, size_t __length, + /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" "" { target c } .-1 } */ + /* { dg-message "parameter 1 of 'int getrandom\\(void\\*, size_t, unsigned int\\)' marked with attribute 'access \\(write_only, 1, 2\\)'" "" { target c++ } .-2 } */ + unsigned int __flags) + __attribute__ ((access (__write_only__, 1, 2))); + +#define GRND_RANDOM 0x02 + +void *test (int flag) +{ + char *ptr; + if (flag) + ptr = (char *) __builtin_malloc (1024); + else + ptr = (char *) __builtin_alloca (1024); + + __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ + + if (getrandom((char *)"foo", 3, GRND_RANDOM)) /* { dg-warning "write to string literal" "warning" } */ + /* { dg-message "1 duplicate" "dup" { target *-*-* } .-1 } */ + __builtin_printf("ok\n"); + + return ptr; +} diff --git a/gcc/testsuite/g++.dg/analyzer/analyzer.exp b/gcc/testsuite/g++.dg/analyzer/analyzer.exp index 9551d82..848bea6 100644 --- a/gcc/testsuite/g++.dg/analyzer/analyzer.exp +++ b/gcc/testsuite/g++.dg/analyzer/analyzer.exp @@ -39,6 +39,9 @@ set tests [lsort [glob -nocomplain $srcdir/$subdir/*.C]] g++-dg-runtest $tests "" $DEFAULT_CXXFLAGS +g++-dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/analyzer/*.\[cS\]]] \ + "" $DEFAULT_CXXFLAGS + # All done. dg-finish diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c deleted file mode 100644 index 003077a..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c +++ /dev/null @@ -1,75 +0,0 @@ -#include "analyzer-decls.h" - -#define NULL ((void *)0) - -struct s1 -{ - int f1; -}; - -static struct s1 *p1_glob = NULL; - -void test_1 (struct s1 **pp1, struct s1 *p1_parm) -{ - struct s1 *init_p1_glob = p1_glob; - - __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ - - if (!p1_glob) - return; - - __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ - __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */ - - *pp1 = p1_parm; - - /* The write through *pp1 can't have changed p1_glob, because - we never take a pointer to p1_glob (and it's static to this TU). */ - __analyzer_eval (p1_glob == init_p1_glob); /* { dg-warning "TRUE" } */ - __analyzer_eval (p1_glob != NULL); /* { dg-warning "TRUE" } */ -} - -struct s2 -{ - int f1; -}; - -static struct s2 *p2_glob = NULL; - -void test_2 (struct s2 **pp2, struct s2 *p2_parm) -{ - /* Ensure that p2_glob is modified. */ - p2_glob = __builtin_malloc (sizeof (struct s2)); - if (!p2_glob) - return; - - __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */ - - *pp2 = p2_parm; - - /* The write through *pp2 can't have changed p2_glob, because - we never take a pointer to p2_glob (and it's static to this TU). */ - __analyzer_eval (p2_glob != NULL); /* { dg-warning "TRUE" } */ -} - -struct s3 -{ - int f1; -}; - -struct s3 *p3_glob = NULL; - -void test_3 (struct s3 **pp3, struct s3 *p3_parm) -{ - p3_glob = __builtin_malloc (sizeof (struct s3)); - if (!p3_glob) - return; - - __analyzer_eval (p3_glob != NULL); /* { dg-warning "TRUE" } */ - - *pp3 = p3_parm; - - /* The write through *pp3 could have changed p3_glob, because - another TU could take a pointer to p3_glob. */ - __analyzer_eval (p3_glob != NULL); /* { dg-warning "UNKNOWN" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c b/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c deleted file mode 100644 index afd1492..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c +++ /dev/null @@ -1,5 +0,0 @@ -void foo(char **args[], int *argc) -{ - *argc = 1; - (*args)[0] = __builtin_malloc(42); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c deleted file mode 100644 index 7251665..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c +++ /dev/null @@ -1,59 +0,0 @@ -/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ - -#include - -void test_constant_1 (void) -{ - int32_t *ptr = __builtin_malloc (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ - __builtin_free (ptr); -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_malloc (1); - ^~~~~~~~~~~~~~~~~~~~ - 'test_constant_1': events 1-2 - | - | int32_t *ptr = __builtin_malloc (1); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ - -void test_constant_2 (void) -{ - int32_t *ptr = __builtin_malloc (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ - __builtin_free (ptr); -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_malloc (2); - ^~~~~~~~~~~~~~~~~~~~ - 'test_constant_2': events 1-2 - | - | int32_t *ptr = __builtin_malloc (2); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ - -void test_symbolic (int n) -{ - int32_t *ptr = __builtin_malloc (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ - __builtin_free (ptr); -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_malloc (n * 2); - ^~~~~~~~~~~~~~~~~~~~~~~~ - 'test_symbolic': event 1 - | - | int32_t *ptr = __builtin_malloc (n * 2); - | ^~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 'n * 2' bytes and assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c deleted file mode 100644 index 7cadbb7..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-2.c +++ /dev/null @@ -1,62 +0,0 @@ -/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-fine-grained" } */ -/* { dg-require-effective-target alloca } */ - -#include - -void test_constant_1 (void) -{ - int32_t *ptr = __builtin_alloca (1); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_alloca (1); - ^~~~~~~~~~~~~~~~~~~~ - 'test_constant_1': events 1-2 - | - | int32_t *ptr = __builtin_alloca (1); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 1 byte here - | (2) assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ - -void test_constant_2 (void) -{ - int32_t *ptr = __builtin_alloca (2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_alloca (2); - ^~~~~~~~~~~~~~~~~~~~ - 'test_constant_2': events 1-2 - | - | int32_t *ptr = __builtin_alloca (2); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 2 bytes here - | (2) assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ - -void test_symbolic (int n) -{ - int32_t *ptr = __builtin_alloca (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = __builtin_alloca (n * 2); - ^~~~~~~~~~~~~~~~~~~~~~~~ - 'test_symbolic': events 1-2 - | - | int32_t *ptr = __builtin_alloca (n * 2); - | ^~~~~~~~~~~~~~~~~~~~~~~~ - | | - | (1) allocated 'n * 2' bytes here - | (2) assigned to 'int32_t *' - | - { dg-end-multiline-output "" } */ - -/* FIXME: am getting a duplicate warning here for some reason - without -fanalyzer-fine-grained (PR PR analyzer/107851). */ - diff --git a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-3.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-3.c deleted file mode 100644 index b3de582..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-3.c +++ /dev/null @@ -1,44 +0,0 @@ -/* Verify that we warn for incorrect uses of "alloca" (which may be in a - macro in a system header), and that the output looks correct. */ - -/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret -fanalyzer-fine-grained" } */ -/* { dg-require-effective-target alloca } */ - -#include -#include "test-alloca.h" - -void test_constant_99 (void) -{ - int32_t *ptr = alloca (99); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = alloca (99); - ^~~~~~ - 'test_constant_99': events 1-2 - | - | int32_t *ptr = alloca (99); - | ^~~~~~ - | | - | (1) allocated 99 bytes here - | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | - { dg-end-multiline-output "" } */ - -void test_symbolic (int n) -{ - int32_t *ptr = alloca (n * 2); /* { dg-warning "allocated buffer size is not a multiple of the pointee's size" } */ -} - -/* { dg-begin-multiline-output "" } - int32_t *ptr = alloca (n * 2); - ^~~~~~ - 'test_symbolic': events 1-2 - | - | int32_t *ptr = alloca (n * 2); - | ^~~~~~ - | | - | (1) allocated 'n * 2' bytes here - | (2) assigned to 'int32_t *' {aka '{re:long :re?}int *'} here; 'sizeof (int32_t {aka {re:long :re?}int})' is '4' - | - { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h index a626728..372a136 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer-decls.h @@ -1,6 +1,18 @@ #ifndef ANALYZER_DECLS_H #define ANALYZER_DECLS_H +#ifndef NULL +#ifdef __cplusplus +#if __cplusplus >= 201103L +#define NULL nullptr +#else +#define NULL 0 +#endif +#else +#define NULL ((void *)0) +#endif +#endif + /* Function decls with special meaning to the analyzer. None of these are actually implemented. */ diff --git a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp index af05c98f..cedf3c0 100644 --- a/gcc/testsuite/gcc.dg/analyzer/analyzer.exp +++ b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp @@ -47,6 +47,9 @@ dg-init dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \ "" $DEFAULT_CFLAGS +dg-runtest [lsort [glob -nocomplain $srcdir/c-c++-common/analyzer/*.\[cS\]]] \ + "" $DEFAULT_CFLAGS + # All done. dg-finish diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c deleted file mode 100644 index 8111709..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c +++ /dev/null @@ -1,77 +0,0 @@ -/* Test reduced from use of dynamic_pr_debug on Linux kernel, to verify that - we treat the static struct _ddebug as not needing to be tracked by the - analyzer, thus optimizing away bloat in the analyzer's state tracking. */ - -/* { dg-do compile { target x86_64-*-* } } */ -/* { dg-additional-options "-fdump-analyzer-untracked" } */ - -/* Adapted from various files in the Linux kernel, all of which have: */ -/* SPDX-License-Identifier: GPL-2.0 */ - -typedef _Bool bool; -#define true 1 -#define false 0 - -typedef struct {} atomic_t; - -/* Adapted from include/linux/compiler_attributes.h */ -#define __always_inline inline __attribute__((__always_inline__)) - -/* Adapted from include/linux/compiler-gcc.h */ -#define asm_volatile_goto(x...) do { asm goto(x); asm (""); } while (0) - -/* Adapted from include/linux/jump_label.h, which has: */ - -struct static_key {}; - -/* Adapted from arch/x86/include/asm/jump_label.h */ - -static __always_inline bool arch_static_branch(struct static_key * const key, const bool branch) -{ - asm_volatile_goto("1:" - : : "i" (key), "i" (branch) : : l_yes); - - return false; -l_yes: - return true; -} - -static __always_inline bool arch_static_branch_jump(struct static_key * const key, const bool branch) -{ - asm_volatile_goto("1:" - : : "i" (key), "i" (branch) : : l_yes); - - return false; -l_yes: - return true; -} - -/* Adapted from include/linux/dynamic_debug.h */ - -struct _ddebug { - /* [...snip...] */ - const char *function; - const char *filename; - const char *format; - unsigned int lineno:18; - /* [...snip...] */ - unsigned int flags:8; - struct static_key key; -} __attribute__((aligned(8))); - -extern void __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...); - -static void expanded_dynamic_pr_debug(void) { - do { - static struct _ddebug __attribute__((__aligned__(8))) - __attribute__((__section__("__dyndbg"))) __UNIQUE_ID_ddebug277 = { /* { dg-warning "track '__UNIQUE_ID_ddebug277': no" } */ - .function = __func__, - .filename = __FILE__, - .format = ("hello world"), - .lineno = __LINE__, - .flags = 0}; - if (arch_static_branch(&__UNIQUE_ID_ddebug277.key, false)) - __dynamic_pr_debug(&__UNIQUE_ID_ddebug277, - "hello world"); - } while (0); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c b/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c deleted file mode 100644 index 2864ab6..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c +++ /dev/null @@ -1,34 +0,0 @@ -/* { dg-do compile { target x86_64-*-* } } */ -/* { dg-require-effective-target lp64 } */ - -/* Adapted from Linux x86: page_ref_dec_and_test.c (GPL-2.0). */ - -typedef _Bool bool; - -typedef struct { - int counter; -} atomic_t; - -bool -arch_atomic_dec_and_test(atomic_t *v) { - return ({ - bool c; - asm volatile(".pushsection .smp_locks,\"a\"\n" - ".balign 4\n" - ".long 671f - .\n" - ".popsection\n" - "671:" - "\n\tlock; " - "decl" - " " - "%[var]" - "\n\t/* output condition code " - "e" - "*/\n" - : [ var ] "+m"(v->counter), "=@cc" - "e"(c) - : - : "memory"); - c; - }); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c b/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c deleted file mode 100644 index 72953a5..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Reduced from haproxy-2.7.1's proxy.c */ - -/* { dg-require-effective-target sync_int_long_stack } */ -/* { dg-require-effective-target sync_int_long } */ - -typedef __SIZE_TYPE__ size_t; - -extern void* malloc(size_t __size) - __attribute__((__nothrow__, __leaf__, __malloc__, __alloc_size__(1))); - -extern void free(void* __ptr) __attribute__((__nothrow__, __leaf__)); - -struct error_snapshot -{ - /* [..snip...] */ -}; - -struct proxy -{ - /* [..snip...] */ - struct error_snapshot *invalid_req, *invalid_rep; - /* [..snip...] */ -}; - -extern unsigned int error_snapshot_id; - -void -proxy_capture_error(struct proxy* proxy, - int is_back) -{ - struct error_snapshot* es; - unsigned int ev_id; - - /* [...snip...] */ - - ev_id = __atomic_fetch_add(&error_snapshot_id, 1, 5); - - /* [...snip...] */ - - es = malloc(sizeof(*es)); - if (!es) - return; - - /* [...snip...] */ - - if (is_back) { - es = __atomic_exchange_n(&proxy->invalid_rep, es, 4); /* { dg-bogus "leak" } */ - } else { - es = __atomic_exchange_n(&proxy->invalid_req, es, 4); /* { dg-bogus "leak" } */ - } - - /* [...snip...] */ - - free(es); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c b/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c deleted file mode 100644 index cd90f8f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c +++ /dev/null @@ -1,18 +0,0 @@ -struct foo { - char placeholder[5]; -}; - -void * -test (const char *str) -{ - struct foo *p = __builtin_malloc(sizeof(struct foo)); - if (!p) - return p; - - __builtin_memset(p, 0, sizeof(*p)); - - static int s = 1; - __atomic_store_n(&s, 0, 0); - - return p; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c deleted file mode 100644 index bd28107..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c +++ /dev/null @@ -1,228 +0,0 @@ -/* Adapted from gcc.dg/Wmismatched-dealloc.c. */ - -#define A(...) __attribute__ ((malloc (__VA_ARGS__))) - -typedef struct FILE FILE; -typedef __SIZE_TYPE__ size_t; - -void free (void*); -void* malloc (size_t); -void* realloc (void*, size_t); - -int fclose (FILE*); -FILE* freopen (const char*, const char*, FILE*); -int pclose (FILE*); - -A (fclose) A (freopen, 3) - FILE* fdopen (int); -A (fclose) A (freopen, 3) - FILE* fopen (const char*, const char*); -A (fclose) A (freopen, 3) - FILE* fmemopen(void *, size_t, const char *); -A (fclose) A (freopen, 3) - FILE* freopen (const char*, const char*, FILE*); -A (pclose) A (freopen, 3) - FILE* popen (const char*, const char*); -A (fclose) A (freopen, 3) - FILE* tmpfile (void); - -void sink (FILE*); - - - void release (void*); -A (release) FILE* acquire (void); - -void nowarn_fdopen (void) -{ - { - FILE *q = fdopen (0); - if (!q) - return; - - fclose (q); - } - - { - FILE *q = fdopen (0); - if (!q) - return; - - q = freopen ("1", "r", q); - fclose (q); - } - - { - FILE *q = fdopen (0); - if (!q) - return; - - sink (q); - } -} - - -void warn_fdopen (void) -{ - { - FILE *q = fdopen (0); // { dg-message "allocated here" } - release (q); // { dg-warning "'release' called on 'q' returned from a mismatched allocation function" } - } - { - FILE *q = fdopen (0); // { dg-message "allocated here" } - free (q); // { dg-warning "'free' called on 'q' returned from a mismatched allocation function" } - } - - { - FILE *q = fdopen (0); // { dg-message "allocated here" } - q = realloc (q, 7); // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" } - sink (q); - } -} - - -void nowarn_fopen (void) -{ - { - FILE *q = fopen ("1", "r"); - sink (q); - fclose (q); - } - - { - FILE *q = fopen ("2", "r"); - sink (q); - q = freopen ("3", "r", q); - sink (q); - fclose (q); - } - - { - FILE *q = fopen ("4", "r"); - sink (q); - } -} - - -void warn_fopen (void) -{ - { - FILE *q = fopen ("1", "r"); - release (q); // { dg-warning "'release' called on 'q' returned from a mismatched allocation function" } - fclose (q); - } - { - FILE *q = fdopen (0); - free (q); // { dg-warning "'free' called on 'q' returned from a mismatched allocation function" } - } - - { - FILE *q = fdopen (0); - q = realloc (q, 7); // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" } - sink (q); - } -} - - -void test_popen (void) -{ - { - FILE *p = popen ("1", "r"); - sink (p); - pclose (p); - } - - { - FILE *p; - p = popen ("2", "r"); // { dg-message "allocated here" } - fclose (p); // { dg-warning "'fclose' called on 'p' returned from a mismatched allocation function" } - } - - { - /* freopen() can close a stream open by popen() but pclose() can't - close the stream returned from freopen(). */ - FILE *p = popen ("2", "r"); - p = freopen ("3", "r", p); // { dg-message "allocated here" } - pclose (p); // { dg-warning "'pclose' called on 'p' returned from a mismatched allocation function" } - } -} - - -void test_tmpfile (void) -{ - { - FILE *p = tmpfile (); - fclose (p); - } - - { - FILE *p = tmpfile (); - p = freopen ("1", "r", p); - fclose (p); - } - - { - FILE *p = tmpfile (); // { dg-message "allocated here" } - pclose (p); // { dg-warning "'pclose' called on 'p' returned from a mismatched allocation function" } - } -} - - -void warn_malloc (void) -{ - { - FILE *p = malloc (100); // { dg-message "allocated here" } - fclose (p); // { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'fclose'" } - } - - { - FILE *p = malloc (100); // { dg-message "allocated here" } - p = freopen ("1", "r", p);// { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'freopen'" } - fclose (p); - } - - { - FILE *p = malloc (100); // { dg-message "allocated here" } - pclose (p); // { dg-warning "'p' should have been deallocated with 'free' but was deallocated with 'pclose'" } - } -} - - -void test_acquire (void) -{ - { - FILE *p = acquire (); - release (p); - } - - { - FILE *p = acquire (); - release (p); - } - - { - FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } - fclose (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'fclose'" } - } - - { - FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } - pclose (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'pclose'" } - } - - { - FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } - p = freopen ("1", "r", p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'freopen'" } - sink (p); - } - - { - FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } - free (p); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'free'" } - } - - { - FILE *p = acquire (); // { dg-message "allocated here \\(expects deallocation with 'release'\\)" } - p = realloc (p, 123); // { dg-warning "'p' should have been deallocated with 'release' but was deallocated with 'realloc'" } - sink (p); - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c b/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c deleted file mode 100644 index e086843..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c +++ /dev/null @@ -1,222 +0,0 @@ -/* Adapted from linux 5.3.11: drivers/net/wireless/ath/ath10k/usb.c - Reduced reproducer for CVE-2019-19078 (leak of struct urb). */ - -typedef unsigned char u8; -typedef unsigned short u16; -typedef _Bool bool; - -#define ENOMEM 12 -#define EINVAL 22 - -/* The original file has this licence header. */ - -// SPDX-License-Identifier: ISC -/* - * Copyright (c) 2007-2011 Atheros Communications Inc. - * Copyright (c) 2011-2012,2017 Qualcomm Atheros, Inc. - * Copyright (c) 2016-2017 Erik Stromdahl - */ - -/* Adapted from include/linux/compiler_attributes.h. */ -#define __aligned(x) __attribute__((__aligned__(x))) -#define __printf(a, b) __attribute__((__format__(printf, a, b))) - -/* Possible macro for the new attribute. */ -#define __malloc(f) __attribute__((malloc(f))); - -/* From include/linux/types.h. */ - -typedef unsigned int gfp_t; - -/* Not the real value, which is in include/linux/gfp.h. */ -#define GFP_ATOMIC 32 - -/* From include/linux/usb.h. */ - -struct urb; -extern void usb_free_urb(struct urb *urb); -extern struct urb *usb_alloc_urb(int iso_packets, gfp_t mem_flags) - __malloc(usb_free_urb); -/* attribute added as part of testcase */ - -extern int usb_submit_urb(/*struct urb *urb, */gfp_t mem_flags); -extern void usb_unanchor_urb(struct urb *urb); - -/* From drivers/net/wireless/ath/ath10k/core.h. */ - -struct ath10k; - -struct ath10k { - /* [...many other fields removed...] */ - - /* must be last */ - u8 drv_priv[0] __aligned(sizeof(void *)); -}; - -/* From drivers/net/wireless/ath/ath10k/debug.h. */ - -enum ath10k_debug_mask { - /* [...other values removed...] */ - ATH10K_DBG_USB_BULK = 0x00080000, -}; - -extern unsigned int ath10k_debug_mask; - -__printf(3, 4) void __ath10k_dbg(struct ath10k *ar, - enum ath10k_debug_mask mask, - const char *fmt, ...); - -/* Simplified for now, to avoid pulling in tracepoint code. */ -static inline -bool trace_ath10k_log_dbg_enabled(void) { return 0; } - -#define ath10k_dbg(ar, dbg_mask, fmt, ...) \ -do { \ - if ((ath10k_debug_mask & dbg_mask) || \ - trace_ath10k_log_dbg_enabled()) \ - __ath10k_dbg(ar, dbg_mask, fmt, ##__VA_ARGS__); \ -} while (0) - -/* From drivers/net/wireless/ath/ath10k/hif.h. */ - -struct ath10k_hif_sg_item { - /* [...other fields removed...] */ - void *transfer_context; /* NULL = tx completion callback not called */ -}; - -struct ath10k_hif_ops { - /* send a scatter-gather list to the target */ - int (*tx_sg)(struct ath10k *ar, u8 pipe_id, - struct ath10k_hif_sg_item *items, int n_items); - /* [...other fields removed...] */ -}; - -/* From drivers/net/wireless/ath/ath10k/usb.h. */ - -/* tx/rx pipes for usb */ -enum ath10k_usb_pipe_id { - /* [...other values removed...] */ - ATH10K_USB_PIPE_MAX = 8 -}; - -struct ath10k_usb_pipe { - /* [...all fields removed...] */ -}; - -/* usb device object */ -struct ath10k_usb { - /* [...other fields removed...] */ - struct ath10k_usb_pipe pipes[ATH10K_USB_PIPE_MAX]; -}; - -/* usb urb object */ -struct ath10k_urb_context { - /* [...other fields removed...] */ - struct ath10k_usb_pipe *pipe; - struct sk_buff *skb; -}; - -static inline struct ath10k_usb *ath10k_usb_priv(struct ath10k *ar) -{ - return (struct ath10k_usb *)ar->drv_priv; -} - -/* The source file. */ - -static void ath10k_usb_post_recv_transfers(struct ath10k *ar, - struct ath10k_usb_pipe *recv_pipe); - -struct ath10k_urb_context * -ath10k_usb_alloc_urb_from_pipe(struct ath10k_usb_pipe *pipe); - -void ath10k_usb_free_urb_to_pipe(struct ath10k_usb_pipe *pipe, - struct ath10k_urb_context *urb_context); - -static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id, - struct ath10k_hif_sg_item *items, int n_items) -{ - struct ath10k_usb *ar_usb = ath10k_usb_priv(ar); - struct ath10k_usb_pipe *pipe = &ar_usb->pipes[pipe_id]; - struct ath10k_urb_context *urb_context; - struct sk_buff *skb; - struct urb *urb; - int ret, i; - - for (i = 0; i < n_items; i++) { - urb_context = ath10k_usb_alloc_urb_from_pipe(pipe); - if (!urb_context) { - ret = -ENOMEM; - goto err; - } - - skb = items[i].transfer_context; - urb_context->skb = skb; - - urb = usb_alloc_urb(0, GFP_ATOMIC); /* { dg-message "allocated here" } */ - if (!urb) { - ret = -ENOMEM; - goto err_free_urb_to_pipe; - } - - /* TODO: these are disabled, otherwise we conservatively - assume that they could free urb. */ -#if 0 - usb_fill_bulk_urb(urb, - ar_usb->udev, - pipe->usb_pipe_handle, - skb->data, - skb->len, - ath10k_usb_transmit_complete, urb_context); - if (!(skb->len % pipe->max_packet_size)) { - /* hit a max packet boundary on this pipe */ - urb->transfer_flags |= URB_ZERO_PACKET; - } - - usb_anchor_urb(urb, &pipe->urb_submitted); -#endif - /* TODO: initial argument disabled, otherwise we conservatively - assume that it could free urb. */ - ret = usb_submit_urb(/*urb, */GFP_ATOMIC); - if (ret) { /* TODO: why doesn't it show this condition at default verbosity? */ - ath10k_dbg(ar, ATH10K_DBG_USB_BULK, - "usb bulk transmit failed: %d\n", ret); - - /* TODO: this is disabled, otherwise we conservatively - assume that it could free urb. */ -#if 0 - usb_unanchor_urb(urb); -#endif - - ret = -EINVAL; - /* Leak of urb happens here. */ - goto err_free_urb_to_pipe; - } - - usb_free_urb(urb); /* { dg-bogus "double-'usb_free_urb' of 'urb'" } */ - } - - return 0; - -err_free_urb_to_pipe: - ath10k_usb_free_urb_to_pipe(urb_context->pipe, urb_context); -err: - return ret; /* { dg-warning "leak of 'urb'" } */ -} - -static const struct ath10k_hif_ops ath10k_usb_hif_ops = { - .tx_sg = ath10k_usb_hif_tx_sg, -}; - -/* Simulate code to register the callback. */ -extern void callback_registration (const void *); -int ath10k_usb_probe(void) -{ - callback_registration(&ath10k_usb_hif_ops); -} - - -/* The original source file ends with: -MODULE_AUTHOR("Atheros Communications, Inc."); -MODULE_DESCRIPTION("Driver support for Qualcomm Atheros 802.11ac WLAN USB devices"); -MODULE_LICENSE("Dual BSD/GPL"); -*/ diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c b/gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c deleted file mode 100644 index e1d87c9..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c +++ /dev/null @@ -1,88 +0,0 @@ -// TODO: remove need for this option -/* { dg-additional-options "-fanalyzer-checker=taint" } */ - -#include "analyzer-decls.h" - -struct arg_buf -{ - int i; - int j; -}; - -/* Example of marking a function as tainted. */ - -void __attribute__((tainted_args)) -test_1 (int i, void *p, char *q) -{ - /* There should be a single enode, - for the "tainted" entry to the function. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - - __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", *q); /* { dg-warning "state: 'tainted'" } */ - - struct arg_buf *args = p; - __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'tainted'" } */ -} - -/* Example of marking a callback field as tainted. */ - -struct s2 -{ - void (*cb) (int, void *, char *) - __attribute__((tainted_args)); -}; - -/* Function not marked as tainted. */ - -void -test_2a (int i, void *p, char *q) -{ - /* There should be a single enode, - for the normal entry to the function. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - - __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'start'" } */ - __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'start'" } */ - __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'start'" } */ - - struct arg_buf *args = p; - __analyzer_dump_state ("taint", args->i); /* { dg-warning "state: 'start'" } */ - __analyzer_dump_state ("taint", args->j); /* { dg-warning "state: 'start'" } */ -} - -/* Function referenced via t2b.cb, marked as "tainted". */ - -void -test_2b (int i, void *p, char *q) -{ - /* There should be two enodes - for the direct call, and the "tainted" entry to the function. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ -} - -/* Callback used via t2c.cb, marked as "tainted". */ -void -__analyzer_test_2c (int i, void *p, char *q) -{ - /* There should be a single enode, - for the "tainted" entry to the function. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - - __analyzer_dump_state ("taint", i); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'tainted'" } */ - __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */ -} - -struct s2 t2b = -{ - .cb = test_2b -}; - -struct s2 t2c = -{ - .cb = __analyzer_test_2c -}; diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c b/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c deleted file mode 100644 index 54f442f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c +++ /dev/null @@ -1,83 +0,0 @@ -/* { dg-additional-options "-fanalyzer-call-summaries" } */ - -typedef __SIZE_TYPE__ size_t; -enum { _ISspace = ((5) < 8 ? ((1 << (5)) << 8) : ((1 << (5)) >> 8)) }; -extern const unsigned short int **__ctype_b_loc(void) - __attribute__((__nothrow__, __leaf__, __const__)); -extern void *malloc(size_t __size) - __attribute__((__nothrow__, __leaf__, __malloc__, __alloc_size__(1))); -extern char *strcpy(char *__restrict __dest, const char *__restrict __src) - __attribute__((__nothrow__, __leaf__, __nonnull__(1, 2))); -extern size_t strlen(const char *__s) - __attribute__((__nothrow__, __leaf__, __pure__, __nonnull__(1))); - -struct mydata { - struct mydata *link; - char *name; - char *type; -}; - -static struct mydata *all_data; -static int line_no; - -__attribute__((__noreturn__)) void failed(const char *message); - -static char *string_dup(const char *string) { - char *buf; - - if ((buf = malloc(strlen(string) + 1)) == ((void *)0)) - failed("malloc() failed"); - - return strcpy(buf, string); -} - -static void store_data(const char *name, const char *type) { - struct mydata *p, *q; - - if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0)) - failed("malloc() failed"); - - p->link = ((void *)0); - p->name = string_dup(name); - p->type = string_dup(type); - - if ((q = all_data) == ((void *)0)) - all_data = p; - else { - while (q->link != ((void *)0)) - q = q->link; - q->link = p; - } -} - -static void parse_tbl(char *buffer) { - char *s = buffer; - char *t = s + strlen(s); - - do { - t--; - if (((*__ctype_b_loc())[(int)(((int)*t))] & (unsigned short int)_ISspace)) - *t = '\0'; - else - break; - } while (t > s); - while (((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) - s++; - buffer = s; - - line_no++; - if (*buffer != ';' && *buffer != '\0') { - if (*buffer == '#') { - store_data(buffer, ""); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ - } else { - - while (*s && !((*__ctype_b_loc())[(int)(((int)*s))] & - (unsigned short int)_ISspace)) - s++; - while ( - ((*__ctype_b_loc())[(int)(((int)*s))] & (unsigned short int)_ISspace)) - *s++ = '\0'; - store_data(buffer, s); /* { dg-bogus "leak" "PR analyzer/107158" { xfail *-*-* } } */ - } - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/calloc-1.c b/gcc/testsuite/gcc.dg/analyzer/calloc-1.c deleted file mode 100644 index bc28128..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/calloc-1.c +++ /dev/null @@ -1,27 +0,0 @@ -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *calloc (size_t __nmemb, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1, 2))) ; - -char *test_1 (size_t sz) -{ - char *p; - - p = calloc (1, 3); - if (!p) - return NULL; - - __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ - - __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ - - return p; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c b/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c deleted file mode 100644 index ccf8fe3..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c +++ /dev/null @@ -1,142 +0,0 @@ -#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/coreutils-cksum-pr108664.c b/gcc/testsuite/gcc.dg/analyzer/coreutils-cksum-pr108664.c deleted file mode 100644 index 62698f3..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/coreutils-cksum-pr108664.c +++ /dev/null @@ -1,83 +0,0 @@ -/* { dg-require-effective-target int32plus } */ -/* { dg-require-effective-target size24plus } */ - -/* Reduced from coreutils's cksum.c: cksum_slice8 */ - -typedef long unsigned int size_t; -typedef unsigned int __uint32_t; -typedef unsigned long int __uintmax_t; -typedef struct _IO_FILE FILE; -extern size_t -fread_unlocked(void* __restrict __ptr, - size_t __size, - size_t __n, - FILE* __restrict __stream); -extern int -feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); -extern int -ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); -static __inline __uint32_t -__bswap_32(__uint32_t __bsx) -{ - - return __builtin_bswap32(__bsx); -} -typedef __uint32_t uint32_t; -typedef unsigned long int uint_fast32_t; -typedef __uintmax_t uintmax_t; -extern int* -__errno_location(void) __attribute__((__nothrow__, __leaf__)) -__attribute__((__const__)); -extern uint_fast32_t const crctab[8][256]; - -static _Bool -cksum_slice8(FILE* fp, uint_fast32_t* crc_out, uintmax_t* length_out) -{ - uint32_t buf[(1 << 16) / sizeof(uint32_t)]; - uint_fast32_t crc = 0; - uintmax_t length = 0; - size_t bytes_read; - - if (!fp || !crc_out || !length_out) - return 0; - - while ((bytes_read = fread_unlocked(buf, 1, (1 << 16), fp)) > 0) { - uint32_t* datap; - - if (length + bytes_read < length) { - - (*__errno_location()) = 75; - return 0; - } - length += bytes_read; - - if (bytes_read == 0) { - if (ferror_unlocked(fp)) - return 0; - } - - datap = (uint32_t*)buf; - while (bytes_read >= 8) { - uint32_t first = *datap++, second = *datap++; /* { dg-bogus "use of uninitialized value" "PR analyzer/108664" } */ - crc ^= __bswap_32(first); - second = __bswap_32(second); - crc = - (crctab[7][(crc >> 24) & 0xFF] ^ crctab[6][(crc >> 16) & 0xFF] ^ - crctab[5][(crc >> 8) & 0xFF] ^ crctab[4][(crc)&0xFF] ^ - crctab[3][(second >> 24) & 0xFF] ^ crctab[2][(second >> 16) & 0xFF] ^ - crctab[1][(second >> 8) & 0xFF] ^ crctab[0][(second)&0xFF]); - bytes_read -= 8; - } - - unsigned char* cp = (unsigned char*)datap; - while (bytes_read--) - crc = (crc << 8) ^ crctab[0][((crc >> 24) ^ *cp++) & 0xFF]; - if (feof_unlocked(fp)) - break; - } - - *crc_out = crc; - *length_out = length; - - return 1; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c b/gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c deleted file mode 100644 index 9d13fce..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Reduced from coreutils's sum.c: bsd_sum_stream */ - -typedef long unsigned int size_t; -typedef unsigned char __uint8_t; -typedef unsigned long int __uintmax_t; -typedef struct _IO_FILE FILE; -extern size_t -fread_unlocked(void* __restrict __ptr, - size_t __size, - size_t __n, - FILE* __restrict __stream); -extern int -feof_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); -extern int -ferror_unlocked(FILE* __stream) __attribute__((__nothrow__, __leaf__)); -extern void* -memcpy(void* __restrict __dest, const void* __restrict __src, size_t __n) - __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); -extern void -rpl_free(void*); -extern int* -__errno_location(void) __attribute__((__nothrow__, __leaf__)) -__attribute__((__const__)); -extern void* -malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) -__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); -typedef __uint8_t uint8_t; -typedef __uintmax_t uintmax_t; - -int -bsd_sum_stream(FILE* stream, void* resstream, uintmax_t* length) -{ - int ret = -1; - size_t sum, n; - int checksum = 0; - uintmax_t total_bytes = 0; - static const size_t buffer_length = 32768; - uint8_t* buffer = malloc(buffer_length); - - if (!buffer) - return -1; - - while (1) { - sum = 0; - - while (1) { - n = fread_unlocked(buffer + sum, 1, buffer_length - sum, stream); - sum += n; - - if (buffer_length == sum) - break; - - if (n == 0) { - if (ferror_unlocked(stream)) - goto cleanup_buffer; - goto final_process; - } - - if (feof_unlocked(stream)) - goto final_process; - } - - for (size_t i = 0; i < sum; i++) { - checksum = (checksum >> 1) + ((checksum & 1) << 15); - checksum += buffer[i]; /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */ - checksum &= 0xffff; - } - if (total_bytes + sum < total_bytes) { - - (*__errno_location()) = 75; - goto cleanup_buffer; - } - total_bytes += sum; - } - -final_process:; - - for (size_t i = 0; i < sum; i++) { - checksum = (checksum >> 1) + ((checksum & 1) << 15); - checksum += buffer[i]; /* { dg-bogus "use of uninitialized value" "PR analyzer/108666" } */ - checksum &= 0xffff; - } - if (total_bytes + sum < total_bytes) { - - (*__errno_location()) = 75; - goto cleanup_buffer; - } - total_bytes += sum; - - memcpy(resstream, &checksum, sizeof checksum); - *length = total_bytes; - ret = 0; -cleanup_buffer: - - rpl_free(buffer); - return ret; -} - diff --git a/gcc/testsuite/gcc.dg/analyzer/data-model-11.c b/gcc/testsuite/gcc.dg/analyzer/data-model-11.c deleted file mode 100644 index 2766324..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/data-model-11.c +++ /dev/null @@ -1,6 +0,0 @@ -int test (void) -{ - unsigned char *s = "abc"; - char *t = "xyz"; - return s[1] + t[1]; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c deleted file mode 100644 index d7d873e..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c +++ /dev/null @@ -1,36 +0,0 @@ -extern int could_fail_1 (void); -extern void *could_fail_2 (int); -extern void cleanup (void *); - -struct header { - int signature; -}; - -int test_1 (void) { - int fd, ret = 0; - void *data = ((void *)0); - struct header *hdr; - - fd = could_fail_1 (); - - if (fd < 0) { - ret = -1; - goto cleanup; - } - - data = could_fail_2 (fd); - hdr = data; - - if (hdr->signature != 42) { - ret = -2; - goto cleanup; - } - -cleanup: - if (ret) { - if (data) /* { dg-bogus "check of 'data' for NULL after already dereferencing it" } */ - cleanup (data); - } - - return ret; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c deleted file mode 100644 index 7553f86..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Reduced from git-2.39.0's pack-revindex.c */ - -typedef unsigned int __uint32_t; -typedef unsigned long int __uintmax_t; -typedef long int __off_t; -typedef long int __off64_t; -typedef __SIZE_TYPE__ size_t; -typedef __off64_t off_t; -typedef __uint32_t uint32_t; -typedef __uintmax_t uintmax_t; - -struct stat { - /* [...snip...] */ - __off_t st_size; - /* [...snip...] */ -}; - -extern int close(int __fd); -extern int fstat(int __fd, struct stat *__buf) - __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(2))); -extern uint32_t default_swab32(uint32_t val); -extern uint32_t git_bswap32(uint32_t x); -__attribute__((__noreturn__)) void die(const char *err, ...) - __attribute__((format(printf, 1, 2))); -int error(const char *err, ...) __attribute__((format(printf, 1, 2))); -int error_errno(const char *err, ...) __attribute__((format(printf, 1, 2))); -static inline int const_error(void) { return -1; } -extern int munmap(void *__addr, size_t __len) - __attribute__((__nothrow__, __leaf__)); -extern size_t st_mult(size_t a, size_t b); -extern void *xmmap(void *start, size_t length, int prot, int flags, int fd, - off_t offset); -extern size_t xsize_t(off_t len); - -extern char *gettext(const char *__msgid) __attribute__((__nothrow__, __leaf__)) -__attribute__((__format_arg__(1))); -static inline __attribute__((format_arg(1))) const char *_(const char *msgid) { - if (!*msgid) - return ""; - return gettext(msgid); -} - -struct repository { - /* [...snip...] */ - const struct git_hash_algo *hash_algo; - /* [...snip...] */ -}; -extern struct repository *the_repository; -struct git_hash_algo { - /* [...snip...] */ - size_t rawsz; - /* [...snip...] */ -}; - -int git_open_cloexec(const char *name, int flags); - -struct revindex_header { - uint32_t signature; - uint32_t version; - uint32_t hash_id; -}; - -int load_revindex_from_disk(char *revindex_name, uint32_t num_objects, - const uint32_t **data_p, size_t *len_p) { - int fd, ret = 0; - struct stat st; - void *data = ((void *)0); - size_t revindex_size; - struct revindex_header *hdr; - - fd = git_open_cloexec(revindex_name, 00); - - if (fd < 0) { - ret = -1; - goto cleanup; - } - if (fstat(fd, &st)) { - ret = (error_errno(_("failed to read %s"), revindex_name), const_error()); - goto cleanup; - } - - revindex_size = xsize_t(st.st_size); - - if (revindex_size < ((12) + (2 * the_repository->hash_algo->rawsz))) { - ret = (error(_("reverse-index file %s is too small"), revindex_name), - const_error()); - goto cleanup; - } - - if (revindex_size - ((12) + (2 * the_repository->hash_algo->rawsz)) != - st_mult(sizeof(uint32_t), num_objects)) { - ret = (error(_("reverse-index file %s is corrupt"), revindex_name), - const_error()); - goto cleanup; - } - - data = xmmap(((void *)0), revindex_size, 0x1, 0x02, fd, 0); - hdr = data; - - if (git_bswap32(hdr->signature) != 0x52494458) { - ret = - (error(_("reverse-index file %s has unknown signature"), revindex_name), - const_error()); - goto cleanup; - } - if (git_bswap32(hdr->version) != 1) { - ret = (error(_("reverse-index file %s has unsupported version %" - "u"), - revindex_name, git_bswap32(hdr->version)), - const_error()); - goto cleanup; - } - if (!(git_bswap32(hdr->hash_id) == 1 || git_bswap32(hdr->hash_id) == 2)) { - ret = (error(_("reverse-index file %s has unsupported hash id %" - "u"), - revindex_name, git_bswap32(hdr->hash_id)), - const_error()); - goto cleanup; - } - -cleanup: - if (ret) { - if (data) /* { dg-bogus "check of 'data' for NULL after already dereferencing it" } */ - munmap(data, revindex_size); - } else { - *len_p = revindex_size; - *data_p = (const uint32_t *)data; - } - - if (fd >= 0) - close(fd); - return ret; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c deleted file mode 100644 index fa3beaa..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c +++ /dev/null @@ -1,51 +0,0 @@ -/* Reduced from haproxy-2.7.1: src/tcpcheck.c. */ - -#define NULL ((void *)0) - -int -test_1 (char **args, int cur_arg) -{ - char *p = NULL; - - if (*args[cur_arg]) { - p = args[cur_arg]; - } - - if (p) { /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ - return 1; - } - return 0; -} - -int -test_2 (char **args, int cur_arg) -{ - char *p = NULL; - char *q = NULL; - - if (*args[cur_arg]) { - if (*args[cur_arg + 1]) { - p = args[cur_arg]; - } else { - q = args[cur_arg]; - } - } - - if (p) { /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ - return 1; - } - if (q) { /* { dg-bogus "check of 'q' for NULL after already dereferencing it" } */ - return 2; - } - return 0; -} - -int test_3 (void **pp, int flag) -{ - void *p = NULL; - if (*pp && flag) - p = pp; - if (p) /* { dg-bogus "check of 'p' for NULL after already dereferencing it" } */ - return 1; - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c deleted file mode 100644 index 1180e17..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c +++ /dev/null @@ -1,169 +0,0 @@ -/* Reduced from haproxy-2.7.1: src/tcpcheck.c. */ - -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -extern void *calloc(size_t __nmemb, size_t __size) - __attribute__((__nothrow__, __leaf__)) __attribute__((__malloc__)) - __attribute__((__alloc_size__(1, 2))); -extern char *strdup(const char *__s) __attribute__((__nothrow__, __leaf__)) -__attribute__((__malloc__)) __attribute__((__nonnull__(1))); -extern char *strstr(const char *__haystack, const char *__needle) - __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) - __attribute__((__nonnull__(1, 2))); -extern size_t strlen(const char *__s) __attribute__((__nothrow__, __leaf__)) -__attribute__((__pure__)) __attribute__((__nonnull__(1))); -struct list { - struct list *n; - struct list *p; -}; -struct buffer { - size_t size; - char *area; - size_t data; - size_t head; -}; -struct proxy; -struct ist { - char *ptr; - size_t len; -}; -static inline int isttest(const struct ist ist) { return ist.ptr != NULL; } - -enum http_meth_t { - HTTP_METH_OPTIONS, - /* [...snip...] */ -} __attribute__((packed)); - -struct http_meth { - enum http_meth_t meth; - struct buffer str; -}; -enum tcpcheck_send_type { - /* [...snip...] */ - TCPCHK_SEND_HTTP, -}; -enum tcpcheck_rule_type { - TCPCHK_ACT_SEND = 0, - /* [...snip...] */ -}; -struct tcpcheck_http_hdr { - struct ist name; - struct list value; - struct list list; -}; -struct tcpcheck_send { - enum tcpcheck_send_type type; - union { - /* [...snip...] */ - struct { - unsigned int flags; - struct http_meth meth; - union { - struct ist uri; - /* [...snip...] */ - }; - struct ist vsn; - struct list hdrs; - /* [...snip...] */ - } http; - }; -}; -struct tcpcheck_rule { - /* [...snip...] */ - enum tcpcheck_rule_type action; - /* [...snip...] */ - union { - /* [...snip...] */ - struct tcpcheck_send send; - /* [...snip...] */ - }; -}; -enum http_meth_t find_http_meth(const char *str, const int len); -void free_tcpcheck(struct tcpcheck_rule *rule, int in_pool); -void free_tcpcheck_http_hdr(struct tcpcheck_http_hdr *hdr); - -#define ist(str) ({ \ - char *__x = (void *)(str); \ - (struct ist){ \ - .ptr = __x, \ - .len = __builtin_constant_p(str) ? \ - ((void *)str == (void *)0) ? 0 : \ - __builtin_strlen(__x) : \ - ({ \ - size_t __l = 0; \ - if (__x) for (__l--; __x[++__l]; ) ; \ - __l; \ - }) \ - }; \ -}) - -struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg, - struct proxy *px, char **errmsg) { - struct tcpcheck_rule *chk = NULL; - struct tcpcheck_http_hdr *hdr = NULL; - char *meth = NULL, *uri = NULL, *vsn = NULL; - char *hdrs, *body; - - hdrs = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2], "\r\n") : NULL); - body = (*args[cur_arg + 2] ? strstr(args[cur_arg + 2], "\r\n\r\n") : NULL); - if (hdrs || body) { - /* [...snip...] */ - goto error; - } - - chk = calloc(1, sizeof(*chk)); - if (!chk) { - /* [...snip...] */ - goto error; - } - chk->action = TCPCHK_ACT_SEND; - chk->send.type = TCPCHK_SEND_HTTP; - chk->send.http.flags |= 0x0004; - chk->send.http.meth.meth = HTTP_METH_OPTIONS; - ((&chk->send.http.hdrs)->n = (&chk->send.http.hdrs)->p = - (&chk->send.http.hdrs)); - - if (*args[cur_arg]) { - if (!*args[cur_arg + 1]) - uri = args[cur_arg]; - else - meth = args[cur_arg]; - } - if (*args[cur_arg + 1]) - uri = args[cur_arg + 1]; - if (*args[cur_arg + 2]) - vsn = args[cur_arg + 2]; - - if (meth) { /* { dg-bogus "check of 'meth' for NULL after already dereferencing it" } */ - chk->send.http.meth.meth = find_http_meth(meth, strlen(meth)); - chk->send.http.meth.str.area = strdup(meth); - chk->send.http.meth.str.data = strlen(meth); - if (!chk->send.http.meth.str.area) { - /* [...snip...] */ - goto error; - } - } - if (uri) { - chk->send.http.uri = ist(strdup(uri)); - if (!isttest(chk->send.http.uri)) { - /* [...snip...] */ - goto error; - } - } - if (vsn) { /* { dg-bogus "check of 'vsn' for NULL after already dereferencing it" } */ - chk->send.http.vsn = ist(strdup(vsn)); - if (!isttest(chk->send.http.vsn)) { - /* [...snip...] */ - goto error; - } - } - return chk; - -error: - free_tcpcheck_http_hdr(hdr); - free_tcpcheck(chk, 0); - return NULL; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c deleted file mode 100644 index 4f50882..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c +++ /dev/null @@ -1,92 +0,0 @@ -/* Reduced from haproxy-2.7.1's cfgparse.c. */ - -typedef __SIZE_TYPE__ size_t; - -extern int -strcmp(const char* __s1, const char* __s2) - __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) - __attribute__((__nonnull__(1, 2))); - -extern int -strncmp(const char* __s1, const char* __s2, size_t __n) - __attribute__((__nothrow__, __leaf__)) __attribute__((__pure__)) - __attribute__((__nonnull__(1, 2))); - -enum -{ - /* [...snip...] */ - _ISdigit = ((3) < 8 ? ((1 << (3)) << 8) : ((1 << (3)) >> 8)), - /* [...snip...] */ -}; - -extern const unsigned short int** -__ctype_b_loc(void) __attribute__((__nothrow__, __leaf__)) - __attribute__((__const__)); - -unsigned int str2uic(const char* s); - -char* -memprintf(char** out, const char* format, ...) - __attribute__((format(printf, 2, 3))); - -int -parse_process_number(const char* arg, - unsigned long* proc, - int max, - int* autoinc, - char** err) -{ - if (autoinc) { - *autoinc = 0; - if (strncmp(arg, "auto:", 5) == 0) { - arg += 5; - *autoinc = 1; - } - } - - if (strcmp(arg, "all") == 0) /* { dg-bogus "pointer 'dash' is dereferenced here" } */ - *proc |= ~0UL; - else if (strcmp(arg, "odd") == 0) - *proc |= ~0UL / 3UL; - else if (strcmp(arg, "even") == 0) - *proc |= (~0UL / 3UL) << 1; - else { - const char *p, *dash = ((void*)0); - unsigned int low, high; - - for (p = arg; *p; p++) { - if (*p == '-' && !dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */ - dash = p; - else if (!((*__ctype_b_loc())[(int)(((unsigned char)*p))] & - (unsigned short int)_ISdigit)) { - memprintf(err, "'%s' is not a valid number/range.", arg); - return -1; - } - } - - low = high = str2uic(arg); - if (dash) /* { dg-bogus "check of 'dash' for NULL after already dereferencing it" } */ - high = ((!*(dash + 1)) ? max : str2uic(dash + 1)); - - if (high < low) { - unsigned int swap = low; - low = high; - high = swap; - } - - if (low < 1 || low > max || high > max) { - memprintf(err, - "'%s' is not a valid number/range." - " It supports numbers from 1 to %d.\n", - arg, - max); - return 1; - } - - for (; low <= high; low++) - *proc |= 1UL << (low - 1); - } - *proc &= ~0UL >> (((unsigned int)sizeof(long) * 8) - max); - - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c deleted file mode 100644 index 49b6420..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c +++ /dev/null @@ -1,153 +0,0 @@ -/* Reduced from linux-5.10.162's drivers-base-bus.c */ -/* { dg-additional-options "-fno-delete-null-pointer-checks -O2" } */ - -#define NULL ((void*)0) - -typedef unsigned int __kernel_size_t; -typedef int __kernel_ssize_t; -typedef __kernel_size_t size_t; -typedef __kernel_ssize_t ssize_t; - -struct list_head -{ - struct list_head *next, *prev; -}; - -struct kobject -{ - /* [...snip...] */ -}; - -struct attribute -{ - /* [...snip...] */ -}; - -static inline -void -sysfs_remove_file_ns(struct kobject* kobj, - const struct attribute* attr, - const void* ns) -{ -} - -static inline -void -sysfs_remove_file(struct kobject* kobj, const struct attribute* attr) -{ - sysfs_remove_file_ns(kobj, attr, NULL); -} - -extern struct kobject* -kobject_get(struct kobject* kobj); - -extern void -kobject_put(struct kobject* kobj); - -struct kset -{ - struct list_head list; - /* [...snip...] */ - struct kobject kobj; - /* [...snip...] */ -} __attribute__((__designated_init__)); - -static inline -struct kset* -to_kset(struct kobject* kobj) -{ - return kobj ? ({ - void* __mptr = (void*)(kobj); - ((struct kset*)(__mptr - __builtin_offsetof(struct kset, kobj))); - }) : NULL; -} - -static inline -struct kset* -kset_get(struct kset* k) -{ - return k ? to_kset(kobject_get(&k->kobj)) : NULL; -} - -static inline -void -kset_put(struct kset* k) -{ - kobject_put(&k->kobj); -} - -struct bus_type -{ - /* [...snip...] */ - struct device* dev_root; - /* [...snip...] */ - struct subsys_private* p; - /* [...snip...] */ -}; - -struct bus_attribute -{ - struct attribute attr; - /* [...snip...] */ -}; - -extern void -device_unregister(struct device* dev); - -struct subsys_private -{ - struct kset subsys; - /* [...snip...] */ -}; - -static struct bus_type* -bus_get(struct bus_type* bus) -{ - if (bus) { /* { dg-bogus "check of 'bus' for NULL after already dereferencing it" } */ - kset_get(&bus->p->subsys); - return bus; - } - return NULL; -} - -static void -bus_put(struct bus_type* bus) -{ - if (bus) - kset_put(&bus->p->subsys); -} - -void -bus_remove_file(struct bus_type* bus, struct bus_attribute* attr) -{ - if (bus_get(bus)) { - sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr); - bus_put(bus); - } -} - -extern ssize_t -drivers_autoprobe_show(struct bus_type* bus, char* buf); - -extern ssize_t -drivers_autoprobe_store(struct bus_type* bus, const char* buf, size_t count); - -extern struct bus_attribute bus_attr_drivers_autoprobe; - -static void -remove_probe_files(struct bus_type* bus) -{ - bus_remove_file(bus, &bus_attr_drivers_autoprobe); - /* [...snip...] */ -} - -void -bus_unregister(struct bus_type* bus) -{ - /* [...snip...] */ - if (bus->dev_root) /* { dg-bogus "pointer 'bus' is dereferenced here" } */ - device_unregister(bus->dev_root); - /* [...snip...] */ - remove_probe_files(bus); - /* [...snip...] */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c b/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c deleted file mode 100644 index 1ceea97..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Fixed in r7-2945-g61f46d0e6dd568. - Simplified from gcc/ipa-devirt.c. */ - -#define NULL ((void *)0) -typedef struct odr_type_d { - /* .... */ - int id; - /* .... */ -} *odr_type; -static odr_type **odr_types_ptr; -#define odr_types (*odr_types_ptr) /* { dg-message "pointer 'odr_types_ptr' is dereferenced here" } */ - -int cond, other_cond; - -odr_type some_logic (); - -odr_type -get_odr_type (/* ... */) -{ - /* .... */ - odr_type val = NULL; - /* .... */ - - val = some_logic (); - - /* .... */ - if (cond) - { - /* .... */ - } - else if (other_cond) - { - odr_types[val->id] = 0; /* { dg-message "in expansion of macro 'odr_types'" } */ - /* .... */ - if (odr_types_ptr) /* { dg-warning "check of 'odr_types_ptr' for NULL after already dereferencing it" } */ - { - /* .... */ - val->id = 42; - } - /* .... */ - } - return val; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/exec-1.c b/gcc/testsuite/gcc.dg/analyzer/exec-1.c deleted file mode 100644 index 6b71118..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/exec-1.c +++ /dev/null @@ -1,43 +0,0 @@ -#define NULL ((void *)0) - -extern int execl(const char *pathname, const char *arg, ...); -extern int execlp(const char *file, const char *arg, ...); -extern int execle(const char *pathname, const char *arg, ...); -extern int execv(const char *pathname, char *const argv[]); -extern int execvp(const char *file, char *const argv[]); -extern int execvpe(const char *file, char *const argv[], char *const envp[]); - -int test_execl_ls_al () -{ - return execl ("/usr/bin/ls", "ls", "-al", NULL); -} - -int test_execlpl_ls_al () -{ - return execlp ("ls", "ls", "-al", NULL); -} - -int test_execle_ls_al () -{ - const char *env[3] = {"FOO=BAR", "BAZ", NULL}; - return execl ("/usr/bin/ls", "ls", "-al", NULL, env); -} - -int test_execv_ls_al () -{ - char *argv[3] = {"ls", "-al", NULL}; - return execv ("/usr/bin/ls", argv); -} - -int test_execvp_ls_al () -{ - char *argv[3] = {"ls", "-al", NULL}; - return execvp ("ls", argv); -} - -int test_execvpe_ls_al () -{ - char *env[3] = {"FOO=BAR", "BAZ", NULL}; - char *argv[3] = {"ls", "-al", NULL}; - return execvpe ("ls", argv, env); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c b/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c deleted file mode 100644 index 0c0bd14..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Reduced and adapted from Linux: fs/proc/inode.c: proc_reg_open - (GPL v2.0). */ - -/* Types. */ - -typedef unsigned char u8; -typedef _Bool bool; -typedef unsigned int gfp_t; - -struct file; -struct kmem_cache; -struct proc_dir_entry; - -struct inode { /* [...snip...] */ }; - -enum { - PROC_ENTRY_PERMANENT = 1U << 0, -}; - -struct proc_ops { - /* [...snip...] */ - int (*proc_open)(struct inode *, struct file *); - /* [...snip...] */ - int (*proc_release)(struct inode *, struct file *); - /* [...snip...] */ -}; - -struct proc_dir_entry { - /* [...snip...] */ - struct completion *pde_unload_completion; - /* [...snip...] */ - union { - const struct proc_ops *proc_ops; - const struct file_operations *proc_dir_ops; - }; - /* [...snip...] */ - u8 flags; - /* [...snip...] */ -}; - -struct pde_opener { - /* [...snip...] */ - struct file *file; - /* [...snip...] */ -}; - -struct proc_inode { - /* [...snip...] */ - struct proc_dir_entry *pde; - /* [...snip...] */ - struct inode vfs_inode; -}; - -/* Data. */ - -static struct kmem_cache *pde_opener_cache __attribute__((__section__(".data..ro_after_init"))); - -/* Functions. */ - -void *kmem_cache_alloc(struct kmem_cache *, gfp_t flags) __attribute__((__malloc__)); -void kmem_cache_free(struct kmem_cache *, void *); - -static inline bool pde_is_permanent(const struct proc_dir_entry *pde) -{ - return pde->flags & PROC_ENTRY_PERMANENT; -} - -static inline struct proc_inode *PROC_I(const struct inode *inode) -{ - void *__mptr = (void *)(inode); - return ((struct proc_inode *)(__mptr - __builtin_offsetof(struct proc_inode, vfs_inode))); -} - -static inline struct proc_dir_entry *PDE(const struct inode *inode) -{ - return PROC_I(inode)->pde; -} - -/* We don't want to emit bogus use of uninitialized value 'pdeo' - warnings from -Wanalyzer-use-of-uninitialized-value in this function; - these would require following infeasible paths in which "release" is - first NULL (to avoid the initialization of "pdeo") and then is non-NULL - (to access "pdeo"). - - "release" is sufficiently complicated in this function to hit the - complexity limit for symbolic values during enode exploration. */ - -static int proc_reg_open(struct inode *inode, struct file *file) -{ - struct proc_dir_entry *pde = PDE(inode); - int rv = 0; - typeof(((struct proc_ops*)0)->proc_open) open; - typeof(((struct proc_ops*)0)->proc_release) release; - struct pde_opener *pdeo; - - if (pde_is_permanent(pde)) { - open = pde->proc_ops->proc_open; - if (open) - rv = open(inode, file); - return rv; - } - - /* [...snip...] */ - - release = pde->proc_ops->proc_release; - if (release) { - pdeo = kmem_cache_alloc(pde_opener_cache, - ((( gfp_t)(0x400u|0x800u)) - | (( gfp_t)0x40u) - | (( gfp_t)0x80u))); - if (!pdeo) { - rv = -12; - goto out_unuse; - } - } - - open = pde->proc_ops->proc_open; - if (open) - rv = open(inode, file); - - if (release) { - if (rv == 0) { - - pdeo->file = file; /* { dg-bogus "uninit" } */ - /* [...snip...] */ - } else - kmem_cache_free(pde_opener_cache, pdeo); /* { dg-bogus "uninit" } */ - } - -out_unuse: - /* [...snip...] */ - return rv; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/fields.c b/gcc/testsuite/gcc.dg/analyzer/fields.c deleted file mode 100644 index 0bf877f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/fields.c +++ /dev/null @@ -1,41 +0,0 @@ -typedef __SIZE_TYPE__ size_t; - -extern size_t strlen (const char *__s) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__pure__)) - __attribute__ ((__nonnull__ (1))); - -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) ; - -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -typedef struct _krb5_data { - unsigned int length; - char *data; -} krb5_data; - -typedef struct _krb5_error { - krb5_data text; -} krb5_error; - -extern const char *error_message (int); - -int -recvauth_common (int problem) -{ - if (problem) { - krb5_error error; - const char *message = error_message(problem); - error.text.length = strlen(message) + 1; - if (!(error.text.data = malloc(error.text.length))) { - goto cleanup; - } - free(error.text.data); - } - - cleanup: - return problem; /* { dg-bogus "leak" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c b/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c deleted file mode 100644 index 3c46f28..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c +++ /dev/null @@ -1,42 +0,0 @@ -#define NULL ((void *)0) - -void calling_null_fn_ptr_1 (void) -{ - void (*fn_ptr) (void) = NULL; - fn_ptr (); /* { dg-warning "jump through null pointer" } */ -} - -int calling_null_fn_ptr_2 (void) -{ - int (*fn_ptr) (void) = NULL; - return fn_ptr (); /* { dg-warning "jump through null pointer" } */ -} - -typedef void (*void_void_fn_ptr) (void); - -void calling_const_fn_ptr (void) -{ - void_void_fn_ptr fn_ptr = (void_void_fn_ptr)0xffd2; - return fn_ptr (); -} - -void skipping_init (int flag) -{ - void_void_fn_ptr fn_ptr = NULL; - if (flag) /* { dg-message "branch" } */ - fn_ptr = (void_void_fn_ptr)0xffd2; - fn_ptr (); /* { dg-warning "jump through null pointer" } */ -} - -struct callbacks -{ - void_void_fn_ptr on_redraw; - void_void_fn_ptr on_cleanup; -}; - -void test_callbacks (void) -{ - struct callbacks cb; - __builtin_memset (&cb, 0, sizeof (cb)); - cb.on_cleanup (); /* { dg-warning "jump through null pointer" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c deleted file mode 100644 index d9221fa8..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c +++ /dev/null @@ -1,145 +0,0 @@ -/* Reduced from qemu-7.2.0's qobject/json-parser.c, which - is licensed under LGPLv2.1 or later. */ - -/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */ - -#define NULL ((void *)0) -typedef __builtin_va_list va_list; - -typedef struct _GQueue GQueue; -typedef struct Error Error; -typedef struct QList QList; -typedef struct QObject QObject; - -struct QObjectBase_ { - /* [...snip...] */ -}; - - -struct QObject { - struct QObjectBase_ base; -}; - -#define QOBJECT(obj) ((QObject *)obj) -#define qobject_unref(OBJ) /* [...snip...] */ - -typedef struct QTailQLink { - void *tql_next; - struct QTailQLink *tql_prev; -} QTailQLink; - -struct QList { - struct QObjectBase_ base; - union { - struct QListEntry *tqh_first; - QTailQLink tqh_circ; - } head; -}; -QList *qlist_new(void); -void qlist_append_obj(QList *qlist, QObject *obj); - -typedef enum json_token_type { - /* [...snip...] */ - JSON_LSQUARE, - JSON_RSQUARE, - /* [...snip...] */ - JSON_COMMA, - /* [...snip...] */ - JSON_KEYWORD, - /* [...snip...] */ -} JSONTokenType; -typedef struct JSONToken JSONToken; - -struct JSONToken { - JSONTokenType type; - int x; - int y; - char str[]; -}; - -typedef struct JSONParserContext { - Error *err; - JSONToken *current; - GQueue *buf; - va_list *ap; -} JSONParserContext; -static QObject *parse_value(JSONParserContext *ctxt); - -JSONToken *parser_context_pop_token(JSONParserContext *ctxt); -JSONToken *parser_context_peek_token(JSONParserContext *ctxt); - -static QObject *parse_array(JSONParserContext *ctxt) { - QList *list = NULL; - JSONToken *token, *peek; - - token = parser_context_pop_token(ctxt); - - list = qlist_new(); - - peek = parser_context_peek_token(ctxt); - if (peek == NULL) { - goto out; - } - - if (peek->type != JSON_RSQUARE) { - QObject *obj; - - obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ - if (obj == NULL) { - goto out; - } - - qlist_append_obj(list, obj); - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - goto out; - } - - while (token->type != JSON_RSQUARE) { - if (token->type != JSON_COMMA) { - goto out; - } - - obj = parse_value(ctxt); - if (obj == NULL) { - goto out; - } - - qlist_append_obj(list, obj); - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - goto out; - } - } - } else { - (void)parser_context_pop_token(ctxt); - } - - return QOBJECT(list); - -out: - qobject_unref(list); - return NULL; -} - -QObject *parse_keyword(JSONParserContext *ctxt); - -QObject *parse_value(JSONParserContext *ctxt) { - JSONToken *token; - - token = parser_context_peek_token(ctxt); - if (token == NULL) { - return NULL; - } - - switch (token->type) { - case JSON_LSQUARE: - return parse_array(ctxt); /* { dg-bogus "infinite recursion" } */ - case JSON_KEYWORD: - return parse_keyword(ctxt); - default: - return NULL; - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c deleted file mode 100644 index 58f6d2f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c +++ /dev/null @@ -1,113 +0,0 @@ -struct st1; - -int foo (struct st1 *p); -int bar (struct st1 *p); - -void test_1 (struct st1 *p) -{ - test_1 (p); /* { dg-warning "infinite recursion" } */ -} - -void test_2_if (struct st1 *p) -{ - if (foo (p)) - test_2_if (p); /* { dg-bogus "infinite recursion" } */ -} - -void test_2_switch (struct st1 *p) -{ - switch (foo (p)) - { - case 0 ... 9: - test_2_switch (p); /* { dg-bogus "infinite recursion" } */ - break; - default: - break; - } -} - -void test_2_if_compound (struct st1 *p) -{ - if ((foo (p) + bar (p)) >= 0) - test_2_if_compound (p); /* { dg-bogus "infinite recursion" } */ -} - -void test_3 (struct st1 *p) -{ - foo (p); - test_3 (p); /* { dg-warning "infinite recursion" } */ - /* The content of *p never affects control flow, so we should - report this. */ -} - -struct st2 -{ - int i; -}; - -void test_4 (struct st2 *p) -{ - if (p->i > 0) - test_4 (p); /* { dg-warning "infinite recursion" } */ -} - -void test_5 (struct st2 *p) -{ - if (p->i-- > 0) - test_5 (p); /* { dg-bogus "infinite recursion" } */ -} - -/* Mixtures of heap allocation and recursion. It's not clear what we - should do for such cases, but make sure we don't ICE. */ - -void test_6 (struct st2 *p) -{ - struct st2 *q = __builtin_malloc (p->i); - if (!q) - return; - q->i = p->i; - test_6 (q); - __builtin_free (q); -} - -void test_7 (struct st2 *p) -{ - struct st2 *q = __builtin_malloc (p->i); - q->i = p->i; /* { dg-warning "dereference of possibly-NULL 'q'" } */ - test_7 (q); - __builtin_free (q); -} - -void test_switch_1 (int i) -{ - int j; - switch (i) - { - case 0: - j = 1066; - break; - case 1: - j = 1776; - break; - default: - j = 1492; - break; - } - test_switch_1 (j); /* { dg-warning "infinite recursion" "" { xfail *-*-* } } */ -} - -void test_switch_2 (int i) -{ - switch (i) - { - case 0: - test_switch_2 (1066); - break; - case 1: - test_switch_2 (1776); - break; - default: - test_switch_2 (1492); /* { dg-warning "infinite recursion" "" { xfail *-*-* } } */ - break; - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c b/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c deleted file mode 100644 index b40326f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c +++ /dev/null @@ -1,322 +0,0 @@ -/* Reduced from qemu-7.2.0's qobject/json-parser.c, which - is licensed under LGPLv2.1 or later. */ - -/* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */ - -#define NULL ((void *)0) -typedef __builtin_va_list va_list; -typedef __SIZE_TYPE__ size_t; - -typedef struct _GString GString; -typedef struct _GQueue GQueue; -typedef struct Error Error; -typedef struct QDict QDict; -typedef struct QList QList; -typedef struct QObject QObject; -typedef struct QString QString; - -typedef enum QType { - /* [...snip...] */ - QTYPE_QSTRING, - /* [...snip...] */ -} QType; - -struct QObjectBase_ { - QType type; -}; - -struct QObject { - struct QObjectBase_ base; -}; - -#define QOBJECT(obj) ((QObject *)obj) -#define qobject_unref(OBJ) /* [...snip...] */ - -void qobject_ref_impl(QObject *obj); -QType qobject_type(const QObject *obj); -QObject *qobject_check_type(const QObject *obj, QType type); - -typedef struct QTailQLink { - void *tql_next; - struct QTailQLink *tql_prev; -} QTailQLink; - -typedef struct QDictEntry { - char *key; - QObject *value; - struct { - struct QDictEntry *le_next; - struct QDictEntry **le_prev; - } next; -} QDictEntry; - -struct QDict { - struct QObjectBase_ base; - size_t size; - struct { - struct QDictEntry *lh_first; - } table[512]; -}; - -QDict *qdict_new(void); -void qdict_put_obj(QDict *qdict, const char *key, QObject *value); -int qdict_haskey(const QDict *qdict, const char *key); -typedef struct QListEntry { - QObject *value; - union { - struct QListEntry *tqe_next; - QTailQLink tqe_circ; - } next; -} QListEntry; - -struct QList { - struct QObjectBase_ base; - union { - struct QListEntry *tqh_first; - QTailQLink tqh_circ; - } head; -}; -QList *qlist_new(void); -void qlist_append_obj(QList *qlist, QObject *obj); - -struct QString { - struct QObjectBase_ base; - const char *string; -}; -QString *qstring_from_str(const char *str); -const char *qstring_get_str(const QString *qstring); - -typedef enum json_token_type { - JSON_ERROR = 0, - - JSON_LCURLY = 100, - JSON_MIN = JSON_LCURLY, - JSON_RCURLY, - JSON_LSQUARE, - JSON_RSQUARE, - JSON_COLON, - JSON_COMMA, - JSON_INTEGER, - JSON_FLOAT, - JSON_KEYWORD, - JSON_STRING, - JSON_INTERP, - JSON_END_OF_INPUT, - JSON_MAX = JSON_END_OF_INPUT -} JSONTokenType; -typedef struct JSONToken JSONToken; - -struct JSONToken { - JSONTokenType type; - int x; - int y; - char str[]; -}; - -typedef struct JSONParserContext { - Error *err; - JSONToken *current; - GQueue *buf; - va_list *ap; -} JSONParserContext; -static QObject *parse_value(JSONParserContext *ctxt); - -void __attribute__((__format__(gnu_printf, 3, 4))) -parse_error(JSONParserContext *ctxt, JSONToken *token, const char *msg, ...); - -JSONToken *parser_context_pop_token(JSONParserContext *ctxt); -JSONToken *parser_context_peek_token(JSONParserContext *ctxt); - -static int parse_pair(JSONParserContext *ctxt, QDict *dict) { - QObject *key_obj = NULL; - QString *key; - QObject *value; - JSONToken *peek, *token; - - peek = parser_context_peek_token(ctxt); - if (peek == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - key_obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ - key = ((QString *)qobject_check_type(key_obj, QTYPE_QSTRING)); - if (!key) { - parse_error(ctxt, peek, "key is not a string in object"); - goto out; - } - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - if (token->type != JSON_COLON) { - parse_error(ctxt, token, "missing : in object pair"); - goto out; - } - - value = parse_value(ctxt); - if (value == NULL) { - parse_error(ctxt, token, "Missing value in dict"); - goto out; - } - - if (qdict_haskey(dict, qstring_get_str(key))) { - parse_error(ctxt, token, "duplicate key"); - goto out; - } - - qdict_put_obj(dict, qstring_get_str(key), value); - - qobject_unref(key_obj); - return 0; - -out: - qobject_unref(key_obj); - return -1; -} - -static QObject *parse_object(JSONParserContext *ctxt) { - QDict *dict = NULL; - JSONToken *token, *peek; - - token = parser_context_pop_token(ctxt); - - dict = qdict_new(); - - peek = parser_context_peek_token(ctxt); - if (peek == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - if (peek->type != JSON_RCURLY) { - if (parse_pair(ctxt, dict) == -1) { - goto out; - } - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - while (token->type != JSON_RCURLY) { - if (token->type != JSON_COMMA) { - parse_error(ctxt, token, "expected separator in dict"); - goto out; - } - - if (parse_pair(ctxt, dict) == -1) { - goto out; - } - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - } - } else { - (void)parser_context_pop_token(ctxt); - } - - return QOBJECT(dict); - -out: - qobject_unref (dict); - return NULL; -} - -static QObject *parse_array(JSONParserContext *ctxt) { - QList *list = NULL; - JSONToken *token, *peek; - - token = parser_context_pop_token(ctxt); - - list = qlist_new(); - - peek = parser_context_peek_token(ctxt); - if (peek == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - if (peek->type != JSON_RSQUARE) { - QObject *obj; - - obj = parse_value(ctxt); /* { dg-bogus "infinite recursion" } */ - if (obj == NULL) { - parse_error(ctxt, token, "expecting value"); - goto out; - } - - qlist_append_obj(list, obj); - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - - while (token->type != JSON_RSQUARE) { - if (token->type != JSON_COMMA) { - parse_error(ctxt, token, "expected separator in list"); - goto out; - } - - obj = parse_value(ctxt); - if (obj == NULL) { - parse_error(ctxt, token, "expecting value"); - goto out; - } - - qlist_append_obj(list, obj); - - token = parser_context_pop_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - goto out; - } - } - } else { - (void)parser_context_pop_token(ctxt); - } - - return QOBJECT(list); - -out: - qobject_unref(list); - return NULL; -} - -QObject *parse_keyword(JSONParserContext *ctxt); -QObject *parse_literal(JSONParserContext *ctxt); - -QObject *parse_value(JSONParserContext *ctxt) { - JSONToken *token; - - token = parser_context_peek_token(ctxt); - if (token == NULL) { - parse_error(ctxt, NULL, "premature EOI"); - return NULL; - } - - switch (token->type) { - case JSON_LCURLY: - return parse_object(ctxt); /* { dg-bogus "infinite recursion" } */ - case JSON_LSQUARE: - return parse_array(ctxt); /* { dg-bogus "infinite recursion" } */ - case JSON_INTEGER: - case JSON_FLOAT: - case JSON_STRING: - return parse_literal(ctxt); - case JSON_KEYWORD: - return parse_keyword(ctxt); - default: - parse_error(ctxt, token, "expecting value"); - return NULL; - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/init.c b/gcc/testsuite/gcc.dg/analyzer/init.c deleted file mode 100644 index e51d88e..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/init.c +++ /dev/null @@ -1,136 +0,0 @@ -/* 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/inlining-3-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c deleted file mode 100644 index 15a2dd8..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c +++ /dev/null @@ -1,64 +0,0 @@ -/* As per inlining-3.c, but testing how the ASCII art version of - the path looks. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ -/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -struct input_file_st -{ - char inpname[1]; -}; - -typedef struct input_file_st input_file; - -static inline const char* -get_input_file_name (const input_file *inpf) -{ - if (inpf) - return inpf->inpname; - return NULL; -} - -size_t -test (const input_file *inpf) -{ - const char *f = get_input_file_name (inpf); - return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ -} - -/* { dg-begin-multiline-output "" } - return __builtin_strlen (f); - ^~~~~~~~~~~~~~~~~~~~ - 'test': events 1-2 (depth 1) - | - | test (const input_file *inpf) - | ^~~~ - | | - | (1) entry to 'test' - | - | const char *f = get_input_file_name (inpf); - | ~ - | | - | (2) inlined call to 'get_input_file_name' from 'test' - | - +--> 'get_input_file_name': event 3 (depth 2) - | - | if (inpf) - | ^ - | | - | (3) following 'false' branch (when 'inpf' is NULL)... - | - <------+ - | - 'test': events 4-5 (depth 1) - | - | return __builtin_strlen (f); - | ^~~~~~~~~~~~~~~~~~~~ - | | - | (4) ...to here - | (5) argument 1 ('') NULL where non-null expected - | - { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-3.c b/gcc/testsuite/gcc.dg/analyzer/inlining-3.c deleted file mode 100644 index 7a292ac..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-3.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -struct input_file_st -{ - char inpname[1]; -}; - -typedef struct input_file_st input_file; - -static inline const char* -get_input_file_name (const input_file *inpf) -{ - if (inpf) /* { dg-message "following 'false' branch \\(when 'inpf' is NULL\\)\\.\\.\\. \\(fndecl 'get_input_file_name', depth 2\\)" } */ - return inpf->inpname; - return NULL; -} - -size_t -test (const input_file *inpf) -{ - const char *f = get_input_file_name (inpf); - return __builtin_strlen (f); /* { dg-warning "use of NULL" "warning" } */ - /* { dg-message "NULL where non-null expected \\(fndecl 'test', depth 1\\)" "message" { target *-*-* } .-1 } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c b/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c deleted file mode 100644 index 0413c39..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c +++ /dev/null @@ -1,72 +0,0 @@ -/* As per inlining-4.c, but testing how the ASCII art version of - the path looks. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ -/* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */ - -#define NULL ((void *)0) - -static inline const char* -inner (int flag) -{ - if (flag) - return NULL; - return "foo"; -} - -static inline const char* -middle (int flag) -{ - return inner (flag); -} - -char -outer (int flag) -{ - return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ -} - -/* { dg-begin-multiline-output "" } - return *middle (flag); - ^~~~~~~~~~~~~~ - 'outer': events 1-2 (depth 1) - | - | outer (int flag) - | ^~~~~ - | | - | (1) entry to 'outer' - | - | return *middle (flag); - | ~ - | | - | (2) inlined call to 'middle' from 'outer' - | - +--> 'middle': event 3 (depth 2) - | - | return inner (flag); - | ^ - | | - | (3) inlined call to 'inner' from 'middle' - | - +--> 'inner': event 4 (depth 3) - | - | if (flag) - | ^ - | | - | (4) following 'true' branch (when 'flag != 0')... - | - <-------------+ - | - 'outer': event 5 (depth 1) - | - |cc1: - | (5): ...to here - | - 'outer': event 6 (depth 1) - | - | return *middle (flag); - | ^~~~~~~~~~~~~~ - | | - | (6) dereference of NULL '' - | - { dg-end-multiline-output "" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-4.c b/gcc/testsuite/gcc.dg/analyzer/inlining-4.c deleted file mode 100644 index f4e4208..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/inlining-4.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Verify that we can reconstruct fndecl and stack depth information - after early inlining. */ - -/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */ - -#define NULL ((void *)0) - -static inline const char* -inner (int flag) -{ - if (flag) /* { dg-message "following 'true' branch \\(when 'flag != 0'\\)\\.\\.\\. \\(fndecl 'inner', depth 3\\)" } */ - return NULL; - return "foo"; -} - -static inline const char* -middle (int flag) -{ - return inner (flag); -} - -char -outer (int flag) -{ - return *middle (flag); /* { dg-warning "dereference of NULL" "warning" } */ - /* { dg-message "\\(fndecl 'outer', depth 1\\)" "message" { target *-*-* } .-1 } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c deleted file mode 100644 index 72901e4..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c +++ /dev/null @@ -1,32 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -#define NULL ((void *)0) - -#define LEN 64 - -char ** -epystr_explode(const char *delim, char *str) -{ - char **out = NULL; - int i; - - if (str == NULL || delim == NULL) - return NULL; - - out = __builtin_malloc(LEN * sizeof(char *)); - if (out == NULL) - return NULL; - - for (i = 0; i < LEN; i++) { - out[i] = __builtin_strdup("bla"); - if (out[i] == NULL) /* { dg-bogus "leak" } */ - goto freem; - } - return out; - -freem: - while (--i >= 0) - __builtin_free(out[i]); - __builtin_free(out); - return NULL; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c deleted file mode 100644 index d63be06..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c +++ /dev/null @@ -1,106 +0,0 @@ -/* { dg-additional-options "-fanalyzer-call-summaries" } */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -/* data structures */ - -struct screen_s { - size_t rows; - size_t cols; - char **data; -}; - -struct context_s { - struct screen_s *scr; -}; - -/* global context variable */ - -static struct context_s *ctx; - -/* prototypes */ - -struct screen_s *screen_create(size_t cols, size_t rows); -void screen_destroy(struct screen_s *scr); -void resize_screen(size_t cols, size_t rows); - -/* functions */ - -struct screen_s *screen_create(size_t cols, size_t rows) -{ - struct screen_s *result = NULL; - - result = __builtin_calloc(1, sizeof(*result)); - if (!result) - return NULL; - - result->cols = cols; - result->rows = rows; - - /* make one allocation which will be accessed like a 2D array */ - result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols); - if (!result->data) { - __builtin_free(result); - return NULL; - } - - /* obtain pointer to start of data area */ - char *ptr = (char *)(result->data + rows); - - /* setup pointers for each row of data to allow 2D array access */ - for (size_t row = 0; row < rows; row++) - result->data[row] = (ptr + row * cols); - /* array can now be accessed like data[row][col] */ - - return result; -} - -void screen_destroy(struct screen_s *scr) -{ - if (!scr) - return; - - __builtin_free(scr->data); - - scr->data = NULL; - scr->rows = 0; - scr->cols = 0; - - __builtin_free(scr); -} - -void resize_screen(size_t cols, size_t rows) -{ - /* create a new screen */ - struct screen_s *new_scr = NULL; - new_scr = screen_create(cols, rows); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */ - if (!new_scr) { - return; - } - - /* swap the old screen with the new one */ - struct screen_s *old_scr = ctx->scr; - ctx->scr = new_scr; - - /* omitted: copy the old screen contents to the new screen */ - - /* free the old screen */ - screen_destroy(old_scr); -} - -int main(void) -{ - ctx = __builtin_calloc(1, sizeof(*ctx)); - if (!ctx) - __builtin_abort(); - - ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */ - resize_screen(100, 20); - - /* tidy up and quit */ - screen_destroy(ctx->scr); - __builtin_free(ctx); - ctx = NULL; - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c deleted file mode 100644 index ae7a7d5..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c +++ /dev/null @@ -1,107 +0,0 @@ -/* { dg-additional-options "-fno-analyzer-call-summaries" } */ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -/* data structures */ - -struct screen_s { - size_t rows; - size_t cols; - char **data; -}; - -struct context_s { - struct screen_s *scr; -}; - -/* global context variable */ - -static struct context_s *ctx; - -/* prototypes */ - -struct screen_s *screen_create(size_t cols, size_t rows); -void screen_destroy(struct screen_s *scr); -void resize_screen(size_t cols, size_t rows); - -/* functions */ - -struct screen_s *screen_create(size_t cols, size_t rows) -{ - struct screen_s *result = NULL; - - result = __builtin_calloc(1, sizeof(*result)); - if (!result) - return NULL; - - result->cols = cols; - result->rows = rows; - - /* make one allocation which will be accessed like a 2D array */ - result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols); - if (!result->data) { - __builtin_free(result); - return NULL; - } - - /* obtain pointer to start of data area */ - char *ptr = (char *)(result->data + rows); - - /* setup pointers for each row of data to allow 2D array access */ - for (size_t row = 0; row < rows; row++) - result->data[row] = (ptr + row * cols); - /* array can now be accessed like data[row][col] */ - - return result; -} - -void screen_destroy(struct screen_s *scr) -{ - if (!scr) - return; - - __builtin_free(scr->data); - - scr->data = NULL; - scr->rows = 0; - scr->cols = 0; - - __builtin_free(scr); /* { dg-bogus "leak" } */ -} - -void resize_screen(size_t cols, size_t rows) -{ - /* create a new screen */ - struct screen_s *new_scr = NULL; - new_scr = screen_create(cols, rows); /* { dg-bogus "leak" } */ - if (!new_scr) { - return; - } - - /* swap the old screen with the new one */ - struct screen_s *old_scr = ctx->scr; - ctx->scr = new_scr; - - /* omitted: copy the old screen contents to the new screen */ - - /* free the old screen */ - screen_destroy(old_scr); -} - -int main(void) -{ - ctx = __builtin_calloc(1, sizeof(*ctx)); - if (!ctx) - __builtin_abort(); - - ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" } */ - resize_screen(100, 20); - - /* tidy up and quit */ - screen_destroy(ctx->scr); - __builtin_free(ctx); - ctx = NULL; - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c deleted file mode 100644 index 033ab79..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Reduced from haproxy-2.7.1's cfgparse.c. */ - -typedef __SIZE_TYPE__ size_t; - -extern void* -calloc(size_t __nmemb, size_t __size) - __attribute__((__nothrow__, __leaf__)) - __attribute__((__malloc__)) __attribute__((__alloc_size__(1, 2))); - -struct list -{ - struct list* n; - struct list* p; -}; - -struct cfg_postparser -{ - struct list list; - char* name; - int (*func)(); -}; - -extern struct list postparsers; - -int -cfg_register_postparser(char* name, int (*func)()) -{ - struct cfg_postparser* cp; - - cp = calloc(1, sizeof(*cp)); - if (!cp) { - /* [...snip...] */ - return 0; - } - cp->name = name; - cp->func = func; - - ({ - (&cp->list)->p = (&postparsers)->p; - (&cp->list)->p->n = (&postparsers)->p = (&cp->list); - (&cp->list)->n = (&postparsers); - (&cp->list); - }); - - return 1; /* { dg-bogus "leak of 'cp'" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c b/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c deleted file mode 100644 index 125bce8..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Reduced from haproxy-2.7.1's cfgparse.c. */ - -typedef __SIZE_TYPE__ size_t; - -extern void* -calloc(size_t __nmemb, size_t __size) - __attribute__((__nothrow__, __leaf__)) - __attribute__((__malloc__)) __attribute__((__alloc_size__(1, 2))); - -struct list -{ - struct list* n; - struct list* p; -}; - -struct cfg_postparser -{ - struct list list; - char* name; -}; - -extern struct list postparsers; - -int -test_1 (char* name) -{ - struct cfg_postparser* cp; - - cp = calloc(1, sizeof(*cp)); - if (!cp) { - /* [...snip...] */ - return 0; - } - cp->name = name; - - (&cp->list)->p = (&postparsers)->p; - (&postparsers)->p = (&cp->list); - (&cp->list)->p->n = (&postparsers)->p; - (&cp->list)->n = (&postparsers); - - return 1; /* { dg-bogus "leak of 'cp'" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-2.c b/gcc/testsuite/gcc.dg/analyzer/malloc-2.c deleted file mode 100644 index bb93c53..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/malloc-2.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Tests for precision-of-wording within malloc warnings. */ - -typedef __SIZE_TYPE__ size_t; -extern void *malloc(size_t); -extern void free(void *); -extern char *strcpy(char *__restrict __dest, const char *__restrict __src) - __attribute__((__nothrow__, __leaf__)) __attribute__((__nonnull__(1, 2))); - -void test_1 (void) -{ - void *p = malloc (1024); /* { dg-message "\\(1\\) this call could return NULL" } */ - strcpy ((char *)p, "hello world"); /* { dg-warning "use of possibly-NULL 'p' where non-null expected" "warning" } */ - /* { dg-message "\\(2\\) argument 1 \\('p'\\) from \\(1\\) could be NULL where non-null expected" "event" { target *-*-* } .-1 } */ - free (p); -} - -int *test_2 (void) -{ - int *i = malloc (sizeof (int)); /* { dg-message "\\(1\\) this call could return NULL" } */ - *i = 42; /* { dg-warning "dereference of possibly-NULL 'i'" "warning" } */ - /* { dg-message "\\(2\\) 'i' could be NULL: unchecked value from \\(1\\)" "event" { target *-*-* } .-1 } */ - return i; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c b/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c deleted file mode 100644 index 51e4a69..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c +++ /dev/null @@ -1,8 +0,0 @@ -/* { dg-additional-options "-Wno-stringop-overflow -Wno-analyzer-out-of-bounds" } */ - -void -main (int c, void *v) -{ - static char a[] = ""; - __builtin_memcpy (v, a, -1); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c deleted file mode 100644 index cb46827..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c +++ /dev/null @@ -1,99 +0,0 @@ -/* Reduced from haproxy's src/ssl_sample.c */ - -/* { dg-require-effective-target ptr_eq_long } */ -/* { dg-additional-options "-O2" } */ - -union sample_value { - long long int sint; - /* [...snip...] */ -}; - -struct sample_data { - int type; - union sample_value u; -}; - -enum { - /* [...snip...] */ - SMP_T_BOOL, - /* [...snip...] */ -}; -struct sample { - unsigned int flags; - struct sample_data data; - /* [...snip...] */ - struct session *sess; - struct stream *strm; - /* [...snip...] */ -}; -struct arg { - /* [...snip...] */ -}; -enum obj_type { - OBJ_TYPE_NONE = 0, - /* [...snip...] */ - OBJ_TYPE_CONN, - /* [...snip...] */ - OBJ_TYPE_CHECK, - OBJ_TYPE_ENTRIES -}; -enum { - /* [...snip...] */ - CO_FL_EARLY_SSL_HS = 0x00004000, - CO_FL_EARLY_DATA = 0x00008000, - /* [...snip...] */ - CO_FL_SSL_WAIT_HS = 0x08000000, - /* [...snip...] */ -}; -struct connection { - enum obj_type obj_type; - unsigned char err_code; - /* [...snip...] */ - unsigned int flags; - /* [...snip...] */ -}; - -static inline enum obj_type obj_type(const enum obj_type *t) -{ - if (!t || *t >= OBJ_TYPE_ENTRIES) - return OBJ_TYPE_NONE; - return *t; -} -static inline struct connection *__objt_conn(enum obj_type *t) -{ - return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type))); -} -static inline struct connection *objt_conn(enum obj_type *t) -{ - if (!t || *t != OBJ_TYPE_CONN) - return ((void *)0); - return __objt_conn(t); -} -struct session { - /* [...snip...] */ - enum obj_type *origin; - /* [...snip...] */ -}; -typedef struct ssl_st SSL; -SSL *ssl_sock_get_ssl_object(struct connection *conn); - -/*****************************************************************************/ - -int -smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - SSL *ssl; - struct connection *conn; - - conn = objt_conn(smp->sess->origin); - ssl = ssl_sock_get_ssl_object(conn); - if (!ssl) - return 0; - - smp->flags = 0; - smp->data.type = SMP_T_BOOL; - smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL" "PR analyzer/108251" { xfail *-*-*} } */ - (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0; - - return 1; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c deleted file mode 100644 index fbacb6c..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c +++ /dev/null @@ -1,98 +0,0 @@ -/* Reduced from haproxy's src/ssl_sample.c */ - -/* { dg-require-effective-target ptr_eq_long } */ - -union sample_value { - long long int sint; - /* [...snip...] */ -}; - -struct sample_data { - int type; - union sample_value u; -}; - -enum { - /* [...snip...] */ - SMP_T_BOOL, - /* [...snip...] */ -}; -struct sample { - unsigned int flags; - struct sample_data data; - /* [...snip...] */ - struct session *sess; - struct stream *strm; - /* [...snip...] */ -}; -struct arg { - /* [...snip...] */ -}; -enum obj_type { - OBJ_TYPE_NONE = 0, - /* [...snip...] */ - OBJ_TYPE_CONN, - /* [...snip...] */ - OBJ_TYPE_CHECK, - OBJ_TYPE_ENTRIES -}; -enum { - /* [...snip...] */ - CO_FL_EARLY_SSL_HS = 0x00004000, - CO_FL_EARLY_DATA = 0x00008000, - /* [...snip...] */ - CO_FL_SSL_WAIT_HS = 0x08000000, - /* [...snip...] */ -}; -struct connection { - enum obj_type obj_type; - unsigned char err_code; - /* [...snip...] */ - unsigned int flags; - /* [...snip...] */ -}; - -static inline enum obj_type obj_type(const enum obj_type *t) -{ - if (!t || *t >= OBJ_TYPE_ENTRIES) - return OBJ_TYPE_NONE; - return *t; -} -static inline struct connection *__objt_conn(enum obj_type *t) -{ - return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type))); -} -static inline struct connection *objt_conn(enum obj_type *t) -{ - if (!t || *t != OBJ_TYPE_CONN) - return ((void *)0); - return __objt_conn(t); -} -struct session { - /* [...snip...] */ - enum obj_type *origin; - /* [...snip...] */ -}; -typedef struct ssl_st SSL; -SSL *ssl_sock_get_ssl_object(struct connection *conn); - -/*****************************************************************************/ - -int -smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *private) -{ - SSL *ssl; - struct connection *conn; - - conn = objt_conn(smp->sess->origin); - ssl = ssl_sock_get_ssl_object(conn); - if (!ssl) - return 0; - - smp->flags = 0; - smp->data.type = SMP_T_BOOL; - smp->data.u.sint = ((conn->flags & CO_FL_EARLY_DATA) && /* { dg-bogus "dereference of NULL 'conn'" "PR analyzer/108251" { xfail *-*-*} } */ - (conn->flags & (CO_FL_EARLY_SSL_HS | CO_FL_SSL_WAIT_HS))) ? 1 : 0; - - return 1; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c deleted file mode 100644 index 3ab72c0..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c +++ /dev/null @@ -1,105 +0,0 @@ -/* Reduced from qemu-7.2.0's hw/intc/omap_intc.c */ - -#define NULL ((void*)0) - -typedef unsigned char __uint8_t; -typedef unsigned int __uint32_t; -typedef unsigned long int __uint64_t; -typedef __uint8_t uint8_t; -typedef __uint32_t uint32_t; -typedef __uint64_t uint64_t; -typedef uint64_t hwaddr; -typedef struct omap_intr_handler_s omap_intr_handler; - -struct omap_intr_handler_bank_s -{ - uint32_t irqs; - uint32_t inputs; - uint32_t mask; - uint32_t fiq; - uint32_t sens_edge; - uint32_t swi; - unsigned char priority[32]; -}; - -struct omap_intr_handler_s -{ - /* [...snip...] */ - unsigned char nbanks; - /* [...snip...] */ - int sir_intr[2]; - int autoidle; - uint32_t mask; - struct omap_intr_handler_bank_s bank[3]; -}; - -uint64_t -omap2_inth_read(struct omap_intr_handler_s* s, int offset) -{ - int bank_no, line_no; - struct omap_intr_handler_bank_s* bank = NULL; - - if ((offset & 0xf80) == 0x80) { - bank_no = (offset & 0x60) >> 5; - if (bank_no < s->nbanks) { - offset &= ~0x60; - bank = &s->bank[bank_no]; - } else { - return 0; - } - } - - switch (offset) { - case 0x10: - return (s->autoidle >> 2) & 1; - - case 0x14: - return 1; - - case 0x40: - return s->sir_intr[0]; - - case 0x44: - return s->sir_intr[1]; - - case 0x48: - return (!s->mask) << 2; - - case 0x4c: - return 0; - - case 0x50: - return s->autoidle & 3; - - case 0x80: - return bank->inputs; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ - - case 0x84: - return bank->mask; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ - - case 0x88: - case 0x8c: - return 0; - - case 0x90: - return bank->swi; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ - - case 0x94: - return 0; - - case 0x98: - return bank->irqs & ~bank->mask & ~bank->fiq; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ - - case 0x9c: - return bank->irqs & ~bank->mask & bank->fiq; /* { dg-bogus "dereference of NULL 'bank'" "PR analyzer/108806" } */ - - case 0x100 ... 0x300: - bank_no = (offset - 0x100) >> 7; - if (bank_no > s->nbanks) - break; - bank = &s->bank[bank_no]; - line_no = (offset & 0x7f) >> 2; - return (bank->priority[line_no] << 2) | ((bank->fiq >> line_no) & 1); - } - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c b/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c deleted file mode 100644 index 417ab00..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Reduced from apr-1.7.0/tables/apr_hash.c: 'apr_hash_merge' */ - -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -#define NULL ((void*)0) - -typedef __SIZE_TYPE__ size_t; - -extern void* -memset(void* __s, int __c, size_t __n) - __attribute__((__nothrow__, __leaf__, __nonnull__(1))); - -typedef struct apr_pool_t apr_pool_t; - -void* -apr_palloc(apr_pool_t* p, size_t size) - __attribute__((alloc_size(2), nonnull(1))); - -typedef struct apr_hash_t apr_hash_t; -typedef struct apr_hash_index_t apr_hash_index_t; -typedef unsigned int (*apr_hashfunc_t)(const char* key, size_t* klen); -typedef struct apr_hash_entry_t apr_hash_entry_t; - -struct apr_hash_entry_t -{ - apr_hash_entry_t* next; - unsigned int hash; - const void* key; - size_t klen; - const void* val; -}; - -struct apr_hash_t -{ - apr_pool_t* pool; - apr_hash_entry_t** array; - /* [...snip.../ */ - unsigned int count, max, seed; - apr_hashfunc_t hash_func; - apr_hash_entry_t* free; -}; - -static apr_hash_entry_t** -alloc_array(apr_hash_t* ht, unsigned int max) -{ - return memset(apr_palloc(ht->pool, sizeof(*ht->array) * (max + 1)), - 0, - sizeof(*ht->array) * (max + 1)); -} - -apr_hash_t* -apr_hash_merge(apr_pool_t* p, - const apr_hash_t* overlay, - const apr_hash_t* base) -{ - apr_hash_t* res; - apr_hash_entry_t* new_vals = NULL; - apr_hash_entry_t* iter; - unsigned int i, j, k; - res = apr_palloc(p, sizeof(apr_hash_t)); - res->pool = p; - res->free = NULL; - res->hash_func = base->hash_func; - res->count = base->count; - res->max = (overlay->max > base->max) ? overlay->max : base->max; - if (base->count + overlay->count > res->max) { - res->max = res->max * 2 + 1; - } - res->seed = base->seed; - res->array = alloc_array(res, res->max); - if (base->count + overlay->count) { - new_vals = - apr_palloc(p, sizeof(apr_hash_entry_t) * (base->count + overlay->count)); - } - j = 0; - for (k = 0; k <= base->max; k++) { - for (iter = base->array[k]; iter; iter = iter->next) { - i = iter->hash & res->max; - /* We should only warn for the first of these - (it's actually a false positive, but we don't have the - invariante to know that). */ - new_vals[j].klen = iter->klen; /* { dg-warning "dereference of NULL 'new_vals'" } */ - /* ...but not for subsequent ones: */ - new_vals[j].key = iter->key; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ - new_vals[j].val = iter->val; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ - new_vals[j].hash = iter->hash; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ - new_vals[j].next = res->array[i]; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ - res->array[i] = &new_vals[j]; /* { dg-bogus "dereference of NULL 'new_vals'" "PR analyzer/108830" } */ - j++; - } - } - /* [...snip...] */ - return res; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/gcc.dg/analyzer/pr101962.c deleted file mode 100644 index 5eb7cf0..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c +++ /dev/null @@ -1,52 +0,0 @@ -#include "analyzer-decls.h" - -#define NULL ((void *)0) - -/* Verify that the analyzer makes the simplifying assumption that we don't - hit NULL when incrementing pointers to non-NULL memory regions. */ - -static int * __attribute__((noinline)) -maybe_inc_int_ptr (int *ptr) -{ - if (!ptr) - return NULL; - return ++ptr; -} - -int -test_1 (void) -{ - int stack; - int *a = &stack; - a = maybe_inc_int_ptr (a); - a = maybe_inc_int_ptr (a); - __analyzer_eval (a == NULL); /* { dg-warning "FALSE" } */ - __analyzer_eval (a != NULL); /* { dg-warning "TRUE" } */ - return *a; /* { dg-line test_1 } */ - - /* { dg-warning "stack-based buffer over-read" "warning" { target *-*-* } test_1 } */ -} - -static const char * __attribute__((noinline)) -maybe_inc_char_ptr (const char *ptr) -{ - if (!ptr) - return NULL; - return ++ptr; -} - -char -test_s (void) -{ - const char *msg = "hello world"; - const char *a = msg; - __analyzer_eval (*a == 'h'); /* { dg-warning "TRUE" } */ - a = maybe_inc_char_ptr (a); - __analyzer_eval (*a == 'e'); /* { dg-warning "TRUE" } */ - a = maybe_inc_char_ptr (a); - __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ - a = maybe_inc_char_ptr (a); - __analyzer_eval (*a == 'l'); /* { dg-warning "TRUE" } */ - a = maybe_inc_char_ptr (a); - __analyzer_eval (*a == 'o'); /* { dg-warning "TRUE" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103217-2.c b/gcc/testsuite/gcc.dg/analyzer/pr103217-2.c deleted file mode 100644 index aa8bca7..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr103217-2.c +++ /dev/null @@ -1,54 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -typedef __SIZE_TYPE__ size_t; - -extern void *calloc (size_t __nmemb, size_t __size) - __attribute__ ((__nothrow__ , __leaf__, __malloc__, __alloc_size__ (1, 2))); - -extern char *strdup (const char *__s) - __attribute__ ((__nothrow__ , __leaf__, __malloc__, __nonnull__ (1))); - -extern void abort (void) - __attribute__ ((__nothrow__ , __leaf__, __noreturn__)); - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __attribute__ ((__nothrow__ , __leaf__, __nonnull__ (2, 3))); -extern char *optarg; - -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -char *xstrdup(const char *src) { - char *val = strdup(src); - if (!val) - abort(); - return val; -} - -struct test { - char *one, *two; -}; - -int main(int argc, char *argv[]) { - struct test *options = calloc(1, sizeof(*options)); - int rc; - if (!options) - abort(); - - while ((rc = getopt(argc, argv, "a:b:")) != -1) { - switch (rc) { - case 'a': - free(options->one); - options->one = xstrdup(optarg); - break; - case 'b': - free(options->two); - options->two = xstrdup(optarg); - break; - } - } - free(options->one); - free(options->two); - free(options); - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103217.c b/gcc/testsuite/gcc.dg/analyzer/pr103217.c deleted file mode 100644 index 08889ac..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr103217.c +++ /dev/null @@ -1,44 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -extern char *strdup (const char *__s) - __attribute__ ((__nothrow__ , __leaf__, __malloc__, __nonnull__ (1))); - -extern void abort (void) - __attribute__ ((__nothrow__ , __leaf__, __noreturn__)); - -extern int getopt (int ___argc, char *const *___argv, const char *__shortopts) - __attribute__ ((__nothrow__ , __leaf__, __nonnull__ (2, 3))); -extern char *optarg; - -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -#define NULL ((void *)0) - -char *xstrdup(const char *src) { - char *val = strdup(src); - if (!val) - abort(); - return val; -} - -int main(int argc, char *argv[]) { - char *one = NULL, *two = NULL; - int rc; - - while ((rc = getopt(argc, argv, "a:b:")) != -1) { - switch (rc) { - case 'a': - free(one); - one = xstrdup(optarg); - break; - case 'b': - free(two); - two = xstrdup(optarg); - break; - } - } - free(one); - free(two); - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104029.c b/gcc/testsuite/gcc.dg/analyzer/pr104029.c deleted file mode 100644 index adf15ed..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr104029.c +++ /dev/null @@ -1,115 +0,0 @@ -// TODO: remove need for this option -/* { dg-additional-options "-fanalyzer-checker=taint" } */ - -typedef __SIZE_TYPE__ size_t; -typedef const void *t_comptype; -typedef int (*t_compfunc)(t_comptype, t_comptype); - -extern int *__errno_location(void) - __attribute__((__nothrow__, __leaf__,__const__)); -extern void free(void *__ptr) - __attribute__((__nothrow__, __leaf__)); -extern void *my_malloc1(const char *file, int line, size_t size); - -int heapsort(void *vbase, size_t nmemb, size_t size, t_compfunc compar) { - char tmp, *tmp1, *tmp2, *abase, *k, *p, *t; - size_t cnt, i, j, l; - - if (nmemb <= 1) - return (0); - - if (!size) { - (*__errno_location()) = 22; - return (-1); - } - - k = my_malloc1(__FILE__, __LINE__, size); - - abase = (char *)vbase - size; - - for (l = nmemb / 2 + 1; --l;) { - for (i = l; (j = i * 2) <= nmemb; i = j) { - p = abase + j * size; - if (j < nmemb && compar(p, p + size) < 0) { - p += size; - ++j; - } - t = abase + i * size; - if (compar(p, t) <= 0) - break; - { - cnt = size; - do { - tmp = *t; - *t++ = *p; - *p++ = tmp; - } while (--cnt); - }; - } - }; - - while (nmemb > 1) { - { - cnt = size; - tmp1 = k; - tmp2 = abase + nmemb * size; - do { - *tmp1++ = *tmp2++; - } while (--cnt); - }; - { - cnt = size; - tmp1 = abase + nmemb * size; - tmp2 = abase + size; - do { - *tmp1++ = *tmp2++; - } while (--cnt); - }; - --nmemb; - { - for (i = 1; (j = i * 2) <= nmemb; i = j) { - p = abase + j * size; - if (j < nmemb && compar(p, p + size) < 0) { - p += size; - ++j; - } - t = abase + i * size; - { - cnt = size; - tmp1 = t; - tmp2 = p; - do { - *tmp1++ = *tmp2++; - } while (--cnt); - }; - } - for (;;) { - j = i; - i = j / 2; - p = abase + j * size; - t = abase + i * size; - if (j == 1 || compar(k, t) < 0) { - { - cnt = size; - tmp1 = p; - tmp2 = k; - do { - *tmp1++ = *tmp2++; - } while (--cnt); - }; - break; - } - { - cnt = size; - tmp1 = p; - tmp2 = t; - do { - *tmp1++ = *tmp2++; - } while (--cnt); - }; - } - }; - } - free(k); - return (0); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104062.c b/gcc/testsuite/gcc.dg/analyzer/pr104062.c deleted file mode 100644 index 7129c27..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr104062.c +++ /dev/null @@ -1,13 +0,0 @@ -void * -calloc (__SIZE_TYPE__, __SIZE_TYPE__); - -void * -realloc (void *, __SIZE_TYPE__); - -void -foo (void) -{ - int *ap5 = calloc (4, sizeof *ap5); - int *ap7 = realloc (ap5, sizeof *ap5); -} /* { dg-warning "leak of 'ap5'" "leak of ap5" } */ -/* { dg-warning "leak of 'ap7'" "leak of ap7" { target *-*-* } .-1 } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c b/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c index c05137b..4a01b8c 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c @@ -1,5 +1,7 @@ /* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-fd-leak" } */ // TODO: remove need for these options +/* C only: C++ does not support transparent_union. */ + typedef __SIZE_TYPE__ size_t; #define NULL ((void *)0) @@ -61,7 +63,7 @@ int main() { struct sockaddr_un remote; socklen_t len = sizeof(remote); - pollfds = calloc(1, sizeof(struct pollfd)); + pollfds = (struct pollfd *) calloc(1, sizeof(struct pollfd)); if (!pollfds) { exit(1); } @@ -74,12 +76,13 @@ int main() { if (pollfds[0].revents & POLLIN) { nsockets++; - newpollfds = realloc(pollfds, nsockets * sizeof(*pollfds)); + newpollfds = (struct pollfd *) realloc(pollfds, nsockets * sizeof(*pollfds)); if (!newpollfds) { exit(1); } pollfds = newpollfds; pollfds[nsockets - 1].fd = accept(pollfds[0].fd, &remote, &len); + /* { dg-error "could not convert '& remote' from 'sockaddr_un*' to '__SOCKADDR_ARG'" "G++ doesn't support transparent_union" { target c++ } .-1 } */ } } return 0; diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c b/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c index 93d9987..0121d1f 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c @@ -1,5 +1,6 @@ /* { dg-additional-options "-Wno-analyzer-fd-leak" } */ // TODO: remove need for this option +/* C only: C++ does not support transparent_union. */ typedef __SIZE_TYPE__ size_t; #define NULL ((void *)0) @@ -61,7 +62,7 @@ int main() { struct sockaddr_un remote; socklen_t len = sizeof(remote); - pollfds = calloc(1, sizeof(struct pollfd)); + pollfds = (struct pollfd *) calloc(1, sizeof(struct pollfd)); if (!pollfds) { exit(1); } @@ -72,11 +73,13 @@ int main() { } nsockets++; - newpollfds = realloc(pollfds, nsockets * sizeof(*pollfds)); + newpollfds = (struct pollfd *) realloc(pollfds, nsockets * sizeof(*pollfds)); if (!newpollfds) { exit(3); } pollfds = newpollfds; pollfds[nsockets - 1].fd = accept(pollfds[0].fd, &remote, &len); + /* { dg-error "could not convert '& remote' from 'sockaddr_un*' to '__SOCKADDR_ARG'" "G++ doesn't support transparent_union" { target c++ } .-1 } */ + exit(4); } diff --git a/gcc/testsuite/gcc.dg/analyzer/pr105783.c b/gcc/testsuite/gcc.dg/analyzer/pr105783.c deleted file mode 100644 index 00f44d0..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr105783.c +++ /dev/null @@ -1,26 +0,0 @@ -/* { dg-additional-options "-O" } */ - -struct ss_s { - union out_or_counting_u { - char *newstr; - unsigned long long cnt; - } uu; - _Bool counting; -}; - -struct ss_s ss_init(void) { - struct ss_s rr = { .counting = 1 }; - return rr; -} - -void ss_out(struct ss_s *t, char cc) { - if (!t->counting) { - *t->uu.newstr++ = cc; - } -} - -int main() { - struct ss_s ss = ss_init(); - ss_out(&ss, 'a'); -} - diff --git a/gcc/testsuite/gcc.dg/analyzer/pr107345.c b/gcc/testsuite/gcc.dg/analyzer/pr107345.c deleted file mode 100644 index 540596d..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr107345.c +++ /dev/null @@ -1,17 +0,0 @@ -/* Ensure the analyzer treats (NULL == &e) as being false for this case, - where the logic is sufficiently complicated to not be optimized away. */ - -#include - -int main() { - int e = 10086; - int *f = &e; - int g = 0; - int *h[2][1]; - h[1][0] = f; - if (g == (h[1][0])) { /* { dg-warning "comparison between pointer and integer" } */ - unsigned int *i = 0; - } - printf("NPD_FLAG: %d\n ", *f); - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr61861.c b/gcc/testsuite/gcc.dg/analyzer/pr61861.c index a85e743..b03f510 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr61861.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr61861.c @@ -1,2 +1,3 @@ /* { dg-additional-options "-Wno-int-conversion" } */ -#include "../pr61861.c" +/* { C only: Wno-int-conversion is not valid for C++. */ +#include "../../gcc.dg/pr61861.c" diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility-2.c b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility-2.c index 1484297..df14bea 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility-2.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr93355-localealias-feasibility-2.c @@ -6,7 +6,6 @@ #include "analyzer-decls.h" -#define NULL ((void *) 0) #define PATH_SEPARATOR ':' #define LOCALE_ALIAS_PATH "value for LOCALE_ALIAS_PATH" diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93457.c b/gcc/testsuite/gcc.dg/analyzer/pr93457.c deleted file mode 100644 index b77911b..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr93457.c +++ /dev/null @@ -1,10 +0,0 @@ -/* { dg-do compile } */ - -void -p5 (const void *); - -void -s5 (const void *cl) -{ - p5 (&cl[1]); /* { dg-warning "dereferencing 'void \\*' pointer" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c b/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c deleted file mode 100644 index e0500c4..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c +++ /dev/null @@ -1,53 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ -/* TODO: remove the need for this option (PR analyzer/93695). */ - -#define NELEMS 10 -#define ARRAY_SIZE(a) (sizeof (a) / sizeof (a[0])) - -void -test_1 (void) -{ - int *p[NELEMS]; - int i; - - for (i = 0; i < ARRAY_SIZE (p); ++i) - p[i] = __builtin_malloc (sizeof (i)); - - for (i = 0; i < ARRAY_SIZE (p); ++i) - __builtin_free (p [i]); -} - -void -test_2 (int n) -{ - int **p; - int i; - - p = (int **)__builtin_malloc (sizeof (int *) * n); - if (!p) - return; - - for (i = 0; i < n; ++i) - p[i] = __builtin_malloc (sizeof (i)); - - for (i = 0; i < n; ++i) - __builtin_free (p [i]); - - __builtin_free (p); -} - -void -test_3 (int **p, int n) -{ - int i; - for (i = 0; i < n; ++i) - p[i] = __builtin_malloc (sizeof (i)); -} - -void -test_4 (void **p, int n) -{ - int i; - for (i = 0; i < n; ++i) - __builtin_free (p[i]); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94596.c b/gcc/testsuite/gcc.dg/analyzer/pr94596.c deleted file mode 100644 index 055d209..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr94596.c +++ /dev/null @@ -1,97 +0,0 @@ -/* Minimized/hacked up from openvswitch lib/conntrack.c, which had this license - header: */ -/* - * Copyright (c) 2015-2019 Nicira, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at: - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) -#define false 0 - -#define OBJECT_OFFSETOF(OBJECT, MEMBER)\ - __builtin_offsetof(typeof(*(OBJECT)), MEMBER) - -#define OBJECT_CONTAINING(POINTER, OBJECT, MEMBER) \ - ((typeof(OBJECT)) (void *) \ - ((char *) (POINTER) - OBJECT_OFFSETOF(OBJECT, MEMBER))) - -#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \ - ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), (void) 0) - -#define INIT_CONTAINER(OBJECT, POINTER, MEMBER) \ - ((OBJECT) = NULL, ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER)) - -#define HMAP_FOR_EACH_POP(NODE, MEMBER, HMAP) \ - for (size_t bucket__ = 0; \ - INIT_CONTAINER(NODE, hmap_pop_helper__(HMAP, &bucket__), MEMBER), \ - (NODE != OBJECT_CONTAINING(NULL, NODE, MEMBER)) \ - || ((NODE = NULL), false);) - -struct hmap { - struct hmap_node **buckets; - struct hmap_node *one; - size_t mask; - size_t n; -}; - -struct hmap_node { - size_t hash; - struct hmap_node *next; -}; - -static inline void hmap_remove(struct hmap *, struct hmap_node *); - -struct hmap_node * -hmap_pop_helper__(struct hmap *hmap, size_t *bucket) { - - for (; *bucket <= hmap->mask; (*bucket)++) { - struct hmap_node *node = hmap->buckets[*bucket]; - - if (node) { - hmap_remove(hmap, node); - return node; - } - } - - return NULL; -} - -static inline void -hmap_remove(struct hmap *hmap, struct hmap_node *node) -{ - struct hmap_node **bucket = &hmap->buckets[node->hash & hmap->mask]; - while (*bucket != node) { - bucket = &(*bucket)->next; - } - *bucket = node->next; - hmap->n--; -} - -struct conntrack { - struct hmap zone_limits; -}; - -struct zone_limit { - struct hmap_node node; -}; - -void -conntrack_destroy(struct conntrack *ct) -{ - struct zone_limit *zl; - HMAP_FOR_EACH_POP (zl, node, &ct->zone_limits) { - __builtin_free(zl); - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94839.c b/gcc/testsuite/gcc.dg/analyzer/pr94839.c deleted file mode 100644 index 46c8bb9..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr94839.c +++ /dev/null @@ -1,20 +0,0 @@ -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/pr95152-4.c b/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c index f2a72ca..579e360 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c @@ -1,4 +1,6 @@ /* { dg-additional-options "-Wno-pointer-to-int-cast" } */ +/* { C only: Wno-pointer-to-int-cast is not valid for C++. */ + extern void my_func (int); typedef struct { int var; @@ -6,6 +8,6 @@ typedef struct { extern void *_data_offs; void test() { - info_t *info = ((void *)((void *)1) + ((unsigned int)&_data_offs)); + info_t *info = (info_t *) ((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 index 604b784..f40d9eb 100644 --- a/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c +++ b/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c @@ -1,4 +1,5 @@ /* { dg-additional-options "-Wno-incompatible-pointer-types" } */ +/* { C only: Wno-incompatible-pointer-types' is not valid for C++. */ void foo(void) { void (*a[1]) (); diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95240.c b/gcc/testsuite/gcc.dg/analyzer/pr95240.c deleted file mode 100644 index c84c64d..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr95240.c +++ /dev/null @@ -1,27 +0,0 @@ -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/pr96639.c b/gcc/testsuite/gcc.dg/analyzer/pr96639.c deleted file mode 100644 index aedf046..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr96639.c +++ /dev/null @@ -1,10 +0,0 @@ -void *calloc (__SIZE_TYPE__, __SIZE_TYPE__); - -int -x7 (void) -{ - int **md = calloc (1, sizeof (void *)); - - return md[0][0]; /* { dg-warning "possibly-NULL" "unchecked deref" } */ - /* { dg-warning "leak of 'md'" "leak" { target *-*-* } .-1 } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96653.c b/gcc/testsuite/gcc.dg/analyzer/pr96653.c deleted file mode 100644 index e5e387c..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr96653.c +++ /dev/null @@ -1,1104 +0,0 @@ -/* 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/pr96792.c b/gcc/testsuite/gcc.dg/analyzer/pr96792.c deleted file mode 100644 index 7757645..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr96792.c +++ /dev/null @@ -1,39 +0,0 @@ -#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 deleted file mode 100644 index 14f3f7a..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c +++ /dev/null @@ -1,21 +0,0 @@ -/* { 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]); - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr97568.c b/gcc/testsuite/gcc.dg/analyzer/pr97568.c deleted file mode 100644 index 22d574b..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr97568.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "analyzer-decls.h" - -#define NULL ((void *)0) - -extern int *const p1; - -int *const p2; - -int v3; -extern int *const p3 = &v3; /* { dg-warning "'p3' initialized and declared 'extern'" } */ - -int v4; -int *const p4 = &v4; - -int main (void) -{ - __analyzer_describe (0, p1); /* { dg-message "INIT_VAL\\(p1\\)" } */ - __analyzer_eval (p1 == NULL); /* { dg-message "UNKNOWN" } */ - - __analyzer_eval (p2 == NULL); /* { dg-message "TRUE" } */ - - __analyzer_describe (0, p3); /* { dg-message "&v3" } */ - __analyzer_eval (p3 == NULL); /* { dg-message "FALSE" } */ - - __analyzer_describe (0, p4); /* { dg-message "&v4" } */ - __analyzer_eval (p4 == NULL); /* { dg-message "FALSE" } */ - - return p1[0]; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98564.c b/gcc/testsuite/gcc.dg/analyzer/pr98564.c deleted file mode 100644 index 74b1abe..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr98564.c +++ /dev/null @@ -1,6 +0,0 @@ -void *calloc (__SIZE_TYPE__, __SIZE_TYPE__); - -void test_1 (void) -{ - int *p = calloc (0, 1); /* { dg-message "allocated here" } */ -} /* { dg-warning "leak of 'p'" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98628.c b/gcc/testsuite/gcc.dg/analyzer/pr98628.c deleted file mode 100644 index fa0ca96..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr98628.c +++ /dev/null @@ -1,18 +0,0 @@ -/* { dg-additional-options "-O1" } */ - -void foo(void *); -struct chanset_t help_subst_chan; -struct chanset_t *help_subst_chan_0_0; -struct chanset_t { - struct chanset_t *next; - char dname[]; -}; -void help_subst(char *writeidx) { - for (;; help_subst_chan = *help_subst_chan_0_0) { - foo(help_subst_chan.next->dname); - if (help_subst_chan_0_0) { - writeidx++; - *writeidx++ = ' '; - } - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98969.c b/gcc/testsuite/gcc.dg/analyzer/pr98969.c deleted file mode 100644 index e4e4f05..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr98969.c +++ /dev/null @@ -1,25 +0,0 @@ -struct foo -{ - char *expr; -}; - -void -test_1 (__UINTPTR_TYPE__ i) -{ - struct foo *f = (struct foo *)i; - f->expr = __builtin_malloc (1024); -} /* { dg-bogus "leak" } */ - -void -test_2 (__UINTPTR_TYPE__ i) -{ - __builtin_free (((struct foo *)i)->expr); - __builtin_free (((struct foo *)i)->expr); /* { dg-warning "double-'free' of '\\*\\(\\(struct foo \\*\\)i\\)\\.expr'" } */ -} - -void -test_3 (void *p) -{ - void **q = (void **)p; - *q = __builtin_malloc (1024); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-2.c b/gcc/testsuite/gcc.dg/analyzer/pr99193-2.c deleted file mode 100644 index 40e6181..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr99193-2.c +++ /dev/null @@ -1,68 +0,0 @@ -/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation - on realloc(3). - Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/df/main.c#L404 - which is GPLv2 or later. */ - -typedef __SIZE_TYPE__ size_t; -typedef __builtin_va_list va_list; - -#define NULL ((void *)0) - -extern void free (void *); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -char *strdup (const char *) - __attribute__((malloc (free))); - -extern void error (int __status, int __errnum, const char *__format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -extern int errno; - -struct drv -{ - struct drv *next; -}; - -#define EXIT_FAILURE 1 - -static char * -single_drive_display_name (struct drv *) -{ - char *result = strdup ("placeholder"); - if (!result) - __builtin_abort (); - return result; -} - -char * -make_display_name (struct drv *drvs) -{ - char *ret; - - if (drvs->next == NULL) - ret = single_drive_display_name (drvs); - else { - size_t pluses = 0; - size_t i, len; - - while (drvs->next != NULL) { - drvs = drvs->next; - pluses++; - } - - ret = single_drive_display_name (drvs); - len = __builtin_strlen (ret); - - ret = realloc (ret, len + pluses + 1); /* { dg-bogus "'free'" } */ - if (ret == NULL) - error (EXIT_FAILURE, errno, "realloc"); - for (i = len; i < len + pluses; ++i) - ret[i] = '+'; - ret[i] = '\0'; - } - - return ret; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c b/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c deleted file mode 100644 index d64b045..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c +++ /dev/null @@ -1,50 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -/* Verify absence of false positive from -Wanalyzer-mismatching-deallocation - on realloc(3). - Based on https://github.com/libguestfs/libguestfs/blob/f19fd566f6387ce7e4d82409528c9dde374d25e0/daemon/debug.c#L115 - which is GPLv2 or later. */ - -typedef __SIZE_TYPE__ size_t; -typedef __builtin_va_list va_list; - -#define NULL ((void *)0) - -extern void free (void *); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern char *strdup (const char *) - __attribute__((malloc (free))); -extern char *strcat (char *__restrict __dest, const char *__restrict __src) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__nonnull__ (1, 2))); - -static char * -debug_help (const char **cmds, size_t argc, char *const *const argv) -{ - size_t len, i; - char *r, *p; - - r = strdup ("Commands supported:"); - if (!r) { - return NULL; - } - - len = __builtin_strlen (r); - for (i = 0; cmds[i] != NULL; ++i) { - len += __builtin_strlen (cmds[i]) + 1; - p = realloc (r, len + 1); /* { dg-bogus "'free'" } */ - if (p == NULL) { - free (r); - return NULL; - } - r = p; - - strcat (r, " "); - strcat (r, cmds[i]); - } - - return r; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c deleted file mode 100644 index 2ccdcc7..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c +++ /dev/null @@ -1,45 +0,0 @@ -typedef struct FILE FILE; - -FILE* fopen (const char*, const char*); -int fclose (FILE*); -int fprintf (FILE *, const char *, ...); - -#define NULL ((void *)0) - -void -test_1 (void) -{ - int i; - - for (i = 0; i < 2; ++i) { - FILE *fp = fopen ("/tmp/test", "w"); - fprintf (fp, "hello:%s ", "world"); - fclose (fp); /* { dg-bogus "double 'fclose'" } */ - } -} - -void -test_2 (void) -{ - int i; - - for (i = 0; i < 2; ++i) { - FILE *fp = fopen ("/tmp/test", "w"); - fprintf (fp, "hello"); - } -} /* { dg-warning "leak of FILE 'fp'" } */ - -FILE *fp3; - -void -test_3 (FILE **fpp) -{ - int i; - - for (i = 0; i < 2; ++i) { - *fpp = fopen ("/tmp/test", "w"); - fprintf (*fpp, "hello"); - fclose (*fpp); /* { dg-bogus "double 'fclose'" } */ - *fpp = NULL; - } -} diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c b/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c deleted file mode 100644 index a0bca8b..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c +++ /dev/null @@ -1,61 +0,0 @@ -/* Reproducer for report from -Wanalyzer-malloc-leak - Reduced from - https://git.qemu.org/?p=qemu.git;a=blob;f=subprojects/libvhost-user/libvhost-user.c;h=fab7ca17ee1fb27bcfc338527d1aeb9f923aade5;hb=HEAD#l1184 - which is licensed under GNU GPLv2 or later. */ - -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned long uint64_t; -typedef unsigned long uint64_t; -typedef __SIZE_TYPE__ size_t; - -extern void *calloc(size_t __nmemb, size_t __size) - __attribute__((__nothrow__, __leaf__)) - __attribute__((__malloc__)) - __attribute__((__alloc_size__(1, 2))) - __attribute__((__warn_unused_result__)); - -typedef struct VuDescStateSplit { - uint8_t inflight; - uint64_t counter; -} VuDescStateSplit; - -typedef struct VuVirtqInflight { - uint16_t desc_num; - VuDescStateSplit desc[]; -} VuVirtqInflight; - -typedef struct VuVirtqInflightDesc { - uint16_t index; - uint64_t counter; -} VuVirtqInflightDesc; - -typedef struct VuVirtq { - VuVirtqInflight *inflight; - VuVirtqInflightDesc *resubmit_list; - uint16_t resubmit_num; - uint64_t counter; - int inuse; -} VuVirtq; - -int vu_check_queue_inflights(VuVirtq *vq) { - int i = 0; - - if (vq->inuse) { - vq->resubmit_list = calloc(vq->inuse, sizeof(VuVirtqInflightDesc)); - if (!vq->resubmit_list) { - return -1; - } - - for (i = 0; i < vq->inflight->desc_num; i++) { - if (vq->inflight->desc[i].inflight) { - vq->resubmit_list[vq->resubmit_num].index = i; /* { dg-bogus "leak" } */ - vq->resubmit_list[vq->resubmit_num].counter = - vq->inflight->desc[i].counter; - vq->resubmit_num++; - } - } - } - - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/gcc.dg/analyzer/realloc-1.c deleted file mode 100644 index 9951e11..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c +++ /dev/null @@ -1,95 +0,0 @@ -/* { dg-additional-options "-Wno-free-nonheap-object" } */ - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1))); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -void *test_1 (void *ptr) -{ - return realloc (ptr, 1024); -} - -void *test_2 (void *ptr) -{ - void *p = malloc (1024); /* { dg-message "allocated here" } */ - p = realloc (p, 4096); /* { dg-message "when 'realloc' fails" } */ - free (p); -} /* { dg-warning "leak of 'p'" } */ // ideally this would be on the realloc stmt - -void *test_3 (void *ptr) -{ - void *p = malloc (1024); - void *q = realloc (p, 4096); - if (q) - free (q); - else - free (p); -} - -void *test_4 (void) -{ - return realloc (NULL, 1024); -} - -int *test_5 (int *p) -{ - *p = 42; - int *q = realloc (p, sizeof(int) * 4); /* { dg-message "when 'realloc' fails" } */ - *q = 43; /* { dg-warning "dereference of NULL 'q'" } */ - return q; -} - -void test_6 (size_t sz) -{ - void *p = realloc (NULL, sz); -} /* { dg-warning "leak of 'p'" } */ - -/* The analyzer should complain about realloc of non-heap. */ - -void *test_7 (size_t sz) -{ - char buf[100]; /* { dg-message "region created on stack here" } */ - void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '&buf' which points to memory on the stack" } */ - return p; -} - -/* Mismatched allocator. */ - -struct foo -{ - int m_int; -}; - -extern void foo_release (struct foo *); -extern struct foo *foo_acquire (void) - __attribute__ ((malloc (foo_release))); - -void test_8 (void) -{ - struct foo *p = foo_acquire (); - void *q = realloc (p, 1024); /* { dg-warning "'p' should have been deallocated with 'foo_release' but was deallocated with 'realloc'" } */ -} - -/* We should complain about realloc on a freed pointer. */ - -void test_9 (void *p) -{ - free (p); - void *q = realloc (p, 1024); /* { dg-warning "double-'free' of 'p'" } */ -} - -void test_10 (char *s, int n) -{ - __builtin_realloc(s, n); /* { dg-warning "ignoring return value of '__builtin_realloc' declared with attribute 'warn_unused_result'" } */ -} /* { dg-warning "leak" } */ diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-2.c b/gcc/testsuite/gcc.dg/analyzer/realloc-2.c deleted file mode 100644 index ab3e4b6..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-2.c +++ /dev/null @@ -1,82 +0,0 @@ -/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ - -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1))); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -char *test_8 (size_t sz) -{ - char *p, *q; - - p = malloc (3); - if (!p) - return NULL; - - __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ - - p[0] = 'a'; - p[1] = 'b'; - p[2] = 'c'; - - __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ - - q = realloc (p, 6); - - /* We should have 3 nodes, corresponding to "failure", - "success without moving", and "success with moving". */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ - - if (q) - { - __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(size_t\\)6'" } */ - q[3] = 'd'; - q[4] = 'e'; - q[5] = 'f'; - if (q == p) - { - /* "realloc" success, growing the buffer in-place. */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ - // TODO - } - else - { - /* "realloc" success, moving the buffer (and thus freeing "p"). */ - __analyzer_eval (q[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[2] == 'c'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ - /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ - } - __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ - } - else - { - /* "realloc" failure. p should be unchanged. */ - __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(size_t\\)3'" } */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ - return p; - } - - return q; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-3.c b/gcc/testsuite/gcc.dg/analyzer/realloc-3.c deleted file mode 100644 index eec6149..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-3.c +++ /dev/null @@ -1,83 +0,0 @@ -/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ - -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *calloc (size_t __nmemb, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1, 2))) ; -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1))); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -/* realloc of calloc buffer. */ - -char *test_8 (size_t sz) -{ - char *p, *q; - - p = calloc (1, 3); - if (!p) - return NULL; - - __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ - - __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ - - q = realloc (p, 6); - - /* We should have 3 nodes, corresponding to "failure", - "success without moving", and "success with moving". */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ - - if (q) - { - __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ - q[3] = 'd'; - q[4] = 'e'; - q[5] = 'f'; - if (q == p) - { - /* "realloc" success, growing the buffer in-place. */ - __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ - } - else - { - /* "realloc" success, moving the buffer (and thus freeing "p"). */ - __analyzer_eval (q[0] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[1] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[2] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ - /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ - } - __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ - } - else - { - /* "realloc" failure. p should be unchanged. */ - __analyzer_dump_capacity (p); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)3'" } */ - __analyzer_eval (p[0] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */ - return p; - } - - return q; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-4.c b/gcc/testsuite/gcc.dg/analyzer/realloc-4.c deleted file mode 100644 index ac338ec..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-4.c +++ /dev/null @@ -1,85 +0,0 @@ -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *calloc (size_t __nmemb, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1, 2))) ; -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1))); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); - -/* realloc where we don't know the original size of the region. */ - -char *test_8 (char *p, size_t sz) -{ - char *q; - - __analyzer_dump_capacity (p); /* { dg-warning "capacity: 'UNKNOWN\\(\[^\n\r\]*\\)'" } */ - - p[0] = 'a'; - p[1] = 'b'; - p[2] = 'c'; - __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ - - q = realloc (p, 6); - - /* We should have 3 nodes, corresponding to "failure", - "success without moving", and "success with moving". */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "3 processed enodes" } */ - - if (q) - { - q[3] = 'd'; - q[4] = 'e'; - q[5] = 'f'; - if (q == p) - { - /* "realloc" success, growing the buffer in-place. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ - __analyzer_eval (q[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[2] == 'c'); /* { dg-warning "TRUE" } */ - } - else - { - /* "realloc" success, moving the buffer (and thus freeing "p"). */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)6'" } */ - /* We don't know how much of the buffer is copied. */ - __analyzer_eval (q[0] == 'a'); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (q[1] == 'b'); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (q[2] == 'c'); /* { dg-warning "UNKNOWN" } */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "UNKNOWN" "unknown" } */ - /* { dg-warning "use after 'free' of 'p'" "use after free" { target *-*-* } .-1 } */ - } - __analyzer_eval (q[3] == 'd'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[4] == 'e'); /* { dg-warning "TRUE" } */ - __analyzer_eval (q[5] == 'f'); /* { dg-warning "TRUE" } */ - } - else - { - /* "realloc" failure. p should be unchanged. */ - __analyzer_dump_exploded_nodes (0); /* { dg-warning "1 processed enode" } */ - __analyzer_dump_capacity (q); /* { dg-warning "capacity: 'UNKNOWN\\(\[^\n\r\]*\\)'" } */ - __analyzer_eval (p[0] == 'a'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */ - __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */ - return p; - } - - return q; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c b/gcc/testsuite/gcc.dg/analyzer/realloc-5.c deleted file mode 100644 index f65f2c6..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c +++ /dev/null @@ -1,46 +0,0 @@ -/* { dg-additional-options "-fno-analyzer-suppress-followups" } */ - -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -#define NULL ((void *)0) - -extern void *malloc (size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__malloc__)) - __attribute__ ((__alloc_size__ (1))); -extern void *realloc (void *__ptr, size_t __size) - __attribute__ ((__nothrow__ , __leaf__)) - __attribute__ ((__warn_unused_result__)) - __attribute__ ((__alloc_size__ (2))); -extern void free (void *__ptr) - __attribute__ ((__nothrow__ , __leaf__)); -extern void *memset (void *__ptr, int __value, size_t __size); - -/* realloc where the region shrinks on success_with_move. */ - -void test_1 () -{ - char *p = malloc (16); - if (!p) - return; - memset (p, 1, 16); - - char *q = realloc (p, 8); - if (!q) - { - free (p); - return; - } - else if (p != q) - { - __analyzer_dump_capacity (q); /* { dg-warning "capacity: '\\(\[^\n\r\]*\\)8'" } */ - __analyzer_eval (q[8] == 1); /* { dg-line eval } */ - - /* { dg-warning "UNKNOWN" "warning" { target *-*-* } eval } */ - /* { dg-warning "heap-based buffer over-read" "warning" { target *-*-* } eval } */ - } - - free (q); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c b/gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c deleted file mode 100644 index d76b878..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c +++ /dev/null @@ -1,25 +0,0 @@ -void *realloc (void *, unsigned long) - __attribute__((__nothrow__, __leaf__)) - __attribute__((__warn_unused_result__)) __attribute__((__alloc_size__ (2))); - -long * -slurp (long *buffer, unsigned long file_size) -{ - unsigned long cc; - if (!__builtin_add_overflow (file_size - file_size % sizeof (long), - 2 * sizeof (long), &cc)) - buffer = realloc (buffer, cc); - return buffer; -} - -long * -slurp1 (long *buffer, unsigned long file_size) -{ - return realloc (buffer, file_size - file_size % sizeof (long)); -} - -long * -slurp2 (long *buffer, unsigned long file_size) -{ - return realloc (buffer, (file_size / sizeof (long)) * sizeof (long)); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c b/gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c deleted file mode 100644 index a557dee..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c +++ /dev/null @@ -1,35 +0,0 @@ -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -extern size_t -strlen(const char* __s) __attribute__((__nothrow__, __leaf__)) -__attribute__((__pure__)) __attribute__((__nonnull__(1))); - -extern void* -malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) -__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); - -extern int -snprintf(char* __restrict __s, size_t size, const char* __restrict, ...) - __attribute__((__nothrow__)); - -char * -test_1 (const char *a, const char *b) -{ - size_t sz = strlen (a) + strlen (b) + 2; - char *p = malloc (sz); - if (!p) - return NULL; - snprintf (p, sz, "%s/%s", a, b); - return p; -} - -void -test_2 (const char *a, const char *b) -{ - size_t sz = strlen (a) + strlen (b) + 2; - char *p = malloc (sz); /* { dg-message "allocated here" "PR 107017" { xfail *-*-* } } */ - if (!p) - return; - snprintf (p, sz, "%s/%s", a, b); /* { dg-warning "leak of 'p'" "PR 107017" { xfail *-*-* } } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/sock-1.c b/gcc/testsuite/gcc.dg/analyzer/sock-1.c deleted file mode 100644 index 0f3e822..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/sock-1.c +++ /dev/null @@ -1,112 +0,0 @@ -typedef unsigned int __u32; -__extension__ typedef __signed__ long long __s64; -__extension__ typedef unsigned long long __u64; -typedef __u32 u32; -typedef __s64 s64; -typedef __u64 u64; -typedef long long __kernel_time64_t; -typedef _Bool bool; -typedef __s64 time64_t; -struct __kernel_timespec { - __kernel_time64_t tv_sec; - long long tv_nsec; -}; -struct timespec64 { - time64_t tv_sec; - long tv_nsec; -}; - -extern struct timespec64 ns_to_timespec64(const s64 nsec); -int put_timespec64(const struct timespec64 *ts, - struct __kernel_timespec *uts); - -/* [...snip...] */ - -extern int put_old_timespec32(const struct timespec64 *, void *); - -/* [...snip...] */ - -/* [...snip...] */ - -typedef s64 ktime_t; - -/* [...snip...] */ - -extern void ktime_get_real_ts64(struct timespec64 *tv); - -/* [...snip...] */ - -enum tk_offsets { - TK_OFFS_REAL, - TK_OFFS_BOOT, - TK_OFFS_TAI, - TK_OFFS_MAX, -}; - -extern ktime_t ktime_get(void); -extern ktime_t ktime_get_with_offset(enum tk_offsets offs); -extern ktime_t ktime_get_coarse_with_offset(enum tk_offsets offs); -extern ktime_t ktime_mono_to_any(ktime_t tmono, enum tk_offsets offs); -extern ktime_t ktime_get_raw(void); -extern u32 ktime_get_resolution_ns(void); - - -static ktime_t ktime_get_real(void) -{ - return ktime_get_with_offset(TK_OFFS_REAL); -} - -/* [...snip...] */ - -struct socket { - /* [...snip...] */ - struct sock *sk; - /* [...snip...] */ -}; - -/* [...snip...] */ - -struct sock { - /* [...snip...] */ - ktime_t sk_stamp; - /* [...snip...] */ -}; - -/* [...snip...] */ - -static ktime_t sock_read_timestamp(struct sock *sk) -{ - return *(const volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp); -} - -static void sock_write_timestamp(struct sock *sk, ktime_t kt) -{ - *(volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp) = kt; -} - -/* [...snip...] */ - -int sock_gettstamp(struct socket *sock, void *userstamp, - bool timeval, bool time32) -{ - struct sock *sk = sock->sk; - struct timespec64 ts; - - /* [...snip...] */ - ts = ns_to_timespec64((sock_read_timestamp(sk))); - if (ts.tv_sec == -1) - return -2; - if (ts.tv_sec == 0) { - ktime_t kt = ktime_get_real(); - sock_write_timestamp(sk, kt); - ts = ns_to_timespec64((kt)); - } - - if (timeval) - ts.tv_nsec /= 1000; - - - if (time32) - return put_old_timespec32(&ts, userstamp); - return put_timespec64(&ts, userstamp); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c index e7c2b30..28914d2 100644 --- a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c @@ -1,55 +1,15 @@ /* See e.g. https://en.cppreference.com/w/c/io/fprintf and https://www.man7.org/linux/man-pages/man3/sprintf.3.html */ +/* C only: C++ fpermissive already emits errors. */ #include "analyzer-decls.h" extern int sprintf(char* dst, const char* fmt, ...) __attribute__((__nothrow__)); -#define NULL ((void *)0) - -int -test_passthrough (char* dst, const char* fmt) -{ - /* This assumes that fmt doesn't have any arguments. */ - return sprintf (dst, fmt); -} - -void -test_known (void) -{ - char buf[10]; - int res = sprintf (buf, "foo"); - /* TODO: ideally we would know the value of "res" is 3, - and known the content and strlen of "buf" after the call */ -} -int -test_null_dst (void) -{ - return sprintf (NULL, "hello world"); /* { dg-warning "use of NULL where non-null expected" } */ -} - -int -test_null_fmt (char *dst) -{ - return sprintf (dst, NULL); /* { dg-warning "use of NULL where non-null expected" } */ -} - -int -test_uninit_dst (void) -{ - char *dst; - return sprintf (dst, "hello world"); /* { dg-warning "use of uninitialized value 'dst'" } */ -} - -int -test_uninit_fmt_ptr (char *dst) -{ - const char *fmt; - return sprintf (dst, fmt); /* { dg-warning "use of uninitialized value 'fmt'" } */ -} +#define NULL ((void *)0) int test_uninit_fmt_buf (char *dst) @@ -66,12 +26,3 @@ test_fmt_not_terminated (char *dst) return sprintf (dst, fmt); /* { dg-warning "stack-based buffer over-read" } */ /* { dg-message "while looking for null terminator for argument 2 \\('&fmt'\\) of 'sprintf'..." "event" { target *-*-* } .-1 } */ } - -void -test_strlen_1 (void) -{ - char buf[10]; - sprintf (buf, "msg: %s\n", "abc"); - __analyzer_eval (__builtin_strlen (buf) == 8); /* { dg-warning "UNKNOWN" } */ - // TODO: ideally would be TRUE -} diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c b/gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c deleted file mode 100644 index 0094f3e..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c +++ /dev/null @@ -1,35 +0,0 @@ -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -extern size_t -strlen(const char* __s) __attribute__((__nothrow__, __leaf__)) -__attribute__((__pure__)) __attribute__((__nonnull__(1))); - -extern void* -malloc(size_t __size) __attribute__((__nothrow__, __leaf__)) -__attribute__((__malloc__)) __attribute__((__alloc_size__(1))); - -extern int -sprintf(char* __restrict __s, const char* __restrict, ...) - __attribute__((__nothrow__)); - -char * -test_1 (const char *a, const char *b) -{ - size_t sz = strlen (a) + strlen (b) + 2; - char *p = malloc (sz); - if (!p) - return NULL; - sprintf (p, "%s/%s", a, b); - return p; -} - -void -test_2 (const char *a, const char *b) -{ - size_t sz = strlen (a) + strlen (b) + 2; - char *p = malloc (sz); /* { dg-message "allocated here" } */ - if (!p) - return; - sprintf (p, "%s/%s", a, b); /* { dg-warning "leak of 'p' " } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c deleted file mode 100644 index f5bcd67..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c +++ /dev/null @@ -1,67 +0,0 @@ -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -/* Concatenating a pair of strings. */ - -/* Correct but poor implementation with repeated __builtin_strlen calls. */ - -char * -alloc_dup_of_concatenated_pair_1_correct (const char *x, const char *y) -{ - size_t sz = __builtin_strlen (x) + __builtin_strlen (y) + 1; - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, __builtin_strlen (x)); - __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); - result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; - return result; -} - -/* Incorrect version: forgetting to add space for terminator. */ - -char * -alloc_dup_of_concatenated_pair_1_incorrect (const char *x, const char *y) -{ - /* Forgetting to add space for the terminator here. */ - size_t sz = __builtin_strlen (x) + __builtin_strlen (y); - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, __builtin_strlen (x)); - __builtin_memcpy (result + __builtin_strlen (x), y, __builtin_strlen (y)); - result[__builtin_strlen(x) + __builtin_strlen (y)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ - return result; -} - -/* As above, but only calling __builtin_strlen once on each input. */ - -char * -alloc_dup_of_concatenated_pair_2_correct (const char *x, const char *y) -{ - size_t len_x = __builtin_strlen (x); - size_t len_y = __builtin_strlen (y); - size_t sz = len_x + len_y + 1; - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, len_x); - __builtin_memcpy (result + len_x, y, len_y); - result[len_x + len_y] = '\0'; - return result; -} - -char * -alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) -{ - size_t len_x = __builtin_strlen (x); - size_t len_y = __builtin_strlen (y); - size_t sz = len_x + len_y; /* Forgetting to add space for the terminator. */ - char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x \\+ len_y' bytes" } */ - if (!result) - return NULL; - __builtin_memcpy (result, x, len_x); - __builtin_memcpy (result + len_x, y, len_y); - result[len_x + len_y] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ - return result; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c b/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c deleted file mode 100644 index 44c4e9d..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c +++ /dev/null @@ -1,61 +0,0 @@ -typedef __SIZE_TYPE__ size_t; -#define NULL ((void *)0) - -/* Duplicating a string. */ - -/* Correct but poor implementation with repeated __builtin_strlen calls. */ - -char * -alloc_dup_1_correct (const char *x) -{ - size_t sz = __builtin_strlen (x) + 1; - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, __builtin_strlen (x)); - result[__builtin_strlen(x)] = '\0'; - return result; -} - -/* Incorrect version: forgetting to add space for terminator. */ - -char * -alloc_dup_1_incorrect (const char *x, const char *y) -{ - /* Forgetting to add space for the terminator here. */ - size_t sz = __builtin_strlen (x) + 1; - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, __builtin_strlen (x)); - result[__builtin_strlen(x)] = '\0'; /* { dg-warning "heap-based buffer overflow" "PR analyzer/105899" { xfail *-*-* } } */ - return result; -} - -/* As above, but only calling __builtin_strlen once. */ - -char * -alloc_dup_2_correct (const char *x) -{ - size_t len_x = __builtin_strlen (x); - size_t sz = len_x + 1; - char *result = __builtin_malloc (sz); - if (!result) - return NULL; - __builtin_memcpy (result, x, len_x); - result[len_x] = '\0'; - return result; -} - -char * -alloc_dup_of_concatenated_pair_2_incorrect (const char *x, const char *y) -{ - size_t len_x = __builtin_strlen (x); - size_t sz = len_x; /* Forgetting to add space for the terminator. */ - char *result = __builtin_malloc (sz); /* { dg-message "capacity: 'len_x' bytes" } */ - if (!result) - return NULL; - __builtin_memcpy (result, x, len_x); - result[len_x] = '\0'; /* { dg-warning "heap-based buffer overflow" } */ - return result; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c b/gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c deleted file mode 100644 index 3362227..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Currently the warning only fires at -O0 - (needs to inline the call without optimizing the - implicit default of the switch). */ - -/* { dg-additional-options "-O0" } */ - -typedef __SIZE_TYPE__ size_t; -int snprintf(char *str, size_t size, const char *format, ...); - -enum usage_kind { - USAGE_ERROR, - USAGE_BUG, -}; - -static void __analyzer_vreportf(enum usage_kind kind) -{ - char buf[256]; - const char *pfx; - - switch (kind) { /* { dg-message "following 'default:' branch" } */ - case USAGE_ERROR: - pfx = "error: "; - break; - case USAGE_BUG: - pfx = "BUG: "; - break; - } - - if (kind == USAGE_BUG) - snprintf(buf, sizeof(buf), "%s%s:%d: ", pfx, "file", 123); - else - snprintf(buf, sizeof(buf), "%s", pfx); /* { dg-warning "uninitialized" } */ -} - -int main(void) -{ - __analyzer_vreportf(42); - - return 0; -} diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c b/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c deleted file mode 100644 index d7c50de..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "analyzer-decls.h" - -void external_fn(void); - -struct st_1 -{ - char *name; - unsigned size; -}; - -void test_1a (void *p, unsigned next_off) -{ - struct st_1 *r = p; - - external_fn(); - - if (next_off >= r->size) - return; - - if (next_off >= r->size) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} - -void test_1b (void *p, unsigned next_off) -{ - struct st_1 *r = p; - - if (next_off >= r->size) - return; - - if (next_off >= r->size) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} - -void test_1c (struct st_1 *r, unsigned next_off) -{ - if (next_off >= r->size) - return; - - if (next_off >= r->size) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} - -void test_1d (struct st_1 *r, unsigned next_off) -{ - external_fn(); - - if (next_off >= r->size) - return; - - if (next_off >= r->size) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} - -void test_1e (void *p, unsigned next_off) -{ - struct st_1 *r = p; - - while (1) - { - external_fn(); - - if (next_off >= r->size) - return; - - __analyzer_dump_path (); /* { dg-message "path" } */ - } -} - -struct st_2 -{ - char *name; - unsigned arr[10]; -}; - -void test_2a (void *p, unsigned next_off) -{ - struct st_2 *r = p; - - external_fn(); - - if (next_off >= r->arr[5]) - return; - - if (next_off >= r->arr[5]) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} - -void test_2b (void *p, unsigned next_off, int idx) -{ - struct st_2 *r = p; - - external_fn(); - - if (next_off >= r->arr[idx]) - return; - - if (next_off >= r->arr[idx]) - /* We should have already returned if this is the case. */ - __analyzer_dump_path (); /* { dg-bogus "path" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c b/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c deleted file mode 100644 index 5dd3f85..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c +++ /dev/null @@ -1,7 +0,0 @@ -/* { dg-require-effective-target alloca } */ - -int test_1 (void) -{ - int *p = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */ - return *p; /* { dg-warning "use of uninitialized value '\\*p'" } */ -} diff --git a/gcc/testsuite/gcc.dg/analyzer/untracked-2.c b/gcc/testsuite/gcc.dg/analyzer/untracked-2.c deleted file mode 100644 index 565a9cc..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/untracked-2.c +++ /dev/null @@ -1,7 +0,0 @@ -typedef unsigned char u8; -extern int foo(const u8 *key, unsigned int keylen); -int test (void) -{ - static const u8 default_salt[64]; - return foo(default_salt, 64); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c b/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c deleted file mode 100644 index 061cd00..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c +++ /dev/null @@ -1,57 +0,0 @@ -/* { dg-additional-options "-Wno-analyzer-too-complex" } */ - -#define NULL ((void *)0) - -extern int printf (const char *__restrict __format, ...); -extern int vasprintf (char **__restrict __ptr, const char *__restrict __f, - __builtin_va_list __arg) - __attribute__ ((__nothrow__, __format__ (__printf__, 2, 0))) ; -extern void free (void *__ptr) __attribute__ ((__nothrow__ , __leaf__)); - -static char * __attribute__ ((__format__ (__printf__, 1, 2))) -zasprintf (const char *format, ...) -{ - char *resultp; - __builtin_va_list args; - __builtin_va_start (args, format); - int r = vasprintf (&resultp, format, args); - __builtin_va_end (args); - return r < 0 ? NULL : resultp; -} - -int run_test() { - char *buf = NULL; - char *bar = NULL; - char *baz = NULL; - int i = 1232; - - printf("static function check\n"); - - buf = zasprintf("i = %d", i); - if (buf) { - printf("buf = %s\nbuf = %p\n", buf, buf); - } - - bar = zasprintf("i = %d - %d", i, i - 13); - if (bar) { - printf("bar = %s\nbar = %p\n", bar, bar); - printf("buf = %s\nbuf = %p\n", buf, buf); - } - - baz = zasprintf("No i's here"); - if (baz) { - printf("baz = %s\nbaz = %p\n", baz, baz); - printf("bar = %s\nbar = %p\n", bar, bar); - printf("buf = %s\nbuf = %p\n", buf, buf); - } - - free(buf); - free(bar); - free(baz); - - return 1; -} - -int main(int argc, char **argv) { - return run_test(); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c b/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c deleted file mode 100644 index dc724e2..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c +++ /dev/null @@ -1,29 +0,0 @@ -/* 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-function-1.c b/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c index c1bece6..a5ee4ca 100644 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c +++ b/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c @@ -1,3 +1,5 @@ +/* { C only: C++ does not allow for conversion from function pointer to 'void *' */ + typedef __SIZE_TYPE__ size_t; int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ 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 deleted file mode 100644 index 092500e..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c +++ /dev/null @@ -1,58 +0,0 @@ -#include - -/* 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/write-to-string-literal-4-disabled.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c deleted file mode 100644 index fa21af1..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Verify that we can disable warnings that have notes added to them via - region_model_context_decorator::add_note. */ - -/* { dg-additional-options "-Wno-analyzer-write-to-string-literal" } */ - -typedef __SIZE_TYPE__ size_t; - -int getrandom (void *__buffer, size_t __length, /* { dg-bogus "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ - unsigned int __flags) - __attribute__ ((access (__write_only__, 1, 2))); - -#define GRND_RANDOM 0x02 - -void test (int flag) -{ - char *buf; - - if (flag) - buf = __builtin_malloc (1024); - else - buf = (char *)""; /* { dg-bogus "here" } */ - - if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-bogus "write to string literal" } */ - __builtin_printf("%s\n", buf); - - if (flag) - __builtin_free (buf); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c deleted file mode 100644 index a8f600f..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c +++ /dev/null @@ -1,23 +0,0 @@ -typedef __SIZE_TYPE__ size_t; - -int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ - unsigned int __flags) - __attribute__ ((access (__write_only__, 1, 2))); - -#define GRND_RANDOM 0x02 - -void test (int flag) -{ - char *buf; - - if (flag) - buf = __builtin_malloc (1024); - else - buf = (char *)""; /* { dg-message "here" } */ - - if (getrandom(buf, 16, GRND_RANDOM)) /* { dg-warning "write to string literal" } */ - __builtin_printf("%s\n", buf); - - if (flag) - __builtin_free (buf); -} diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c b/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c deleted file mode 100644 index 42efc49..0000000 --- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Verify that deduplication of -Wanalyzer-write-to-string-literal (and their - notes) works. */ - -/* { dg-additional-options "-fanalyzer-show-duplicate-count" } */ -/* { dg-require-effective-target alloca } */ - -#include "analyzer-decls.h" - -typedef __SIZE_TYPE__ size_t; - -int getrandom (void *__buffer, size_t __length, /* { dg-message "parameter 1 of 'getrandom' marked with attribute 'access \\(write_only, 1, 2\\)'" } */ - unsigned int __flags) - __attribute__ ((access (__write_only__, 1, 2))); - -#define GRND_RANDOM 0x02 - -void *test (int flag) -{ - char *ptr; - if (flag) - ptr = __builtin_malloc (1024); - else - ptr = __builtin_alloca (1024); - - __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */ - - if (getrandom((char *)"foo", 3, GRND_RANDOM)) /* { dg-warning "write to string literal" "warning" } */ - /* { dg-message "1 duplicate" "dup" { target *-*-* } .-1 } */ - __builtin_printf("ok\n"); - - return ptr; -} -- cgit v1.1