analyzer: Move gcc.dg/analyzer tests to c-c++-common (1).

Message ID 20230824183919.2485913-1-vultkayn@gcc.gnu.org
State Unresolved
Headers
Series analyzer: Move gcc.dg/analyzer tests to c-c++-common (1). |

Checks

Context Check Description
snail/gcc-patch-check warning Git am fail log

Commit Message

Li, Pan2 via Gcc-patches Aug. 24, 2023, 6:39 p.m. UTC
  From: benjamin priour <priour.be@gmail.com>

Hi,

Below the first batch of a serie of patches to transition
the analyzer testsuite from gcc.dg/analyzer to c-c++-common/analyzer.
I do not know how long this serie will be, thus the patch was not
numbered.

For the grand majority of the tests, the transition only required some
adjustement over the syntax and casts to be C++-friendly, or to adjust
the warnings regexes to fit the C++ FE.

The most noteworthy change is in the handling of known_functions,
as described in the below patch.

Successfully regstrapped on x86_64-linux-gnu off trunk
18befd6f050e70f11ecca1dd58624f0ee3c68cc7.

Is it OK for trunk ?

Thanks,
Benjamin.

Patch below.
---

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 <vultkayn@gcc.gnu.org>

gcc/analyzer/ChangeLog:

	* 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_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:

	* 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-4-multiline.c: Moved to...
	* c-c++-common/analyzer/inlining-4-multiline.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/pr104369-1.c: Moved to...
	* c-c++-common/analyzer/pr104369-1.c: ...here.
	* gcc.dg/analyzer/pr104369-2.c: Moved to...
	* c-c++-common/analyzer/pr104369-2.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: Moved to...
	* c-c++-common/analyzer/pr95152-4.c: ...here.
	* gcc.dg/analyzer/pr95152-5.c: Moved to...
	* c-c++-common/analyzer/pr95152-5.c: ...here.
	* 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: Moved to...
	* c-c++-common/analyzer/write-to-function-1.c: ...here.
	* gcc.dg/analyzer/write-to-string-literal-1.c: Moved to...
	* c-c++-common/analyzer/write-to-string-literal-1bis.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.exp: Likewise.
	* gcc.dg/analyzer/sprintf-1.c:
	* gcc.dg/analyzer/allocation-size-multiline-1.c: Moved into
	c-c++-common/analyzer.
	* gcc.dg/analyzer/allocation-size-multiline-2.c: Likewise.
	* gcc.dg/analyzer/allocation-size-multiline-3.c: Likewise.
	* gcc.dg/analyzer/data-model-11.c: Likewise.
	* gcc.dg/analyzer/inlining-3.c: Likewise.
	* gcc.dg/analyzer/inlining-4.c: Likewise.
	* gcc.dg/analyzer/pr61861.c: Likewise.
	* gcc.dg/analyzer/pr93457.c: Likewise.
	* gcc.dg/analyzer/pr97568.c: Likewise.
	* gcc.dg/analyzer/write-to-string-literal-4.c: Removed.
	* c-c++-common/analyzer/allocation-size-multiline-1.c: Added
	specific multiline targets.
	* c-c++-common/analyzer/allocation-size-multiline-2.c: Likewise.
	* c-c++-common/analyzer/allocation-size-multiline-3.c: Likewise.
	* c-c++-common/analyzer/analyzer-decls.h: Copied from
	gcc.dg/analyzer/.
	* c-c++-common/analyzer/data-model-11.c: New test.
	* c-c++-common/analyzer/inlining-3.c: New test.
	* c-c++-common/analyzer/inlining-4.c: New test.
	* c-c++-common/analyzer/pr61861.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: New test.
	* c-c++-common/analyzer/test-alloca.h: Copied from
	gcc.dg/analyzer/.
	* c-c++-common/analyzer/test-assert.h: Likewise.
	* c-c++-common/analyzer/test-setjmp.h: Likewise.
	* c-c++-common/analyzer/test-uaccess.h: Likewise.
	* c-c++-common/analyzer/write-to-string-literal-1.c: C++ compatible.
	* c-c++-common/analyzer/write-to-string-literal-4.c: Add dg
	regex specific to C++.
---
 gcc/analyzer/analyzer.h                       |  26 +++
 gcc/analyzer/kf.cc                            | 191 ++++++++++++++----
 gcc/analyzer/known-function-manager.cc        |   7 +
 gcc/analyzer/known-function-manager.h         |   2 +
 gcc/analyzer/region-model.cc                  |  28 +++
 gcc/analyzer/region-model.h                   |   4 +
 gcc/analyzer/sm-fd.cc                         |  25 ++-
 gcc/analyzer/sm-malloc.cc                     | 133 ++++++------
 .../analyzer/aliasing-3.c                     |  14 +-
 .../analyzer/aliasing-pr106473.c              |   2 +-
 .../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/analyzer-decls.h    |  56 +++++
 .../analyzer/asm-x86-dyndbg-2.c               |   8 +-
 .../analyzer/asm-x86-lp64-2.c                 |   4 +-
 .../analyzer/atomic-builtins-haproxy-proxy.c  |   2 +-
 .../analyzer/atomic-builtins-qemu-sockets.c   |   2 +-
 .../analyzer/attr-malloc-6.c                  |  12 +-
 .../attr-malloc-CVE-2019-19078-usb-leak.c     |   9 +-
 .../analyzer/attr-tainted_args-1.c            |   4 +-
 .../analyzer/call-summaries-pr107158.c        |   4 +-
 .../analyzer/calloc-1.c                       |  12 +-
 .../analyzer/compound-assignment-5.c          |  28 +--
 .../analyzer/coreutils-cksum-pr108664.c       |   7 +-
 .../analyzer/coreutils-sum-pr108666.c         |   2 +-
 .../c-c++-common/analyzer/data-model-11.c     |   6 +
 .../analyzer/deref-before-check-pr108455-1.c  |   2 +-
 ...-before-check-pr108455-git-pack-revindex.c |   2 +-
 .../analyzer/deref-before-check-pr108475-1.c  |  10 +-
 ...f-before-check-pr108475-haproxy-tcpcheck.c |  15 +-
 ...f-before-check-pr109060-haproxy-cfgparse.c |   2 +-
 .../deref-before-check-pr109239-linux-bus.c   |  12 +-
 .../analyzer/deref-before-check-pr77425.c     |  11 +-
 .../analyzer/exec-1.c                         |  22 +-
 .../analyzer/feasibility-3.c                  |  13 +-
 .../analyzer/fields.c                         |   2 +-
 .../analyzer/function-ptr-5.c                 |  10 +-
 .../analyzer/infinite-recursion-pr108524-1.c  |  11 +-
 .../analyzer/infinite-recursion-pr108524-2.c  |   4 +-
 ...e-recursion-pr108524-qobject-json-parser.c |  11 +-
 .../{gcc.dg => c-c++-common}/analyzer/init.c  |   2 +-
 .../analyzer/inlining-3-multiline.c           |  47 ++++-
 .../c-c++-common/analyzer/inlining-3.c        |  41 ++++
 .../analyzer/inlining-4-multiline.c           |  56 ++++-
 .../c-c++-common/analyzer/inlining-4.c        |  38 ++++
 .../analyzer/leak-pr105906.c                  |  12 +-
 .../leak-pr108045-with-call-summaries.c       |  16 +-
 .../leak-pr108045-without-call-summaries.c    |  16 +-
 .../analyzer/leak-pr109059-1.c                |   2 +-
 .../analyzer/leak-pr109059-2.c                |   2 +-
 .../analyzer/malloc-2.c                       |   2 +-
 .../analyzer/memcpy-2.c                       |   5 +-
 ...f-pr108251-smp_fetch_ssl_fc_has_early-O2.c |   6 +-
 ...eref-pr108251-smp_fetch_ssl_fc_has_early.c |   6 +-
 .../analyzer/null-deref-pr108806-qemu.c       |  10 +-
 .../analyzer/null-deref-pr108830.c            |  16 +-
 .../analyzer/pr101962.c                       |  12 +-
 .../analyzer/pr103217-2.c                     |   2 +-
 .../analyzer/pr103217.c                       |  11 +-
 .../analyzer/pr104029.c                       |   2 +-
 .../analyzer/pr104062.c                       |   4 +-
 .../analyzer/pr104369-1.c                     |  17 +-
 .../analyzer/pr104369-2.c                     |  17 +-
 .../analyzer/pr105783.c                       |   6 +-
 .../analyzer/pr107345.c                       |   3 +-
 gcc/testsuite/c-c++-common/analyzer/pr61861.c |   3 +
 gcc/testsuite/c-c++-common/analyzer/pr93457.c |  12 ++
 .../analyzer/pr93695-1.c                      |   6 +-
 .../analyzer/pr94596.c                        |  14 +-
 .../analyzer/pr94839.c                        |   2 +-
 .../analyzer/pr95152-4.c                      |   4 +-
 .../analyzer/pr95152-5.c                      |   1 +
 .../analyzer/pr95240.c                        |   2 +-
 .../analyzer/pr96639.c                        |   2 +-
 .../analyzer/pr96653.c                        |  26 +--
 .../analyzer/pr96792.c                        |  10 +-
 .../analyzer/pr96841.c                        |   2 +-
 gcc/testsuite/c-c++-common/analyzer/pr97568.c |  40 ++++
 .../analyzer/pr98564.c                        |   2 +-
 .../analyzer/pr98628.c                        |   4 +-
 .../analyzer/pr98969.c                        |   5 +-
 .../analyzer/pr99193-2.c                      |   2 +-
 .../analyzer/pr99193-3.c                      |  13 +-
 .../analyzer/pr99716-1.c                      |  10 +-
 .../analyzer/pr99774-1.c                      |   2 +-
 .../analyzer/realloc-1.c                      |  11 +-
 .../analyzer/realloc-2.c                      |  14 +-
 .../analyzer/realloc-3.c                      |  14 +-
 .../analyzer/realloc-4.c                      |   2 +-
 .../analyzer/realloc-5.c                      |   4 +-
 .../analyzer/realloc-pr110014.c               |   6 +-
 .../analyzer/snprintf-concat.c                |  14 +-
 .../analyzer/sock-1.c                         |   8 +-
 .../c-c++-common/analyzer/sprintf-2.c         |  58 ++++++
 .../analyzer/sprintf-concat.c                 |  15 +-
 .../analyzer/string-ops-concat-pair.c         |  19 +-
 .../analyzer/string-ops-dup.c                 |  19 +-
 .../switch-enum-pr105273-git-vreportf-2.c     |   2 +-
 .../analyzer/symbolic-12.c                    |  10 +-
 .../c-c++-common/analyzer/test-alloca.h       |   3 +
 .../c-c++-common/analyzer/test-assert.h       |   7 +
 .../c-c++-common/analyzer/test-setjmp.h       |  27 +++
 .../c-c++-common/analyzer/test-uaccess.h      |  15 ++
 .../analyzer/uninit-alloca.c                  |   2 +-
 .../analyzer/untracked-2.c                    |   2 +-
 .../analyzer/vasprintf-1.c                    |  10 +-
 .../analyzer/write-to-const-1.c               |   2 +-
 .../analyzer/write-to-function-1.c            |   2 +
 .../analyzer/write-to-string-literal-1.c      |  15 ++
 .../analyzer/write-to-string-literal-1bis.c}  |  13 +-
 .../write-to-string-literal-4-disabled.c      |   2 +-
 .../analyzer/write-to-string-literal-4.c      |  26 +++
 .../analyzer/write-to-string-literal-5.c      |   8 +-
 gcc/testsuite/g++.dg/analyzer/analyzer.exp    |   3 +
 .../analyzer/allocation-size-multiline-1.c    |  59 ------
 .../analyzer/allocation-size-multiline-2.c    |  62 ------
 .../analyzer/allocation-size-multiline-3.c    |  44 ----
 gcc/testsuite/gcc.dg/analyzer/analyzer.exp    |   3 +
 gcc/testsuite/gcc.dg/analyzer/data-model-11.c |   6 -
 gcc/testsuite/gcc.dg/analyzer/inlining-3.c    |  30 ---
 gcc/testsuite/gcc.dg/analyzer/inlining-4.c    |  27 ---
 gcc/testsuite/gcc.dg/analyzer/pr61861.c       |   2 -
 gcc/testsuite/gcc.dg/analyzer/pr93457.c       |  10 -
 gcc/testsuite/gcc.dg/analyzer/pr97568.c       |  29 ---
 gcc/testsuite/gcc.dg/analyzer/sprintf-1.c     |  45 +----
 .../analyzer/write-to-string-literal-4.c      |  23 ---
 127 files changed, 1516 insertions(+), 647 deletions(-)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/aliasing-3.c (85%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/aliasing-pr106473.c (53%)
 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/analyzer-decls.h
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/asm-x86-dyndbg-2.c (96%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/asm-x86-lp64-2.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/atomic-builtins-haproxy-proxy.c (95%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/atomic-builtins-qemu-sockets.c (74%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/attr-malloc-6.c (88%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c (97%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/attr-tainted_args-1.c (96%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/call-summaries-pr107158.c (95%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/calloc-1.c (76%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/compound-assignment-5.c (84%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/coreutils-cksum-pr108664.c (97%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/coreutils-sum-pr108666.c (97%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/data-model-11.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr108455-1.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr108455-git-pack-revindex.c (98%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr108475-1.c (86%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c (97%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr109239-linux-bus.c (93%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/deref-before-check-pr77425.c (84%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/exec-1.c (56%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/feasibility-3.c (92%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/fields.c (92%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/function-ptr-5.c (85%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/infinite-recursion-pr108524-1.c (95%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/infinite-recursion-pr108524-2.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/infinite-recursion-pr108524-qobject-json-parser.c (97%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/init.c (98%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/inlining-3-multiline.c (54%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-3.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/inlining-4-multiline.c (52%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/inlining-4.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/leak-pr105906.c (70%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/leak-pr108045-with-call-summaries.c (83%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/leak-pr108045-without-call-summaries.c (84%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/leak-pr109059-1.c (93%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/leak-pr109059-2.c (92%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/malloc-2.c (89%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/memcpy-2.c (79%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c (93%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c (93%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/null-deref-pr108806-qemu.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/null-deref-pr108830.c (89%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr101962.c (89%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr103217-2.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr103217.c (86%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr104029.c (97%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr104062.c (70%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr104369-1.c (77%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr104369-2.c (77%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr105783.c (85%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr107345.c (73%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr61861.c
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr93457.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr93695-1.c (83%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr94596.c (93%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr94839.c (82%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr95152-4.c (55%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr95152-5.c (61%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr95240.c (89%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr96639.c (80%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr96653.c (98%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr96792.c (82%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr96841.c (77%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/pr97568.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr98564.c (59%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr98628.c (100%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr98969.c (61%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr99193-2.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr99193-3.c (85%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr99716-1.c (83%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/pr99774-1.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-1.c (84%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-2.c (92%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-3.c (92%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-4.c (99%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-5.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/realloc-pr110014.c (70%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/snprintf-concat.c (74%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/sock-1.c (91%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/sprintf-2.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/sprintf-concat.c (74%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/string-ops-concat-pair.c (80%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/string-ops-dup.c (79%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/switch-enum-pr105273-git-vreportf-2.c (94%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/symbolic-12.c (90%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/test-alloca.h
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/test-assert.h
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/test-setjmp.h
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/uninit-alloca.c (57%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/untracked-2.c (76%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/vasprintf-1.c (90%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/write-to-const-1.c (91%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/write-to-function-1.c (81%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1.c
 rename gcc/testsuite/{gcc.dg/analyzer/write-to-string-literal-1.c => c-c++-common/analyzer/write-to-string-literal-1bis.c} (86%)
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/write-to-string-literal-4-disabled.c (94%)
 create mode 100644 gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4.c
 rename gcc/testsuite/{gcc.dg => c-c++-common}/analyzer/write-to-string-literal-5.c (62%)
 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/data-model-11.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-3.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/inlining-4.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr61861.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr93457.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/pr97568.c
 delete mode 100644 gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4.c
  

Comments

David Malcolm Aug. 25, 2023, 12:12 a.m. UTC | #1
> From: benjamin priour <priour.be@gmail.com>
> 
> Hi,
> 
> Below the first batch of a serie of patches to transition
> the analyzer testsuite from gcc.dg/analyzer to c-c++-common/analyzer.
> I do not know how long this serie will be, thus the patch was not
> numbered.
> 
> For the grand majority of the tests, the transition only required some
> adjustement over the syntax and casts to be C++-friendly, or to adjust
> the warnings regexes to fit the C++ FE.
> 
> The most noteworthy change is in the handling of known_functions,
> as described in the below patch.

Hi Benjamin.

Many thanks for putting this together, it looks like it was a lot of
work.

> Successfully regstrapped on x86_64-linux-gnu off trunk
> 18befd6f050e70f11ecca1dd58624f0ee3c68cc7.

Did you compare the before/after results from DejaGnu somehow?

Note that I've pushed 9 patches to the analyzer since
18befd6f050e70f11ecca1dd58624f0ee3c68cc7 and some of those touch the
files below, so it's worth rebasing and double-checking the results.

> Is it OK for trunk ?

It's *almost* ready; various comments inline below, throughout...

> 
> Thanks,
> Benjamin.
> 
> Patch below.
> ---
> 
> 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 <vultkayn@gcc.gnu.org>
> 
> gcc/analyzer/ChangeLog:

Please add
 	PR analyzer/96395
to the ChangeLog entries, and [PR96395] to the end of the Subject of
the commit, so that these get tracked within that bug as they get
pushed.

> 
> 	* 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_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:

Add
 	PR analyzer/96395
here, as well, please.

> 
> 	* gcc.dg/analyzer/aliasing-3.c: Moved to...
> 	* c-c++-common/analyzer/aliasing-3.c: ...here.

[...snip...]

> diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
> index 93a28b4b5cf..63a220c9b6d 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,28 @@ public:
>    {
>      return;
>    }
> +
> +  virtual const builtin_known_function *
> +  dyn_cast_builtin_kf () const { return NULL; }
> +  virtual builtin_known_function *
> +  dyn_cast_builtin_kf () { return NULL; }

I don't think we ever work with non-const known_function pointers, so
we don't need this non-const version of the vfunc.

> +};
> +
> +/* 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;
> +  }
> +
> +  virtual const builtin_known_function *
> +  dyn_cast_builtin_kf () const { return this; }

This doesn't need a "virtual", but should have a "final override".


> +  virtual builtin_known_function *
> +  dyn_cast_builtin_kf () { return this; }

Drop the non-const overload, as noted above.

>  };
>  
>  /* Subclass of known_function for IFN_* functions.  */
> diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
> index 59f46bab581..6c58a1b20e5 100644
> --- a/gcc/analyzer/kf.cc
> +++ b/gcc/analyzer/kf.cc

[...snip...]

> @@ -1406,41 +1491,69 @@ register_known_functions (known_function_manager &kfm)
>      kfm.add (IFN_UBSAN_BOUNDS, make_unique<kf_ubsan_bounds> ());
>    }
>  
> -  /* Built-ins the analyzer has known_functions for.  */
> +  /* GCC built-ins that does not correspond to a function
> +     in the standard library.  */

"does not" -> "do not"

[...snip...]

> diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
> index 99817aee3a9..3a8f07525ba 100644
> --- a/gcc/analyzer/region-model.cc
> +++ b/gcc/analyzer/region-model.cc
> @@ -1514,6 +1514,34 @@ 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.  */

I confess I'm still a little hazy as to the whole builtin_kf logic, but
I trust you that this is needed.

Please can you add a paragraph to this comment to explain the
motivation here (perhaps giving examples?)

> +
> +const builtin_known_function *
> +region_model::get_builtin_kf (const gcall *call,
> +			       region_model_context *ctxt /* = NULL */) const
> +{
> +  region_model *mut_this = const_cast <region_model *> (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;
> +}
> +

[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> similarity index 85%
> rename from gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
> rename to gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> index 003077ad5c1..f78fea64fbe 100644
> --- a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
> +++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> @@ -1,6 +1,14 @@
>  #include "analyzer-decls.h"
>  
> -#define NULL ((void *)0)
> +#ifdef __cplusplus
> +  #if __cplusplus >= 201103L
> +  #define NULL nullptr
> +  #else
> +  #define NULL 0
> +  #endif
> +#else
> +  #define NULL ((void *)0)
> +#endif

The above fragment of code gets used a lot; can it be moved into
analyzer-decls.h, perhaps wrapped in a "#ifndef NULL"?

That could be done as a followup patch if it's easier.

[...snip...]

> diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
> new file mode 100644
> index 00000000000..d9a32ed9370
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
> @@ -0,0 +1,56 @@
> +#ifndef ANALYZER_DECLS_H
> +#define ANALYZER_DECLS_H
> +
[...snip...]
> +
> +/* Obtain an "unknown" void *.  */
> +extern void *__analyzer_get_unknown_ptr (void);
> +
> +#endif /* #ifndef ANALYZER_DECLS_H.  */

We don't want to have a copy of the file here (the "DRY principle"). 
For example, I added a __analyzer_get_strlen in
325f9e88802daaca0a4793ca079bb504f7d76c54 which doesn't seem to be in
this copy.

Can we simply have something like

  #include "../../gcc.dg/analyzer/analyzer-decls.h"

here so that we're getting the "real" analyzer-decls.h by reference.

The relative path in the above #include might need tweaking as I'm not
sure exactly what "-I" directives are passed in when running the c-c++-
common tests.


[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
> similarity index 79%
> rename from gcc/testsuite/gcc.dg/analyzer/memcpy-2.c
> rename to gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
> index 51e4a694951..25b0a5e4ff4 100644
> --- a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c
> +++ b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
> @@ -1,8 +1,9 @@
>  /* { dg-additional-options "-Wno-stringop-overflow -Wno-analyzer-out-of-bounds" } */
>  
> -void
> -main (int c, void *v)
> +int
> +test (int c, void *v)
>  {
>    static char a[] = "";
>    __builtin_memcpy (v, a, -1);
> +  return 0;
>  }

FWIW, the analyzer special-cases the handling of functions named
"main", but I don't think it matters for this testcase, so the renaming
is OK.

[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
> similarity index 77%
> rename from gcc/testsuite/gcc.dg/analyzer/pr96841.c
> rename to gcc/testsuite/c-c++-common/analyzer/pr96841.c
> index 14f3f7a86a3..dd61176b73b 100644
> --- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c
> +++ b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
> @@ -12,7 +12,7 @@ th (int *);
>  void
>  bv (__SIZE_TYPE__ ny, int ***mf)
>  {
> -  while (l8 ())
> +  while (l8 ()) /* { dg-warning "terminating analysis for this program point" } */
>      {
>        *mf = 0;
>        (*mf)[ny] = (int *) malloc (sizeof (int));

Does this warning happen for both C and C++?

It's probably better to simply add -Wno-analyzer-too-complex to this
case, as we don't want to be fussy about precisely which line the
message is emitted at (or, indeed, that the warning is emitted at all).

[...snip...]

> diff --git a/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h b/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h
> new file mode 100644
> index 00000000000..52c57d02b70
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h
> @@ -0,0 +1,27 @@
> +/* Various integration tests for setjmp-handling expect a precise
> +   multiline output.
> +   
> +   The outputs from -fdiagnostics-path-format=inline-events for such
> +   setjmp tests are dependent on whether setjmp is a macro or a function
> +   (and whether that macro is defined in a system header).
> +
> +   setjmp is a function on some systems and a macro on others.
> +   This header provides a SETJMP macro in a (fake) system header,
> +   along with precanned decls of setjmp, for consistency of output across
> +   different systems.  */
> +
> +#pragma GCC system_header
> +
> +struct __jmp_buf_tag {
> +  char buf[1];
> +};
> +typedef struct __jmp_buf_tag jmp_buf[1];
> +typedef struct __jmp_buf_tag sigjmp_buf[1];
> +
> +extern int setjmp(jmp_buf env);
> +extern int sigsetjmp(sigjmp_buf env, int savesigs);
> +
> +extern void longjmp(jmp_buf env, int val);
> +extern void siglongjmp(sigjmp_buf env, int val);
> +
> +#define SETJMP(E) setjmp(E)

Is this a copy of gcc.dg/analyzer/test-setjmp.h ?
If so, can the content of that file be #included from this one, rather
than keeping a copy.

> diff --git a/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
b/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
> new file mode 100644
> index 00000000000..70c9d6309ef
> --- /dev/null
> +++ b/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
> @@ -0,0 +1,15 @@
> +/* Shared header for testcases for copy_from_user/copy_to_user.  */
> +
> +/* Adapted from include/linux/compiler.h  */
> +
> +#define __user
> +
> +/* Adapted from include/asm-generic/uaccess.h  */
> +
> +extern int copy_from_user(void *to, const void __user *from, long n)
> +  __attribute__((access (write_only, 1, 3),
> +		 access (read_only, 2, 3)));
> +
> +extern long copy_to_user(void __user *to, const void *from, unsigned long n)
> +  __attribute__((access (write_only, 1, 3),
> +		 access (read_only, 2, 3)));

Similarly here, can this be a #include of the other file, rather than a
copy?

[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
> similarity index 86%
> rename from gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
> rename to gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
> index 092500e066f..7d06febba77 100644
> --- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
> +++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
> @@ -1,20 +1,21 @@
>  #include <string.h>
>  
> +#ifdef __cplusplus
> +#define CONST_CAST(type) const_cast<type>
> +#else
> +#define CONST_CAST(type)
> +#endif
> +
>  /* PR analyzer/95007.  */
>  
>  void test_1 (void)
>  {
> -  char *s = "foo";
> +  char *s = CONST_CAST(char *)("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)
>  {

Why the rename from -1.c to to -1bis.c ?

[...snip...]

> diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> index f8dc806d619..e94c0561665 100644
> --- a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> +++ b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> @@ -1,53 +1,14 @@
>  /* See e.g. https://en.cppreference.com/w/c/io/fprintf
>     and https://www.man7.org/linux/man-pages/man3/sprintf.3.html */
>  
> +/* { dg-skip-if "C++ fpermissive already throws an error" { c++ } } */

Given that this is in the gcc.dg directory, this directive presumably
never skips.

Is the intent here to document that
(a) this set of tests is just for C, and
(b) you've checked that this test has been examined, and isn't on the
"TODO" list to be migrated?

If so, could it just be a regular comment for humans?

> +
>  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)

Looks like you split this out into sprintf-2.c, but note that I
recently touched sprintf-1.c in
3b691e0190c6e7291f8a52e1e14d8293a28ff4ce and in
5ef89c5c2f52a2c47fd26845d1f73e20b9081fc9.  I think those changes affect
the rest of the file below this hunk, but does the result still work
after rebasing?  Should any of those changes have been moved to c-c++-
common?

[...snip...]

Thanks again for the patch.

This will be OK for trunk with the above issues fixed.

Dave
  
Benjamin Priour Aug. 25, 2023, 12:48 p.m. UTC | #2
Hi David,

Thanks for the review.

On Fri, Aug 25, 2023 at 2:12 AM David Malcolm <dmalcolm@redhat.com> wrote:

> > From: benjamin priour <priour.be@gmail.com>
> >
> > Hi,
> >
> > Below the first batch of a serie of patches to transition
> > the analyzer testsuite from gcc.dg/analyzer to c-c++-common/analyzer.
> > I do not know how long this serie will be, thus the patch was not
> > numbered.
> >
> > For the grand majority of the tests, the transition only required some
> > adjustement over the syntax and casts to be C++-friendly, or to adjust
> > the warnings regexes to fit the C++ FE.
> >
> > The most noteworthy change is in the handling of known_functions,
> > as described in the below patch.
>
> Hi Benjamin.
>
> Many thanks for putting this together, it looks like it was a lot of
> work.
>
> > Successfully regstrapped on x86_64-linux-gnu off trunk
> > 18befd6f050e70f11ecca1dd58624f0ee3c68cc7.
>
> Did you compare the before/after results from DejaGnu somehow?
>
> Note that I've pushed 9 patches to the analyzer since
> 18befd6f050e70f11ecca1dd58624f0ee3c68cc7 and some of those touch the
> files below, so it's worth rebasing and double-checking the results.
>
>
Thanks for the info, I've rebased off it and I'm regstrapping.
For tests I didn't touch the warnings, I have checked they still pass in C
and C++.
Except for pr96841.c, C tests most notable update was to add a { target c }.
Every previous PASS and XFAIL remained as such in gcc.dg output.
For C++ I went  with a no failure policy. Some tests weren't making sense
in C++,
such as transparent_unions. I've just skipped those.
For some tests C++ fpermissive would throw out an error. These tests I've
tried
to smuggle them out with const_cast and the likes, but never disabled
fpermissive.


> Please add
>         PR analyzer/96395
> to the ChangeLog entries, and [PR96395] to the end of the Subject of
> the commit, so that these get tracked within that bug as they get
> pushed.
>
>
Nods.

[...snip...]


> I confess I'm still a little hazy as to the whole builtin_kf logic, but
> I trust you that this is needed.
>
> Please can you add a paragraph to this comment to explain the
> motivation here (perhaps giving examples?)
>
> > +
> > +const builtin_known_function *
> > +region_model::get_builtin_kf (const gcall *call,
> > +                            region_model_context *ctxt /* = NULL */)
> const
> > +{
> > +  region_model *mut_this = const_cast <region_model *> (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;
> > +}
> > +
>
>
The new comment is as follow:

/* 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.  */

I hope it clarifies the new kf subclass's purpose.

[...snip...]
>
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
> b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> > similarity index 85%
> > rename from gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
> > rename to gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> > index 003077ad5c1..f78fea64fbe 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
> > +++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
> > @@ -1,6 +1,14 @@
> >  #include "analyzer-decls.h"
> >
> > -#define NULL ((void *)0)
> > +#ifdef __cplusplus
> > +  #if __cplusplus >= 201103L
> > +  #define NULL nullptr
> > +  #else
> > +  #define NULL 0
> > +  #endif
> > +#else
> > +  #define NULL ((void *)0)
> > +#endif
>
> The above fragment of code gets used a lot; can it be moved into
> analyzer-decls.h, perhaps wrapped in a "#ifndef NULL"?
>
> That could be done as a followup patch if it's easier.
>
>
Done.

[...snip...]
>
> > diff --git a/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
> b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
> > new file mode 100644
> > index 00000000000..d9a32ed9370
> > --- /dev/null
> > +++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
> > @@ -0,0 +1,56 @@
> > +#ifndef ANALYZER_DECLS_H
> > +#define ANALYZER_DECLS_H
> > +
> [...snip...]
> > +
> > +/* Obtain an "unknown" void *.  */
> > +extern void *__analyzer_get_unknown_ptr (void);
> > +
> > +#endif /* #ifndef ANALYZER_DECLS_H.  */
>
> We don't want to have a copy of the file here (the "DRY principle").
> For example, I added a __analyzer_get_strlen in
> 325f9e88802daaca0a4793ca079bb504f7d76c54 which doesn't seem to be in
> this copy.
>
> Can we simply have something like
>
>   #include "../../gcc.dg/analyzer/analyzer-decls.h"
>
> here so that we're getting the "real" analyzer-decls.h by reference.
>
> The relative path in the above #include might need tweaking as I'm not
> sure exactly what "-I" directives are passed in when running the c-c++-
> common tests.
>
>
Thanks for noticing that, I had basically copied them to a test subfolder
and was in auto mode when writing the Changelog, I didn't even notice the
copy.
I will double check all the duplicates.

[...snip...]


> > diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c
> b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
> > similarity index 77%
> > rename from gcc/testsuite/gcc.dg/analyzer/pr96841.c
> > rename to gcc/testsuite/c-c++-common/analyzer/pr96841.c
> > index 14f3f7a86a3..dd61176b73b 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c
> > +++ b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
> > @@ -12,7 +12,7 @@ th (int *);
> >  void
> >  bv (__SIZE_TYPE__ ny, int ***mf)
> >  {
> > -  while (l8 ())
> > +  while (l8 ()) /* { dg-warning "terminating analysis for this program
> point" } */
> >      {
> >        *mf = 0;
> >        (*mf)[ny] = (int *) malloc (sizeof (int));
>
> Does this warning happen for both C and C++?
>
> It's probably better to simply add -Wno-analyzer-too-complex to this
> case, as we don't want to be fussy about precisely which line the
> message is emitted at (or, indeed, that the warning is emitted at all).
>
>
OK. The warning does appear both for C and C++ now, and I wanted to
emphasis this, yet
it is not relevant for the long-term.
Note this new warning is the only divergence in C Dejagnu tests between
trunk and my patch,
and was added after discussion
https://gcc.gnu.org/pipermail/gcc/2023-August/242317.html.

[...snip...]


> Why the rename from -1.c to to -1bis.c ?
>
>
I had to split it up at some point between C-only (-1bis.c) and
C++-friendly (-1.c still there).
The Changelog didn't reflect that though.
Actually double-checked and merged them back, as a const_cast made -1bis
work in C++.


> [...snip...]
>
> > diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > index f8dc806d619..e94c0561665 100644
> > --- a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > +++ b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > @@ -1,53 +1,14 @@
> >  /* See e.g. https://en.cppreference.com/w/c/io/fprintf
> >     and https://www.man7.org/linux/man-pages/man3/sprintf.3.html */
> >
> > +/* { dg-skip-if "C++ fpermissive already throws an error" { c++ } } */
>
> Given that this is in the gcc.dg directory, this directive presumably
> never skips.
>
> Is the intent here to document that
> (a) this set of tests is just for C, and
> (b) you've checked that this test has been examined, and isn't on the
> "TODO" list to be migrated?
>
> If so, could it just be a regular comment for humans?
>
>
Nods. I will do the same for tests with transparent_union.
FWIW I'm logging on my side which tests I have already checked for C++
and discarded.
FYI here is the new comment

/* This test needs not be moved to c-c++-common/analyzer as C++
   fpermissive already throws errors. */

> +
> >  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)
>
> Looks like you split this out into sprintf-2.c, but note that I
> recently touched sprintf-1.c in
> 3b691e0190c6e7291f8a52e1e14d8293a28ff4ce and in
> 5ef89c5c2f52a2c47fd26845d1f73e20b9081fc9.  I think those changes affect
> the rest of the file below this hunk, but does the result still work
> after rebasing?  Should any of those changes have been moved to c-c++-
> common?
>
>
Your new change with strlen has been added to the C++-friendly bit.


> [...snip...]
>
> Thanks again for the patch.
>
> This will be OK for trunk with the above issues fixed.
>
> Dave
>
>
Updated patch will follow when done with regstrapping.
Thanks,
Benjamin.
  
David Malcolm Aug. 25, 2023, 8:10 p.m. UTC | #3
On Fri, 2023-08-25 at 14:48 +0200, Benjamin Priour wrote:
> Hi David,
> 
> Thanks for the review.
> 
> On Fri, Aug 25, 2023 at 2:12 AM David Malcolm <dmalcolm@redhat.com>
> wrote:
> 
> > > From: benjamin priour <priour.be@gmail.com>
> > > 
> > > Hi,
> > > 
> > > Below the first batch of a serie of patches to transition
> > > the analyzer testsuite from gcc.dg/analyzer to c-c++-
> > > common/analyzer.
> > > I do not know how long this serie will be, thus the patch was not
> > > numbered.
> > > 
> > > For the grand majority of the tests, the transition only required
> > > some
> > > adjustement over the syntax and casts to be C++-friendly, or to
> > > adjust
> > > the warnings regexes to fit the C++ FE.
> > > 
> > > The most noteworthy change is in the handling of known_functions,
> > > as described in the below patch.
> > 
> > Hi Benjamin.
> > 
> > Many thanks for putting this together, it looks like it was a lot
> > of
> > work.
> > 
> > > Successfully regstrapped on x86_64-linux-gnu off trunk
> > > 18befd6f050e70f11ecca1dd58624f0ee3c68cc7.
> > 
> > Did you compare the before/after results from DejaGnu somehow?
> > 
> > Note that I've pushed 9 patches to the analyzer since
> > 18befd6f050e70f11ecca1dd58624f0ee3c68cc7 and some of those touch
> > the
> > files below, so it's worth rebasing and double-checking the
> > results.
> > 
> > 

[...snip...]

> 
> > I confess I'm still a little hazy as to the whole builtin_kf logic,
> > but
> > I trust you that this is needed.
> > 
> > Please can you add a paragraph to this comment to explain the
> > motivation here (perhaps giving examples?)
> > 
> > > +
> > > +const builtin_known_function *
> > > +region_model::get_builtin_kf (const gcall *call,
> > > +                            region_model_context *ctxt /* = NULL
> > > */)
> > const
> > > +{
> > > +  region_model *mut_this = const_cast <region_model *> (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;
> > > +}
> > > +
> > 
> > 
> The new comment is as follow:
> 
> /* 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.  */
> 
> I hope it clarifies the new kf subclass's purpose.

Thanks!

[...snip...]

> > 
> 
> > > diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > > index f8dc806d619..e94c0561665 100644
> > > --- a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > > +++ b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
> > > @@ -1,53 +1,14 @@
> > >  /* See e.g. https://en.cppreference.com/w/c/io/fprintf
> > >     and
> > > https://www.man7.org/linux/man-pages/man3/sprintf.3.html */
> > > 
> > > +/* { dg-skip-if "C++ fpermissive already throws an error" { c++
> > > } } */
> > 
> > Given that this is in the gcc.dg directory, this directive
> > presumably
> > never skips.
> > 
> > Is the intent here to document that
> > (a) this set of tests is just for C, and
> > (b) you've checked that this test has been examined, and isn't on
> > the
> > "TODO" list to be migrated?
> > 
> > If so, could it just be a regular comment for humans?
> > 
> > 
> Nods. I will do the same for tests with transparent_union.
> FWIW I'm logging on my side which tests I have already checked for
> C++
> and discarded.
> FYI here is the new comment
> 
> /* This test needs not be moved to c-c++-common/analyzer as C++
>    fpermissive already throws errors. */

Thanks.

(though FWIW I'd say "emits" rather than "throws" here; "throws" makes
me think of exceptions, when you're talking about diagnostics, right?)

[...snip...]

> > 
> > Looks like you split this out into sprintf-2.c, but note that I
> > recently touched sprintf-1.c in
> > 3b691e0190c6e7291f8a52e1e14d8293a28ff4ce and in
> > 5ef89c5c2f52a2c47fd26845d1f73e20b9081fc9.  I think those changes
> > affect
> > the rest of the file below this hunk, but does the result still
> > work
> > after rebasing?  Should any of those changes have been moved to c-
> > c++-
> > common?
> > 
> > 
> Your new change with strlen has been added to the C++-friendly bit.
> 
> 
> > [...snip...]
> > 
> > Thanks again for the patch.
> > 
> > This will be OK for trunk with the above issues fixed.
> > 
> > Dave
> > 
> > 
> Updated patch will follow when done with regstrapping.

Thanks!

I have some low-urgency patches that touch analyzer testcases, so I'll
wait to push them until after your patch is in trunk.  Once your patch
is in trunk  I can try to ensure all my new testcases go in the c-c++-
common/analyzer subdirectory, from then on (using the support for this
that your patch adds).

Dave
  

Patch

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 93a28b4b5cf..63a220c9b6d 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,28 @@  public:
   {
     return;
   }
+
+  virtual const builtin_known_function *
+  dyn_cast_builtin_kf () const { return NULL; }
+  virtual builtin_known_function *
+  dyn_cast_builtin_kf () { 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;
+  }
+
+  virtual const builtin_known_function *
+  dyn_cast_builtin_kf () const { return this; }
+  virtual builtin_known_function *
+  dyn_cast_builtin_kf () { return this; }
 };
 
 /* Subclass of known_function for IFN_* functions.  */
diff --git a/gcc/analyzer/kf.cc b/gcc/analyzer/kf.cc
index 59f46bab581..6c58a1b20e5 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
@@ -563,15 +607,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
@@ -753,7 +803,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
@@ -762,6 +812,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;
 };
 
@@ -974,7 +1030,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
@@ -985,6 +1041,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;
 };
 
@@ -1061,7 +1122,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
@@ -1071,6 +1132,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
@@ -1114,21 +1180,27 @@  public:
 
 /* 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
@@ -1162,13 +1234,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 ();
@@ -1189,13 +1265,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 *bytes_read = cd.check_for_null_terminated_string_arg (0))
@@ -1227,13 +1308,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 ();
@@ -1406,41 +1491,69 @@  register_known_functions (known_function_manager &kfm)
     kfm.add (IFN_UBSAN_BOUNDS, make_unique<kf_ubsan_bounds> ());
   }
 
-  /* Built-ins the analyzer has known_functions for.  */
+  /* GCC built-ins that does not correspond to a function
+     in the standard library.  */
   {
-    kfm.add (BUILT_IN_ALLOCA, make_unique<kf_alloca> ());
-    kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, make_unique<kf_alloca> ());
-    kfm.add (BUILT_IN_CALLOC, make_unique<kf_calloc> ());
     kfm.add (BUILT_IN_EXPECT, make_unique<kf_expect> ());
     kfm.add (BUILT_IN_EXPECT_WITH_PROBABILITY, make_unique<kf_expect> ());
-    kfm.add (BUILT_IN_FREE, make_unique<kf_free> ());
-    kfm.add (BUILT_IN_MALLOC, make_unique<kf_malloc> ());
-    kfm.add (BUILT_IN_MEMCPY, make_unique<kf_memcpy_memmove> ());
-    kfm.add (BUILT_IN_MEMCPY_CHK, make_unique<kf_memcpy_memmove> ());
-    kfm.add (BUILT_IN_MEMMOVE, make_unique<kf_memcpy_memmove> ());
-    kfm.add (BUILT_IN_MEMMOVE_CHK, make_unique<kf_memcpy_memmove> ());
-    kfm.add (BUILT_IN_MEMSET, make_unique<kf_memset> ());
-    kfm.add (BUILT_IN_MEMSET_CHK, make_unique<kf_memset> ());
-    kfm.add (BUILT_IN_REALLOC, make_unique<kf_realloc> ());
-    kfm.add (BUILT_IN_SPRINTF, make_unique<kf_sprintf> ());
+    kfm.add (BUILT_IN_ALLOCA_WITH_ALIGN, make_unique<kf_alloca> ());
     kfm.add (BUILT_IN_STACK_RESTORE, make_unique<kf_stack_restore> ());
     kfm.add (BUILT_IN_STACK_SAVE, make_unique<kf_stack_save> ());
-    kfm.add (BUILT_IN_STRCHR, make_unique<kf_strchr> ());
-    kfm.add (BUILT_IN_STRCPY, make_unique<kf_strcpy> (2));
-    kfm.add (BUILT_IN_STRCPY_CHK, make_unique<kf_strcpy> (3));
-    kfm.add (BUILT_IN_STRDUP, make_unique<kf_strdup> ());
-    kfm.add (BUILT_IN_STRNDUP, make_unique<kf_strndup> ());
-    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<kf_memset> ());
+    kfm.add ("alloca", make_unique<kf_alloca> ());
+    kfm.add ("__builtin_alloca", make_unique<kf_alloca> ());
+    kfm.add ("calloc", make_unique<kf_calloc> ());
+    kfm.add ("__builtin_calloc", make_unique<kf_calloc> ());
+    kfm.add ("free", make_unique<kf_free> ());
+    kfm.add ("__builtin_free", make_unique<kf_free> ());
+    kfm.add ("malloc", make_unique<kf_malloc> ());
+    kfm.add ("__builtin_malloc", make_unique<kf_malloc> ());
+    kfm.add ("memcpy",
+	      make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
+    kfm.add ("__builtin_memcpy",
+	      make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMCPY));
+    kfm.add ("__memcpy_chk", make_unique<kf_memcpy_memmove>
+			      (kf_memcpy_memmove::KF_MEMCPY_CHK));
+    kfm.add ("__builtin___memcpy_chk", make_unique<kf_memcpy_memmove>
+			      (kf_memcpy_memmove::KF_MEMCPY_CHK));
+    kfm.add ("memmove",
+	      make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
+    kfm.add ("__builtin_memmove",
+	      make_unique<kf_memcpy_memmove> (kf_memcpy_memmove::KF_MEMMOVE));
+    kfm.add ("__memmove_chk", make_unique<kf_memcpy_memmove>
+			      (kf_memcpy_memmove::KF_MEMMOVE_CHK));
+    kfm.add ("__builtin___memmove_chk", make_unique<kf_memcpy_memmove>
+			      (kf_memcpy_memmove::KF_MEMMOVE_CHK));
+    kfm.add ("memset", make_unique<kf_memset> (false));
+    kfm.add ("__builtin_memset", make_unique<kf_memset> (false));
+    kfm.add ("__memset_chk", make_unique<kf_memset> (true));
+    kfm.add ("__builtin___memset_chk", make_unique<kf_memset> (true));
+    kfm.add ("realloc", make_unique<kf_realloc> ());
+    kfm.add ("__builtin_realloc", make_unique<kf_realloc> ());
+    kfm.add ("sprintf", make_unique<kf_sprintf> ());
+    kfm.add ("__builtin_sprintf", make_unique<kf_sprintf> ());
+    kfm.add ("strchr", make_unique<kf_strchr> ());
+    kfm.add ("__builtin_strchr", make_unique<kf_strchr> ());
+    kfm.add ("strcpy", make_unique<kf_strcpy> (2, false));
+    kfm.add ("__builtin_strcpy", make_unique<kf_strcpy> (2, false));
+    kfm.add ("__strcpy_chk", make_unique<kf_strcpy> (3, true));
+    kfm.add ("__builtin___strcpy_chk", make_unique<kf_strcpy> (3, true));
     kfm.add ("strdup", make_unique<kf_strdup> ());
+    kfm.add ("__builtin_strdup", make_unique<kf_strdup> ());
     kfm.add ("strndup", make_unique<kf_strndup> ());
+    kfm.add ("__builtin_strndup", make_unique<kf_strndup> ());
+    kfm.add ("strlen", make_unique<kf_strlen> ());
+    kfm.add ("__builtin_strlen", make_unique<kf_strlen> ());
+
+    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 4a2cf52d0b8..615c495f895 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 1432e548acb..04f49ceb768 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 99817aee3a9..3a8f07525ba 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -1514,6 +1514,34 @@  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.  */
+
+const builtin_known_function *
+region_model::get_builtin_kf (const gcall *call,
+			       region_model_context *ctxt /* = NULL */) const
+{
+  region_model *mut_this = const_cast <region_model *> (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 3979bf12478..5dec1280c9e 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -514,6 +514,10 @@  class region_model
 					unsigned idx,
 					const svalue **out_sval = nullptr);
 
+  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 c75744ff63a..34bbd84f6e7 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<fd_use_after_close>
 			       (*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<fd_use_without_check>
 				 (*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<fd_access_mode_mismatch> (*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<fd_access_mode_mismatch> (*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 ec763254b29..2ff777daaca 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 <malloc_state_machine *> (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<possible_null_arg>
+					    (*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<null_arg>
+					    (*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<possible_null_arg>
-					   (*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<null_arg>
-					   (*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/gcc.dg/analyzer/aliasing-3.c b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
similarity index 85%
rename from gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
rename to gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
index 003077ad5c1..f78fea64fbe 100644
--- a/gcc/testsuite/gcc.dg/analyzer/aliasing-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-3.c
@@ -1,6 +1,14 @@ 
 #include "analyzer-decls.h"
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 struct s1
 {
@@ -39,7 +47,7 @@  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));
+  p2_glob = (struct s2 *) __builtin_malloc (sizeof (struct s2));
   if (!p2_glob)
     return;
 
@@ -61,7 +69,7 @@  struct s3 *p3_glob = NULL;
 
 void test_3 (struct s3 **pp3, struct s3 *p3_parm)
 {
-  p3_glob = __builtin_malloc (sizeof (struct s3));
+  p3_glob = (struct s3 *) __builtin_malloc (sizeof (struct s3));
   if (!p3_glob)
     return;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c b/gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c
similarity index 53%
rename from gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c
rename to gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c
index afd1492252e..4affa27b26c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/aliasing-pr106473.c
+++ b/gcc/testsuite/c-c++-common/analyzer/aliasing-pr106473.c
@@ -1,5 +1,5 @@ 
 void foo(char **args[], int *argc)
 {
   *argc = 1;
-  (*args)[0] = __builtin_malloc(42);
+  (*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 00000000000..de1a49c436e
--- /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 <stdint.h>
+
+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 00000000000..a5def2764fe
--- /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 <stdint.h>
+
+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 00000000000..e08eba94ba5
--- /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 <stdint.h>
+#include "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/analyzer-decls.h b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
new file mode 100644
index 00000000000..d9a32ed9370
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/analyzer-decls.h
@@ -0,0 +1,56 @@ 
+#ifndef ANALYZER_DECLS_H
+#define ANALYZER_DECLS_H
+
+/* Function decls with special meaning to the analyzer.
+   None of these are actually implemented.  */
+
+/* Trigger a breakpoint in the analyzer when reached.  */
+extern void __analyzer_break (void);
+
+/* Emit a warning describing the 2nd argument (which can be of any
+   type), at the given verbosity level.  This is for use when
+   debugging, and may be of use in DejaGnu tests.  */
+extern void __analyzer_describe (int verbosity, ...);
+
+/* Dump copious information about the analyzer’s state when reached.  */
+extern void __analyzer_dump (void);
+
+/* Emit a warning describing the size of the base region of (*ptr).  */
+extern void __analyzer_dump_capacity (const void *ptr);
+
+/* Dump information about what decls have escaped at this point on the path.  */
+extern void __analyzer_dump_escaped (void);
+
+/* Dump information after analysis on all of the exploded nodes at this
+   program point.
+
+   __analyzer_dump_exploded_nodes (0);
+   will dump just the number of nodes, and their IDs.
+
+   __analyzer_dump_exploded_nodes (1);
+   will also dump all of the states within those nodes.  */
+extern void __analyzer_dump_exploded_nodes (int);
+
+/* Emit a warning describing what is known about the value of NAME.  */
+extern void __analyzer_dump_named_constant (const char *name);
+
+/* Emit a placeholder "note" diagnostic with a path to this call site,
+   if the analyzer finds a feasible path to it.  */
+extern void __analyzer_dump_path (void);
+
+/* Dump the region_model's state to stderr.  */
+extern void __analyzer_dump_region_model (void);
+
+/* Emit a warning describing the state of the 2nd argument
+   (which can be of any type) with respect to NAME.
+   This is for use when debugging, and may be of use in DejaGnu tests.  */
+extern void __analyzer_dump_state (const char *name, ...);
+
+/* Emit a warning with text "TRUE", FALSE" or "UNKNOWN" based on the
+   truthfulness of the argument.  */
+extern void __analyzer_eval (int);
+
+/* Obtain an "unknown" void *.  */
+extern void *__analyzer_get_unknown_ptr (void);
+
+#endif /* #ifndef ANALYZER_DECLS_H.  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c b/gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c
similarity index 96%
rename from gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c
rename to gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c
index 8111709206f..d5e748c9acd 100644
--- a/gcc/testsuite/gcc.dg/analyzer/asm-x86-dyndbg-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/asm-x86-dyndbg-2.c
@@ -8,9 +8,11 @@ 
 /* 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
+#ifndef __cplusplus 
+  typedef _Bool bool;
+  #define true 1
+  #define false 0
+#endif
 
 typedef struct {} atomic_t;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c b/gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c
rename to gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c
index 2864ab69d2a..37c487a69c2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/asm-x86-lp64-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/asm-x86-lp64-2.c
@@ -3,7 +3,9 @@ 
 
 /* Adapted from Linux x86: page_ref_dec_and_test.c (GPL-2.0).  */
 
-typedef _Bool bool;
+#ifndef __cplusplus 
+  typedef _Bool bool;
+#endif
 
 typedef struct {
   int counter;
diff --git a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c
similarity index 95%
rename from gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c
rename to gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c
index 72953a561b8..fbe89f7dfbb 100644
--- a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-haproxy-proxy.c
+++ b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-haproxy-proxy.c
@@ -37,7 +37,7 @@  proxy_capture_error(struct proxy* proxy,
 
   /* [...snip...] */
 
-  es = malloc(sizeof(*es));
+  es = (struct error_snapshot *) malloc(sizeof(*es));
   if (!es)
     return;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c
similarity index 74%
rename from gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c
rename to gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c
index cd90f8f263d..05ac339ada7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/atomic-builtins-qemu-sockets.c
+++ b/gcc/testsuite/c-c++-common/analyzer/atomic-builtins-qemu-sockets.c
@@ -5,7 +5,7 @@  struct foo {
 void *
 test (const char *str)
 {
-  struct foo *p = __builtin_malloc(sizeof(struct foo));
+  struct foo *p = (struct foo *) __builtin_malloc(sizeof(struct foo));
   if (!p)
     return p;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c
similarity index 88%
rename from gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c
rename to gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c
index bd28107d0d7..1665d4128f5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-6.c
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-6.c
@@ -74,7 +74,7 @@  void warn_fdopen (void)
 
   {
     FILE *q = fdopen (0);     // { dg-message "allocated here" }
-    q = realloc (q, 7);       // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" }
+    q = (FILE *) realloc (q, 7);       // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" }
     sink (q);
   }
 }
@@ -117,7 +117,7 @@  void warn_fopen (void)
 
   {
     FILE *q = fdopen (0);
-    q = realloc (q, 7);       // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" }
+    q = (FILE *) realloc (q, 7);       // { dg-warning "'realloc' called on 'q' returned from a mismatched allocation function" }
     sink (q);
   }
 }
@@ -170,18 +170,18 @@  void test_tmpfile (void)
 void warn_malloc (void)
 {
   {
-    FILE *p = malloc (100);   // { dg-message "allocated here" }
+    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 = malloc (100);   // { dg-message "allocated here" }
+    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 = malloc (100);   // { dg-message "allocated here" }
+    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'" }
   }
 }
@@ -222,7 +222,7 @@  void test_acquire (void)
 
   {
     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'" }
+    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/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c
rename to gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c
index e086843c42b..24fb46bd5a9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-malloc-CVE-2019-19078-usb-leak.c
@@ -3,7 +3,10 @@ 
 
 typedef unsigned char u8;
 typedef unsigned short u16;
-typedef _Bool bool;
+
+#ifndef __cplusplus 
+  typedef _Bool bool;
+#endif
 
 #define	ENOMEM		12
 #define	EINVAL		22
@@ -149,7 +152,7 @@  static int ath10k_usb_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
 			goto err;
 		}
 
-		skb = items[i].transfer_context;
+		skb = (struct sk_buff *) items[i].transfer_context;
 		urb_context->skb = skb;
 
 		urb = usb_alloc_urb(0, GFP_ATOMIC); /* { dg-message "allocated here" } */
@@ -209,7 +212,7 @@  static const struct ath10k_hif_ops ath10k_usb_hif_ops = {
 
 /* Simulate code to register the callback.  */
 extern void callback_registration (const void *);
-int ath10k_usb_probe(void)
+void ath10k_usb_probe(void)
 {
   callback_registration(&ath10k_usb_hif_ops);
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c b/gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c
similarity index 96%
rename from gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c
rename to gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c
index e1d87c9cece..127e1535fdf 100644
--- a/gcc/testsuite/gcc.dg/analyzer/attr-tainted_args-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/attr-tainted_args-1.c
@@ -23,7 +23,7 @@  test_1 (int i, void *p, char *q)
   __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'tainted'" } */
   __analyzer_dump_state ("taint", *q); /* { dg-warning "state: 'tainted'" } */
 
-  struct arg_buf *args = p;
+  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'" } */  
 }
@@ -49,7 +49,7 @@  test_2a (int i, void *p, char *q)
   __analyzer_dump_state ("taint", p); /* { dg-warning "state: 'start'" } */
   __analyzer_dump_state ("taint", q); /* { dg-warning "state: 'start'" } */
 
-  struct arg_buf *args = p;
+  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'" } */  
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
similarity index 95%
rename from gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c
rename to gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
index 54f442f0ad4..d4cf079cef8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/call-summaries-pr107158.c
+++ b/gcc/testsuite/c-c++-common/analyzer/call-summaries-pr107158.c
@@ -25,7 +25,7 @@  __attribute__((__noreturn__)) void failed(const char *message);
 static char *string_dup(const char *string) {
   char *buf;
 
-  if ((buf = malloc(strlen(string) + 1)) == ((void *)0))
+  if ((buf = (char *) malloc(strlen(string) + 1)) == ((void *)0))
     failed("malloc() failed");
 
   return strcpy(buf, string);
@@ -37,7 +37,7 @@  static void store_data(const char *name, const char *type) {
   if ((p = (struct mydata *)malloc(sizeof(struct mydata))) == ((void *)0))
     failed("malloc() failed");
 
-  p->link = ((void *)0);
+  p->link = (struct mydata *)((void *)0);
   p->name = string_dup(name);
   p->type = string_dup(type);
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/calloc-1.c b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c
similarity index 76%
rename from gcc/testsuite/gcc.dg/analyzer/calloc-1.c
rename to gcc/testsuite/c-c++-common/analyzer/calloc-1.c
index bc28128671f..5395631e6eb 100644
--- a/gcc/testsuite/gcc.dg/analyzer/calloc-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/calloc-1.c
@@ -2,7 +2,15 @@ 
 
 typedef __SIZE_TYPE__ size_t;
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern void *calloc (size_t __nmemb, size_t __size)
   __attribute__ ((__nothrow__ , __leaf__))
@@ -13,7 +21,7 @@  char *test_1 (size_t sz)
 {
   char *p;
 
-  p = calloc (1, 3);
+  p = (char *) calloc (1, 3);
   if (!p)
     return NULL;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
similarity index 84%
rename from gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c
rename to gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
index ccf8fe392bf..ee745051617 100644
--- a/gcc/testsuite/gcc.dg/analyzer/compound-assignment-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/compound-assignment-5.c
@@ -23,7 +23,7 @@  void test_1 (void)
 
 /* Copying from an on-stack array to a global array.  */
 
-struct coord glob_arr[16];
+struct coord glob_arr2[16];
 
 void test_2 (void)
 {
@@ -31,32 +31,30 @@  void test_2 (void)
   arr[3].x = 5;
   arr[3].y = 6;
 
-  glob_arr[7] = arr[3];
+  glob_arr2[7] = arr[3];
 
-  __analyzer_eval (glob_arr[7].x == 5); /* { dg-warning "TRUE" } */
-  __analyzer_eval (glob_arr[7].y == 6); /* { dg-warning "TRUE" } */
+  __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_arr[16];
+struct coord glob_arr3[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?
+  glob_arr3[7] = arr[3]; // or should the uninit warning be here?
 
-  __analyzer_eval (glob_arr[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */
+  __analyzer_eval (glob_arr3[7].x); /* { dg-warning "uninitialized" "uninit" { xfail *-*-* } } */
   /* { dg-bogus "UNKNOWN" "unknown" { xfail *-*-* } .-1 } */
-  __analyzer_eval (glob_arr[7].y == 6); /* { dg-warning "TRUE" } */
+  __analyzer_eval (glob_arr3[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];
@@ -77,8 +75,6 @@  void test_4 (int i)
 
 /* 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];
@@ -95,8 +91,6 @@  void test_5a (int i, int j)
 
 /* Symbolic bindings: copying within an array: symbolic src, concrete dest.  */
 
-struct coord glob_arr[16];
-
 void test_5b (int i)
 {
   struct coord arr[16];
@@ -113,8 +107,6 @@  void test_5b (int i)
 
 /* Symbolic bindings: copying within an array: concrete src, symbolic dest.  */
 
-struct coord glob_arr[16];
-
 void test_5c (int i)
 {
   struct coord arr[16];
@@ -132,10 +124,12 @@  void test_5c (int i)
 /* 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_arr[3];
+  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/gcc.dg/analyzer/coreutils-cksum-pr108664.c b/gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/coreutils-cksum-pr108664.c
rename to gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c
index 62698f3d148..7ae4e6b06be 100644
--- a/gcc/testsuite/gcc.dg/analyzer/coreutils-cksum-pr108664.c
+++ b/gcc/testsuite/c-c++-common/analyzer/coreutils-cksum-pr108664.c
@@ -7,6 +7,11 @@  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,
@@ -30,7 +35,7 @@  __errno_location(void) __attribute__((__nothrow__, __leaf__))
 __attribute__((__const__));
 extern uint_fast32_t const crctab[8][256];
 
-static _Bool
+static bool
 cksum_slice8(FILE* fp, uint_fast32_t* crc_out, uintmax_t* length_out)
 {
   uint32_t buf[(1 << 16) / sizeof(uint32_t)];
diff --git a/gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c b/gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c
rename to gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c
index 9d13fce8531..5684d1b02d4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/coreutils-sum-pr108666.c
+++ b/gcc/testsuite/c-c++-common/analyzer/coreutils-sum-pr108666.c
@@ -35,7 +35,7 @@  bsd_sum_stream(FILE* stream, void* resstream, uintmax_t* length)
   int checksum = 0;
   uintmax_t total_bytes = 0;
   static const size_t buffer_length = 32768;
-  uint8_t* buffer = malloc(buffer_length);
+  uint8_t* buffer = (uint8_t *) malloc(buffer_length);
 
   if (!buffer)
     return -1;
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 00000000000..0e64e5bf3ba
--- /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/gcc.dg/analyzer/deref-before-check-pr108455-1.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c
index d7d873edc51..5f2ca966931 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-1.c
@@ -19,7 +19,7 @@  int test_1 (void) {
   }
 
   data = could_fail_2 (fd);
-  hdr = data;
+  hdr = (struct header *) data;
 
   if (hdr->signature != 42) {
     ret = -2;
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c
similarity index 98%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c
index 7553f86051d..7431bd11c42 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108455-git-pack-revindex.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108455-git-pack-revindex.c
@@ -95,7 +95,7 @@  int load_revindex_from_disk(char *revindex_name, uint32_t num_objects,
   }
 
   data = xmmap(((void *)0), revindex_size, 0x1, 0x02, fd, 0);
-  hdr = data;
+  hdr = (struct revindex_header *) data;
 
   if (git_bswap32(hdr->signature) != 0x52494458) {
     ret =
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c
similarity index 86%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c
index fa3beaaa15f..2075ac35db7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-1.c
@@ -1,6 +1,14 @@ 
 /* Reduced from haproxy-2.7.1: src/tcpcheck.c.  */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 int
 test_1 (char **args, int cur_arg)
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c
index 1180e17e555..68edd2bfa32 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr108475-haproxy-tcpcheck.c
@@ -3,7 +3,16 @@ 
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern void *calloc(size_t __nmemb, size_t __size)
     __attribute__((__nothrow__, __leaf__)) __attribute__((__malloc__))
@@ -86,7 +95,7 @@  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);                                     \
+	char *__x = (char *) ((void *)(str));                                     \
 	(struct ist){                                                  \
 		.ptr = __x,                                            \
 		.len = __builtin_constant_p(str) ?                     \
@@ -114,7 +123,7 @@  struct tcpcheck_rule *proxy_parse_httpchk_req(char **args, int cur_arg,
     goto error;
   }
 
-  chk = calloc(1, sizeof(*chk));
+  chk = (struct tcpcheck_rule *) calloc(1, sizeof(*chk));
   if (!chk) {
     /* [...snip...] */
     goto error;
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
index 4f50882eb8a..1d28e10747c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109060-haproxy-cfgparse.c
@@ -51,7 +51,7 @@  parse_process_number(const char* arg,
   else if (strcmp(arg, "even") == 0)
     *proc |= (~0UL / 3UL) << 1;
   else {
-    const char *p, *dash = ((void*)0);
+    const char *p, *dash = (const char *) ((void*)0);
     unsigned int low, high;
 
     for (p = arg; *p; p++) {
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c
similarity index 93%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c
index 49b6420cc6b..c3d28a573cc 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr109239-linux-bus.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr109239-linux-bus.c
@@ -1,7 +1,15 @@ 
 /* Reduced from linux-5.10.162's drivers-base-bus.c  */
 /* { dg-additional-options "-fno-delete-null-pointer-checks -O2" } */
 
-#define NULL ((void*)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 typedef unsigned int __kernel_size_t;
 typedef int __kernel_ssize_t;
@@ -57,7 +65,7 @@  struct kset*
 to_kset(struct kobject* kobj)
 {
   return kobj ? ({
-    void* __mptr = (void*)(kobj);
+    char* __mptr = (char*)(kobj);
     ((struct kset*)(__mptr - __builtin_offsetof(struct kset, kobj)));
   }) : NULL;
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c
similarity index 84%
rename from gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c
rename to gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c
index 1ceea97b422..12cd717f9c6 100644
--- a/gcc/testsuite/gcc.dg/analyzer/deref-before-check-pr77425.c
+++ b/gcc/testsuite/c-c++-common/analyzer/deref-before-check-pr77425.c
@@ -1,7 +1,16 @@ 
 /* Fixed in r7-2945-g61f46d0e6dd568.
    Simplified from gcc/ipa-devirt.c.  */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
 typedef struct odr_type_d {
   /* .... */
   int id;
diff --git a/gcc/testsuite/gcc.dg/analyzer/exec-1.c b/gcc/testsuite/c-c++-common/analyzer/exec-1.c
similarity index 56%
rename from gcc/testsuite/gcc.dg/analyzer/exec-1.c
rename to gcc/testsuite/c-c++-common/analyzer/exec-1.c
index 6b71118bd54..6748c290b30 100644
--- a/gcc/testsuite/gcc.dg/analyzer/exec-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/exec-1.c
@@ -1,4 +1,14 @@ 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+  #define CONST_CAST(type) const_cast<type>
+#else
+  #define NULL ((void *)0)
+  #define CONST_CAST(type) 
+#endif
 
 extern int execl(const char *pathname, const char *arg, ...);
 extern int execlp(const char *file, const char *arg, ...);
@@ -19,25 +29,25 @@  int test_execlpl_ls_al ()
 
 int test_execle_ls_al ()
 {
-  const char *env[3] = {"FOO=BAR", "BAZ", NULL};
+  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] = {"ls", "-al", NULL};
+  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] = {"ls", "-al", NULL};
+  char *argv[3] = {CONST_CAST(char *)("ls"), CONST_CAST(char *)("-al"), NULL};
   return execvp ("ls", argv);
 }
 
 int test_execvpe_ls_al ()
 {
-  char *env[3] = {"FOO=BAR", "BAZ", NULL};
-  char *argv[3] = {"ls", "-al", NULL};
+  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/gcc.dg/analyzer/feasibility-3.c b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
similarity index 92%
rename from gcc/testsuite/gcc.dg/analyzer/feasibility-3.c
rename to gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
index 0c0bd14fa54..2fcd064e801 100644
--- a/gcc/testsuite/gcc.dg/analyzer/feasibility-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/feasibility-3.c
@@ -4,7 +4,9 @@ 
 /* Types.  */
 
 typedef unsigned char u8;
+#ifndef __cplusplus
 typedef _Bool bool;
+#endif
 typedef unsigned int gfp_t;
 
 struct file;
@@ -67,7 +69,7 @@  static inline bool pde_is_permanent(const struct proc_dir_entry *pde)
 
 static inline struct proc_inode *PROC_I(const struct inode *inode)
 {
-  void *__mptr = (void *)(inode);
+  char *__mptr = (char *)(inode);
   return ((struct proc_inode *)(__mptr - __builtin_offsetof(struct proc_inode, vfs_inode)));
 }
 
@@ -89,8 +91,11 @@  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;
+
+
+ int (*open)(struct inode *, struct file *);
+ int (*release)(struct inode *, struct file *);
+
  struct pde_opener *pdeo;
 
  if (pde_is_permanent(pde)) {
@@ -104,7 +109,7 @@  static int proc_reg_open(struct inode *inode, struct file *file)
 
  release = pde->proc_ops->proc_release;
  if (release) {
-  pdeo = kmem_cache_alloc(pde_opener_cache,
+  pdeo = (struct pde_opener *) kmem_cache_alloc(pde_opener_cache,
 			  ((( gfp_t)(0x400u|0x800u))
 			   | (( gfp_t)0x40u)
 			   | (( gfp_t)0x80u)));
diff --git a/gcc/testsuite/gcc.dg/analyzer/fields.c b/gcc/testsuite/c-c++-common/analyzer/fields.c
similarity index 92%
rename from gcc/testsuite/gcc.dg/analyzer/fields.c
rename to gcc/testsuite/c-c++-common/analyzer/fields.c
index 0bf877fcf1e..18595307c9b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/fields.c
+++ b/gcc/testsuite/c-c++-common/analyzer/fields.c
@@ -30,7 +30,7 @@  recvauth_common (int problem)
     krb5_error error;
     const char *message = error_message(problem);
     error.text.length = strlen(message) + 1;
-    if (!(error.text.data = malloc(error.text.length))) {
+    if (!(error.text.data = (char *) malloc(error.text.length))) {
       goto cleanup;
     }
     free(error.text.data);
diff --git a/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c b/gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c
similarity index 85%
rename from gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c
rename to gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c
index 3c46f289082..6c9f5cae556 100644
--- a/gcc/testsuite/gcc.dg/analyzer/function-ptr-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/function-ptr-5.c
@@ -1,4 +1,12 @@ 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 void calling_null_fn_ptr_1 (void)
 {
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c
similarity index 95%
rename from gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c
rename to gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c
index d9221fa8dc5..8799f03bf41 100644
--- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-1.c
@@ -3,7 +3,16 @@ 
 
 /* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
 typedef __builtin_va_list va_list;
 
 typedef struct _GQueue GQueue;
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c
rename to gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c
index 58f6d2f4463..d483d7e643c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-2.c
@@ -62,7 +62,7 @@  void test_5 (struct st2 *p)
 
 void test_6 (struct st2 *p)
 {
-  struct st2 *q = __builtin_malloc (p->i);
+  struct st2 *q = (struct st2 *) __builtin_malloc (p->i);
   if (!q)
     return;
   q->i = p->i;
@@ -72,7 +72,7 @@  void test_6 (struct st2 *p)
 
 void test_7 (struct st2 *p)
 {
-  struct st2 *q = __builtin_malloc (p->i);
+  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);
diff --git a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c
rename to gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c
index b40326fc252..dd677a26f75 100644
--- a/gcc/testsuite/gcc.dg/analyzer/infinite-recursion-pr108524-qobject-json-parser.c
+++ b/gcc/testsuite/c-c++-common/analyzer/infinite-recursion-pr108524-qobject-json-parser.c
@@ -3,7 +3,16 @@ 
 
 /* { dg-additional-options "-fno-analyzer-call-summaries -Wno-analyzer-too-complex" } */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
 typedef __builtin_va_list va_list;
 typedef __SIZE_TYPE__ size_t;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/init.c b/gcc/testsuite/c-c++-common/analyzer/init.c
similarity index 98%
rename from gcc/testsuite/gcc.dg/analyzer/init.c
rename to gcc/testsuite/c-c++-common/analyzer/init.c
index e51d88e9ff9..8b478bbbf51 100644
--- a/gcc/testsuite/gcc.dg/analyzer/init.c
+++ b/gcc/testsuite/c-c++-common/analyzer/init.c
@@ -95,7 +95,7 @@  void test_9 (void)
 
 void test_10 (void)
 {
-  struct coord c[2] = {{.y = 4, .x = 3}, {5, 6}};
+  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" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c
similarity index 54%
rename from gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c
rename to gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c
index 15a2dd8f0e1..b6dfc199adc 100644
--- a/gcc/testsuite/gcc.dg/analyzer/inlining-3-multiline.c
+++ b/gcc/testsuite/c-c++-common/analyzer/inlining-3-multiline.c
@@ -5,7 +5,15 @@ 
 /* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 struct input_file_st 
 {
@@ -61,4 +69,39 @@  test (const input_file *inpf)
     |          (4) ...to here
     |          (5) argument 1 ('<unknown>') NULL where non-null expected
     |
-   { dg-end-multiline-output "" } */
+   { 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 ('<unknown>') 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 00000000000..3db1a9852fb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/inlining-3.c
@@ -0,0 +1,41 @@ 
+/* 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;
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
+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/gcc.dg/analyzer/inlining-4-multiline.c b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c
similarity index 52%
rename from gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c
rename to gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c
index 0413c39af03..8bf74d608ec 100644
--- a/gcc/testsuite/gcc.dg/analyzer/inlining-4-multiline.c
+++ b/gcc/testsuite/c-c++-common/analyzer/inlining-4-multiline.c
@@ -4,7 +4,15 @@ 
 /* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */
 /* { dg-additional-options "-fdiagnostics-path-format=inline-events -fdiagnostics-show-caret" } */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 static inline const char*
 inner (int flag)
@@ -69,4 +77,48 @@  outer (int flag)
     |          |
     |          (6) dereference of NULL '<unknown>'
     |
-   { dg-end-multiline-output "" } */
+   { 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 '<unknown>'
+    |
+   { 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 00000000000..5ec47130196
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/inlining-4.c
@@ -0,0 +1,38 @@ 
+/* Verify that we can reconstruct fndecl and stack depth information
+   after early inlining.  */
+
+/* { dg-additional-options "-O2 -fdiagnostics-show-path-depths" } */
+
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
+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/gcc.dg/analyzer/leak-pr105906.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c
similarity index 70%
rename from gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c
rename to gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c
index 72901e4d1eb..25a85e7ed61 100644
--- a/gcc/testsuite/gcc.dg/analyzer/leak-pr105906.c
+++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr105906.c
@@ -1,6 +1,14 @@ 
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 #define LEN 64
 
@@ -13,7 +21,7 @@  epystr_explode(const char *delim, char *str)
 	if (str == NULL || delim == NULL)
 		return NULL;
 
-	out = __builtin_malloc(LEN * sizeof(char *));
+	out = (char **) __builtin_malloc(LEN * sizeof(char *));
 	if (out == NULL)
 		return NULL;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c
similarity index 83%
rename from gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c
rename to gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c
index d63be06a9bb..39a2b345d83 100644
--- a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-with-call-summaries.c
+++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-with-call-summaries.c
@@ -1,7 +1,15 @@ 
 /* { dg-additional-options "-fanalyzer-call-summaries" } */
 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 /* data structures */
 
@@ -31,7 +39,7 @@  struct screen_s *screen_create(size_t cols, size_t rows)
 {
 	struct screen_s *result = NULL;
 
-	result = __builtin_calloc(1, sizeof(*result));
+	result = (struct screen_s *) __builtin_calloc(1, sizeof(*result));
 	if (!result)
 		return NULL;
 
@@ -39,7 +47,7 @@  struct screen_s *screen_create(size_t cols, size_t rows)
 	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);
+	result->data = (char **) __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
 	if (!result->data) {
 		__builtin_free(result);
 		return NULL;
@@ -91,7 +99,7 @@  void resize_screen(size_t cols, size_t rows)
 
 int main(void)
 {
-	ctx = __builtin_calloc(1, sizeof(*ctx));
+	ctx = (struct context_s *) __builtin_calloc(1, sizeof(*ctx));
 	if (!ctx)
 		__builtin_abort();
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c
similarity index 84%
rename from gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c
rename to gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c
index ae7a7d5c159..79fdf5e4ff6 100644
--- a/gcc/testsuite/gcc.dg/analyzer/leak-pr108045-without-call-summaries.c
+++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr108045-without-call-summaries.c
@@ -2,7 +2,15 @@ 
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 /* data structures */
 
@@ -32,7 +40,7 @@  struct screen_s *screen_create(size_t cols, size_t rows)
 {
 	struct screen_s *result = NULL;
 
-	result = __builtin_calloc(1, sizeof(*result));
+	result = (struct screen_s *) __builtin_calloc(1, sizeof(*result));
 	if (!result)
 		return NULL;
 
@@ -40,7 +48,7 @@  struct screen_s *screen_create(size_t cols, size_t rows)
 	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);
+	result->data = (char **) __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
 	if (!result->data) {
 		__builtin_free(result);
 		return NULL;
@@ -92,7 +100,7 @@  void resize_screen(size_t cols, size_t rows)
 
 int main(void)
 {
-	ctx = __builtin_calloc(1, sizeof(*ctx));
+	ctx = (struct context_s *) __builtin_calloc(1, sizeof(*ctx));
 	if (!ctx)
 		__builtin_abort();
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c
similarity index 93%
rename from gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c
rename to gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c
index 033ab79460e..ae196d75b93 100644
--- a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-1.c
@@ -27,7 +27,7 @@  cfg_register_postparser(char* name, int (*func)())
 {
   struct cfg_postparser* cp;
 
-  cp = calloc(1, sizeof(*cp));
+  cp = (struct cfg_postparser *) calloc(1, sizeof(*cp));
   if (!cp) {
     /* [...snip...] */
     return 0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c
similarity index 92%
rename from gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c
rename to gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c
index 125bce84864..26329ffac46 100644
--- a/gcc/testsuite/gcc.dg/analyzer/leak-pr109059-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/leak-pr109059-2.c
@@ -26,7 +26,7 @@  test_1 (char* name)
 {
   struct cfg_postparser* cp;
 
-  cp = calloc(1, sizeof(*cp));
+  cp = (struct cfg_postparser*) calloc(1, sizeof(*cp));
   if (!cp) {
     /* [...snip...] */
     return 0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/malloc-2.c b/gcc/testsuite/c-c++-common/analyzer/malloc-2.c
similarity index 89%
rename from gcc/testsuite/gcc.dg/analyzer/malloc-2.c
rename to gcc/testsuite/c-c++-common/analyzer/malloc-2.c
index bb93c53d3e0..ed68209da72 100644
--- a/gcc/testsuite/gcc.dg/analyzer/malloc-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/malloc-2.c
@@ -16,7 +16,7 @@  void test_1 (void)
 
 int *test_2 (void)
 {
-  int *i = malloc (sizeof (int)); /* { dg-message "\\(1\\) this call could return NULL" } */
+  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/gcc.dg/analyzer/memcpy-2.c b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
similarity index 79%
rename from gcc/testsuite/gcc.dg/analyzer/memcpy-2.c
rename to gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
index 51e4a694951..25b0a5e4ff4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/memcpy-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/memcpy-2.c
@@ -1,8 +1,9 @@ 
 /* { dg-additional-options "-Wno-stringop-overflow -Wno-analyzer-out-of-bounds" } */
 
-void
-main (int c, void *v)
+int
+test (int c, void *v)
 {
   static char a[] = "";
   __builtin_memcpy (v, a, -1);
+  return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/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
similarity index 93%
rename from gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
rename to gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early-O2.c
index cb46827ab65..c46ffe91a6b 100644
--- a/gcc/testsuite/gcc.dg/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
@@ -61,12 +61,12 @@  static inline enum obj_type obj_type(const enum obj_type *t)
 }
 static inline struct connection *__objt_conn(enum obj_type *t)
 {
- return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+ 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 ((void *)0);
+   return (struct connection *)((void *)0);
  return __objt_conn(t);
 }
 struct session {
@@ -80,7 +80,7 @@  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)
+smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *Private)
 {
  SSL *ssl;
  struct connection *conn;
diff --git a/gcc/testsuite/gcc.dg/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
similarity index 93%
rename from gcc/testsuite/gcc.dg/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
rename to gcc/testsuite/c-c++-common/analyzer/null-deref-pr108251-smp_fetch_ssl_fc_has_early.c
index fbacb6ca2d3..ef34a76c50d 100644
--- a/gcc/testsuite/gcc.dg/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
@@ -60,12 +60,12 @@  static inline enum obj_type obj_type(const enum obj_type *t)
 }
 static inline struct connection *__objt_conn(enum obj_type *t)
 {
- return ((struct connection *)(((void *)(t)) - ((long)&((struct connection *)0)->obj_type)));
+ 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 ((void *)0);
+   return (struct connection *) ((void *)0);
  return __objt_conn(t);
 }
 struct session {
@@ -79,7 +79,7 @@  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)
+smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const char *kw, void *Private)
 {
  SSL *ssl;
  struct connection *conn;
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c
rename to gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
index 3ab72c053af..f8f87024d8b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108806-qemu.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108806-qemu.c
@@ -1,6 +1,14 @@ 
 /* Reduced from qemu-7.2.0's hw/intc/omap_intc.c */
 
-#define NULL ((void*)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 typedef unsigned char __uint8_t;
 typedef unsigned int __uint32_t;
diff --git a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
similarity index 89%
rename from gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c
rename to gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
index 417ab00794d..f66d567e5c5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/null-deref-pr108830.c
+++ b/gcc/testsuite/c-c++-common/analyzer/null-deref-pr108830.c
@@ -2,7 +2,15 @@ 
 
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
-#define NULL ((void*)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 typedef __SIZE_TYPE__ size_t;
 
@@ -43,7 +51,7 @@  struct apr_hash_t
 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)),
+  return (apr_hash_entry_t **) memset(apr_palloc(ht->pool, sizeof(*ht->array) * (max + 1)),
                 0,
                 sizeof(*ht->array) * (max + 1));
 }
@@ -57,7 +65,7 @@  apr_hash_merge(apr_pool_t* p,
   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 = (apr_hash_t *) apr_palloc(p, sizeof(apr_hash_t));
   res->pool = p;
   res->free = NULL;
   res->hash_func = base->hash_func;
@@ -69,7 +77,7 @@  apr_hash_merge(apr_pool_t* p,
   res->seed = base->seed;
   res->array = alloc_array(res, res->max);
   if (base->count + overlay->count) {
-    new_vals =
+    new_vals = (apr_hash_entry_t *)
       apr_palloc(p, sizeof(apr_hash_entry_t) * (base->count + overlay->count));
   }
   j = 0;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr101962.c b/gcc/testsuite/c-c++-common/analyzer/pr101962.c
similarity index 89%
rename from gcc/testsuite/gcc.dg/analyzer/pr101962.c
rename to gcc/testsuite/c-c++-common/analyzer/pr101962.c
index 5eb7cf0b995..53919f84666 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr101962.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr101962.c
@@ -1,6 +1,14 @@ 
 #include "analyzer-decls.h"
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 /* Verify that the analyzer makes the simplifying assumption that we don't
    hit NULL when incrementing pointers to non-NULL memory regions.  */
@@ -35,7 +43,7 @@  maybe_inc_char_ptr (const char *ptr)
   return ++ptr;
 }
 
-char
+void
 test_s (void)
 {
   const char *msg = "hello world";
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103217-2.c b/gcc/testsuite/c-c++-common/analyzer/pr103217-2.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/pr103217-2.c
rename to gcc/testsuite/c-c++-common/analyzer/pr103217-2.c
index aa8bca7ce5f..69ba6454e57 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr103217-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr103217-2.c
@@ -30,7 +30,7 @@  struct test {
 };
 
 int main(int argc, char *argv[]) {
-	struct test *options = calloc(1, sizeof(*options));
+	struct test *options = (struct test *) calloc(1, sizeof(*options));
 	int rc;
 	if (!options)
 		abort();
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr103217.c b/gcc/testsuite/c-c++-common/analyzer/pr103217.c
similarity index 86%
rename from gcc/testsuite/gcc.dg/analyzer/pr103217.c
rename to gcc/testsuite/c-c++-common/analyzer/pr103217.c
index 08889acb2c9..6474fa893b7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr103217.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr103217.c
@@ -13,8 +13,15 @@  extern char *optarg;
 extern void free (void *__ptr)
   __attribute__ ((__nothrow__ , __leaf__));
 
-#define NULL ((void *)0)
-
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 char *xstrdup(const char *src) {
 	char *val = strdup(src);
 	if (!val)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104029.c b/gcc/testsuite/c-c++-common/analyzer/pr104029.c
similarity index 97%
rename from gcc/testsuite/gcc.dg/analyzer/pr104029.c
rename to gcc/testsuite/c-c++-common/analyzer/pr104029.c
index adf15ed356f..873f0eb16b7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104029.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr104029.c
@@ -23,7 +23,7 @@  int heapsort(void *vbase, size_t nmemb, size_t size, t_compfunc compar) {
     return (-1);
   }
 
-  k = my_malloc1(__FILE__, __LINE__, size);
+  k = (char *) my_malloc1(__FILE__, __LINE__, size);
 
   abase = (char *)vbase - size;
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr104062.c b/gcc/testsuite/c-c++-common/analyzer/pr104062.c
similarity index 70%
rename from gcc/testsuite/gcc.dg/analyzer/pr104062.c
rename to gcc/testsuite/c-c++-common/analyzer/pr104062.c
index 7129c27f60b..9b44893dd4b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104062.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr104062.c
@@ -7,7 +7,7 @@  realloc (void *, __SIZE_TYPE__);
 void
 foo (void)
 {
-  int *ap5 = calloc (4, sizeof *ap5);
-  int *ap7 = realloc (ap5, sizeof *ap5);
+  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/gcc.dg/analyzer/pr104369-1.c b/gcc/testsuite/c-c++-common/analyzer/pr104369-1.c
similarity index 77%
rename from gcc/testsuite/gcc.dg/analyzer/pr104369-1.c
rename to gcc/testsuite/c-c++-common/analyzer/pr104369-1.c
index c05137bb219..ca9b24cda69 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104369-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr104369-1.c
@@ -1,8 +1,18 @@ 
 /* { dg-additional-options "-Wno-analyzer-too-complex -Wno-analyzer-fd-leak" } */
 // TODO: remove need for these options
 
+/* { dg-skip-if "C++ doesn't not support extension 'transparent_union'" { c++ } } */
+
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 #define POLLIN 0x001
 
 typedef struct {
@@ -61,7 +71,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 +84,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/c-c++-common/analyzer/pr104369-2.c
similarity index 77%
rename from gcc/testsuite/gcc.dg/analyzer/pr104369-2.c
rename to gcc/testsuite/c-c++-common/analyzer/pr104369-2.c
index 93d9987d0ba..a8e66b6ba9b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr104369-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr104369-2.c
@@ -1,8 +1,17 @@ 
 /* { dg-additional-options "-Wno-analyzer-fd-leak" } */
+/* { dg-skip-if "c++ does not support transparent_union" { c++ } } */
 // TODO: remove need for this option
 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 #define POLLIN 0x001
 
 typedef struct {
@@ -61,7 +70,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 +81,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/c-c++-common/analyzer/pr105783.c
similarity index 85%
rename from gcc/testsuite/gcc.dg/analyzer/pr105783.c
rename to gcc/testsuite/c-c++-common/analyzer/pr105783.c
index 00f44d04b64..f17519415ce 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr105783.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr105783.c
@@ -1,11 +1,15 @@ 
 /* { 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;
+    bool counting;
 };
 
 struct ss_s ss_init(void) {
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr107345.c b/gcc/testsuite/c-c++-common/analyzer/pr107345.c
similarity index 73%
rename from gcc/testsuite/gcc.dg/analyzer/pr107345.c
rename to gcc/testsuite/c-c++-common/analyzer/pr107345.c
index 540596d1182..ea1925bfa19 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr107345.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr107345.c
@@ -9,7 +9,8 @@  int main() {
   int g = 0;
   int *h[2][1];
   h[1][0] = f;
-  if (g == (h[1][0])) { /* { dg-warning "comparison between pointer and integer" } */
+  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);
diff --git a/gcc/testsuite/c-c++-common/analyzer/pr61861.c b/gcc/testsuite/c-c++-common/analyzer/pr61861.c
new file mode 100644
index 00000000000..bb9e039ebd5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/pr61861.c
@@ -0,0 +1,3 @@ 
+/* { dg-additional-options "-Wno-int-conversion" } */
+/* { dg-skip-if "-Wno-int-conversion for C++" { c++ } } */
+#include "../../gcc.dg/pr61861.c"
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 00000000000..71b3962980d
--- /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/gcc.dg/analyzer/pr93695-1.c b/gcc/testsuite/c-c++-common/analyzer/pr93695-1.c
similarity index 83%
rename from gcc/testsuite/gcc.dg/analyzer/pr93695-1.c
rename to gcc/testsuite/c-c++-common/analyzer/pr93695-1.c
index e0500c49be7..529c60131ca 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr93695-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr93695-1.c
@@ -11,7 +11,7 @@  test_1 (void)
   int i;
 
   for (i = 0; i < ARRAY_SIZE (p); ++i)
-    p[i] = __builtin_malloc (sizeof (i));
+    p[i] = (int *) __builtin_malloc (sizeof (i));
 
   for (i = 0; i < ARRAY_SIZE (p); ++i)
     __builtin_free (p [i]);
@@ -28,7 +28,7 @@  test_2 (int n)
     return;
 
   for (i = 0; i < n; ++i)
-    p[i] = __builtin_malloc (sizeof (i));
+    p[i] = (int *) __builtin_malloc (sizeof (i));
 
   for (i = 0; i < n; ++i)
     __builtin_free (p [i]);
@@ -41,7 +41,7 @@  test_3 (int **p, int n)
 {
   int i;
   for (i = 0; i < n; ++i)
-    p[i] = __builtin_malloc (sizeof (i));
+    p[i] = (int *) __builtin_malloc (sizeof (i));
 }
 
 void
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94596.c b/gcc/testsuite/c-c++-common/analyzer/pr94596.c
similarity index 93%
rename from gcc/testsuite/gcc.dg/analyzer/pr94596.c
rename to gcc/testsuite/c-c++-common/analyzer/pr94596.c
index 055d2098064..0e7360e2ea4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94596.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr94596.c
@@ -16,9 +16,19 @@ 
  * limitations under the License.
  */
 
+/* { dg-skip-if "" { c++ } } */
+
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
-#define false 0
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+  #define false 0
+#endif
 
 #define OBJECT_OFFSETOF(OBJECT, MEMBER)\
     __builtin_offsetof(typeof(*(OBJECT)), MEMBER)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr94839.c b/gcc/testsuite/c-c++-common/analyzer/pr94839.c
similarity index 82%
rename from gcc/testsuite/gcc.dg/analyzer/pr94839.c
rename to gcc/testsuite/c-c++-common/analyzer/pr94839.c
index 46c8bb98bd2..26e7e616cf6 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr94839.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr94839.c
@@ -13,7 +13,7 @@  int bitmap_create(struct bitmap *bm, int min, int max)
 
   bm->min = min;
   bm->max = max;
-  bm->vec = __builtin_calloc(sz, sizeof(int));
+  bm->vec = (int *) __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/c-c++-common/analyzer/pr95152-4.c
similarity index 55%
rename from gcc/testsuite/gcc.dg/analyzer/pr95152-4.c
rename to gcc/testsuite/c-c++-common/analyzer/pr95152-4.c
index f2a72cad01c..5ebbae85aee 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr95152-4.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr95152-4.c
@@ -1,4 +1,6 @@ 
+/* { dg-skip-if "'-Wno-pointer-to-int-cast' invalid for C++" { c++ } } */
 /* { dg-additional-options "-Wno-pointer-to-int-cast" } */
+
 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/c-c++-common/analyzer/pr95152-5.c
similarity index 61%
rename from gcc/testsuite/gcc.dg/analyzer/pr95152-5.c
rename to gcc/testsuite/c-c++-common/analyzer/pr95152-5.c
index 604b78458c7..fbc4753e0b4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr95152-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr95152-5.c
@@ -1,3 +1,4 @@ 
+/* { dg-skip-if "'-Wno-incompatible-pointer-types' invalid for C++" { c++ } } */
 /* { dg-additional-options "-Wno-incompatible-pointer-types" } */
 void foo(void)
 {
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr95240.c b/gcc/testsuite/c-c++-common/analyzer/pr95240.c
similarity index 89%
rename from gcc/testsuite/gcc.dg/analyzer/pr95240.c
rename to gcc/testsuite/c-c++-common/analyzer/pr95240.c
index c84c64de8b8..afd831b3d26 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr95240.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr95240.c
@@ -8,7 +8,7 @@  static char *activeTroubleArray;
 int
 initActiveTroubleArray ()
 {
-  activeTroubleArray = calloc (1, 1);
+  activeTroubleArray = (char *) calloc (1, 1);
   return activeTroubleArray ? 0 : 1;
 }
 
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96639.c b/gcc/testsuite/c-c++-common/analyzer/pr96639.c
similarity index 80%
rename from gcc/testsuite/gcc.dg/analyzer/pr96639.c
rename to gcc/testsuite/c-c++-common/analyzer/pr96639.c
index aedf0464dc9..b95217df6c4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96639.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr96639.c
@@ -3,7 +3,7 @@  void *calloc (__SIZE_TYPE__, __SIZE_TYPE__);
 int
 x7 (void)
 {
-  int **md = calloc (1, sizeof (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/gcc.dg/analyzer/pr96653.c b/gcc/testsuite/c-c++-common/analyzer/pr96653.c
similarity index 98%
rename from gcc/testsuite/gcc.dg/analyzer/pr96653.c
rename to gcc/testsuite/c-c++-common/analyzer/pr96653.c
index e5e387c44a5..75f3d23aa98 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96653.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr96653.c
@@ -753,7 +753,7 @@  const char *v4l2_ctrl_get_name(u32 id) {
   case ((0x00a30000 | 0x900) + 4):
     return "MD Region Grid";
   default:
-    return ((void *)0);
+    return (const char *) ((void *)0);
   }
 }
 
@@ -989,40 +989,40 @@  void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
     *type = V4L2_CTRL_TYPE_U32;
     break;
   case ((0x00990000 | 0x900) + 250):
-    *type = 0x0103;
+    *type = (enum v4l2_ctrl_type) 0x0103;
     break;
   case ((0x00990000 | 0x900) + 251):
-    *type = 0x0104;
+    *type = (enum v4l2_ctrl_type) 0x0104;
     break;
   case ((0x00990000 | 0x900) + 292):
-    *type = 0x0105;
+    *type = (enum v4l2_ctrl_type) 0x0105;
     break;
   case ((0x00990000 | 0x900) + 1000):
-    *type = 0x0110;
+    *type = (enum v4l2_ctrl_type) 0x0110;
     break;
   case ((0x00990000 | 0x900) + 1001):
-    *type = 0x0111;
+    *type = (enum v4l2_ctrl_type) 0x0111;
     break;
   case ((0x00990000 | 0x900) + 1002):
-    *type = 0x0112;
+    *type = (enum v4l2_ctrl_type) 0x0112;
     break;
   case ((0x00990000 | 0x900) + 1003):
-    *type = 0x0113;
+    *type = (enum v4l2_ctrl_type) 0x0113;
     break;
   case ((0x00990000 | 0x900) + 1004):
-    *type = 0x0114;
+    *type = (enum v4l2_ctrl_type) 0x0114;
     break;
   case ((0x00990000 | 0x900) + 2000):
-    *type = 0x301;
+    *type = (enum v4l2_ctrl_type) 0x301;
     break;
   case ((0x00990000 | 0x900) + 1008):
-    *type = 0x0120;
+    *type = (enum v4l2_ctrl_type) 0x0120;
     break;
   case ((0x00990000 | 0x900) + 1009):
-    *type = 0x0121;
+    *type = (enum v4l2_ctrl_type) 0x0121;
     break;
   case ((0x00990000 | 0x900) + 1010):
-    *type = 0x0122;
+    *type = (enum v4l2_ctrl_type) 0x0122;
     break;
   case ((0x009e0000 | 0x900) + 8):
     *type = V4L2_CTRL_TYPE_AREA;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96792.c b/gcc/testsuite/c-c++-common/analyzer/pr96792.c
similarity index 82%
rename from gcc/testsuite/gcc.dg/analyzer/pr96792.c
rename to gcc/testsuite/c-c++-common/analyzer/pr96792.c
index 7757645a133..911d89b6ef2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96792.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr96792.c
@@ -1,4 +1,12 @@ 
-#define NULL (void *)0
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 struct block
 {
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr96841.c b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
similarity index 77%
rename from gcc/testsuite/gcc.dg/analyzer/pr96841.c
rename to gcc/testsuite/c-c++-common/analyzer/pr96841.c
index 14f3f7a86a3..dd61176b73b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr96841.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr96841.c
@@ -12,7 +12,7 @@  th (int *);
 void
 bv (__SIZE_TYPE__ ny, int ***mf)
 {
-  while (l8 ())
+  while (l8 ()) /* { dg-warning "terminating analysis for this program point" } */
     {
       *mf = 0;
       (*mf)[ny] = (int *) malloc (sizeof (int));
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 00000000000..cb7c97df18b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/pr97568.c
@@ -0,0 +1,40 @@ 
+#include "analyzer-decls.h"
+
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
+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/gcc.dg/analyzer/pr98564.c b/gcc/testsuite/c-c++-common/analyzer/pr98564.c
similarity index 59%
rename from gcc/testsuite/gcc.dg/analyzer/pr98564.c
rename to gcc/testsuite/c-c++-common/analyzer/pr98564.c
index 74b1abec6bf..a404e358cd2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr98564.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr98564.c
@@ -2,5 +2,5 @@  void *calloc (__SIZE_TYPE__, __SIZE_TYPE__);
 
 void test_1 (void)
 {
-  int *p = calloc (0, 1); /* { dg-message "allocated here" } */
+  int *p = (int *) 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/c-c++-common/analyzer/pr98628.c
similarity index 100%
rename from gcc/testsuite/gcc.dg/analyzer/pr98628.c
rename to gcc/testsuite/c-c++-common/analyzer/pr98628.c
index fa0ca961c46..f339c495fd4 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr98628.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr98628.c
@@ -1,12 +1,12 @@ 
 /* { 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[];
 };
+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);
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr98969.c b/gcc/testsuite/c-c++-common/analyzer/pr98969.c
similarity index 61%
rename from gcc/testsuite/gcc.dg/analyzer/pr98969.c
rename to gcc/testsuite/c-c++-common/analyzer/pr98969.c
index e4e4f059197..4fe76012f00 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr98969.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr98969.c
@@ -7,14 +7,15 @@  void
 test_1 (__UINTPTR_TYPE__ i)
 {
   struct foo *f = (struct foo *)i;
-  f->expr = __builtin_malloc (1024);
+  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'" } */
+  __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
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-2.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/pr99193-2.c
rename to gcc/testsuite/c-c++-common/analyzer/pr99193-2.c
index 40e61817503..791b857dcc5 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr99193-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-2.c
@@ -56,7 +56,7 @@  make_display_name (struct drv *drvs)
     ret = single_drive_display_name (drvs);
     len = __builtin_strlen (ret);
 
-    ret = realloc (ret, len + pluses + 1); /* { dg-bogus "'free'" } */
+    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)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c b/gcc/testsuite/c-c++-common/analyzer/pr99193-3.c
similarity index 85%
rename from gcc/testsuite/gcc.dg/analyzer/pr99193-3.c
rename to gcc/testsuite/c-c++-common/analyzer/pr99193-3.c
index d64b0458e9e..9828abf0332 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr99193-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr99193-3.c
@@ -8,8 +8,15 @@ 
 typedef __SIZE_TYPE__ size_t;
 typedef __builtin_va_list va_list;
 
-#define NULL ((void *)0)
-
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 extern void free (void *);
 extern void *realloc (void *__ptr, size_t __size)
   __attribute__ ((__nothrow__ , __leaf__))
@@ -35,7 +42,7 @@  debug_help (const char **cmds, size_t argc, char *const *const argv)
   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'" } */
+    p = (char *) realloc (r, len + 1); /* { dg-bogus "'free'" } */
     if (p == NULL) {
       free (r);
       return NULL;
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c b/gcc/testsuite/c-c++-common/analyzer/pr99716-1.c
similarity index 83%
rename from gcc/testsuite/gcc.dg/analyzer/pr99716-1.c
rename to gcc/testsuite/c-c++-common/analyzer/pr99716-1.c
index 2ccdcc73a5c..56d77f45b69 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr99716-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr99716-1.c
@@ -4,7 +4,15 @@  FILE* fopen (const char*, const char*);
 int   fclose (FILE*);
 int fprintf (FILE *, const char *, ...);
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 void
 test_1 (void)
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c b/gcc/testsuite/c-c++-common/analyzer/pr99774-1.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/pr99774-1.c
rename to gcc/testsuite/c-c++-common/analyzer/pr99774-1.c
index a0bca8b1fe2..184baeef935 100644
--- a/gcc/testsuite/gcc.dg/analyzer/pr99774-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/pr99774-1.c
@@ -42,7 +42,7 @@  int vu_check_queue_inflights(VuVirtq *vq) {
   int i = 0;
 
   if (vq->inuse) {
-    vq->resubmit_list = calloc(vq->inuse, sizeof(VuVirtqInflightDesc));
+    vq->resubmit_list = (VuVirtqInflightDesc *) calloc(vq->inuse, sizeof(VuVirtqInflightDesc));
     if (!vq->resubmit_list) {
       return -1;
     }
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c
similarity index 84%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-1.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-1.c
index 9951e118efe..75e0b10e964 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-1.c
@@ -20,14 +20,14 @@  void *test_1 (void *ptr)
   return realloc (ptr, 1024);
 }
 
-void *test_2 (void *ptr)
+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 test_3 (void *ptr)
 {
   void *p = malloc (1024);
   void *q = realloc (p, 4096);
@@ -45,7 +45,7 @@  void *test_4 (void)
 int *test_5 (int *p)
 {
   *p = 42;
-  int *q = realloc (p, sizeof(int) * 4); /* { dg-message "when 'realloc' fails" } */
+  int *q = (int *) realloc (p, sizeof(int) * 4); /* { dg-message "when 'realloc' fails" } */
   *q = 43; /* { dg-warning "dereference of NULL 'q'" } */
   return q;
 }
@@ -60,7 +60,7 @@  void test_6 (size_t sz)
 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" } */
+  void *p = realloc (&buf, sz); /* { dg-warning "'realloc' of '& ?buf' which points to memory on the stack" } */
   return p;  
 }
 
@@ -91,5 +91,6 @@  void test_9 (void *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'" } */
+  __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/gcc.dg/analyzer/realloc-2.c b/gcc/testsuite/c-c++-common/analyzer/realloc-2.c
similarity index 92%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-2.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-2.c
index ab3e4b6628a..c9e50873dce 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-2.c
@@ -4,7 +4,15 @@ 
 
 typedef __SIZE_TYPE__ size_t;
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern void *malloc (size_t __size)
   __attribute__ ((__nothrow__ , __leaf__))
@@ -21,7 +29,7 @@  char *test_8 (size_t sz)
 {
   char *p, *q;
 
-  p = malloc (3);
+  p = (char *) malloc (3);
   if (!p)
     return NULL;
 
@@ -35,7 +43,7 @@  char *test_8 (size_t sz)
   __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */
   __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */
 
-  q = realloc (p, 6);
+  q = (char *) realloc (p, 6);
 
   /* We should have 3 nodes, corresponding to "failure",
      "success without moving", and "success with moving".  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-3.c b/gcc/testsuite/c-c++-common/analyzer/realloc-3.c
similarity index 92%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-3.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-3.c
index eec61497d5b..d3355ec30e9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-3.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-3.c
@@ -4,7 +4,15 @@ 
 
 typedef __SIZE_TYPE__ size_t;
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern void *calloc (size_t __nmemb, size_t __size)
   __attribute__ ((__nothrow__ , __leaf__))
@@ -27,7 +35,7 @@  char *test_8 (size_t sz)
 {
   char *p, *q;
 
-  p = calloc (1, 3);
+  p = (char *) calloc (1, 3);
   if (!p)
     return NULL;
 
@@ -37,7 +45,7 @@  char *test_8 (size_t sz)
   __analyzer_eval (p[1] == 0); /* { dg-warning "TRUE" } */
   __analyzer_eval (p[2] == 0); /* { dg-warning "TRUE" } */
 
-  q = realloc (p, 6);
+  q = (char *) realloc (p, 6);
 
   /* We should have 3 nodes, corresponding to "failure",
      "success without moving", and "success with moving".  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-4.c b/gcc/testsuite/c-c++-common/analyzer/realloc-4.c
similarity index 99%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-4.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-4.c
index ac338ec0497..8bb1893b9b9 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-4.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-4.c
@@ -34,7 +34,7 @@  char *test_8 (char *p, size_t sz)
   __analyzer_eval (p[1] == 'b'); /* { dg-warning "TRUE" } */
   __analyzer_eval (p[2] == 'c'); /* { dg-warning "TRUE" } */
 
-  q = realloc (p, 6);
+  q = (char *) realloc (p, 6);
 
   /* We should have 3 nodes, corresponding to "failure",
      "success without moving", and "success with moving".  */
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c b/gcc/testsuite/c-c++-common/analyzer/realloc-5.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-5.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-5.c
index f65f2c6ca25..9e413be45e7 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-5.c
@@ -22,12 +22,12 @@  extern void *memset (void *__ptr, int __value, size_t __size);
 
 void test_1 ()
 {
-  char *p = malloc (16);
+  char *p = (char *) malloc (16);
   if (!p)
     return;
   memset (p, 1, 16);
 
-  char *q = realloc (p, 8);
+  char *q = (char *) realloc (p, 8);
   if (!q)
     {
       free (p);
diff --git a/gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c b/gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c
similarity index 70%
rename from gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c
rename to gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c
index d76b8781413..e25722a3328 100644
--- a/gcc/testsuite/gcc.dg/analyzer/realloc-pr110014.c
+++ b/gcc/testsuite/c-c++-common/analyzer/realloc-pr110014.c
@@ -8,18 +8,18 @@  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);
+    buffer = (long *) realloc (buffer, cc);
   return buffer;
 }
 
 long *
 slurp1 (long *buffer, unsigned long file_size)
 {
-  return realloc (buffer, file_size - file_size % sizeof (long));
+  return (long *) 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));
+  return (long *) realloc (buffer, (file_size / sizeof (long)) * sizeof (long));
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c b/gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c
similarity index 74%
rename from gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c
rename to gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c
index a557dee6e44..9b785e09ec2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/snprintf-concat.c
+++ b/gcc/testsuite/c-c++-common/analyzer/snprintf-concat.c
@@ -1,5 +1,13 @@ 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern size_t
 strlen(const char* __s) __attribute__((__nothrow__, __leaf__))
@@ -17,7 +25,7 @@  char *
 test_1 (const char *a, const char *b)
 {
   size_t sz = strlen (a) + strlen (b) + 2;
-  char *p = malloc (sz);
+  char *p = (char *) malloc (sz);
   if (!p)
     return NULL;
   snprintf (p, sz, "%s/%s", a, b);
@@ -28,7 +36,7 @@  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 *-*-* } } */
+  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/gcc.dg/analyzer/sock-1.c b/gcc/testsuite/c-c++-common/analyzer/sock-1.c
similarity index 91%
rename from gcc/testsuite/gcc.dg/analyzer/sock-1.c
rename to gcc/testsuite/c-c++-common/analyzer/sock-1.c
index 0f3e822492f..e5e2f23bba0 100644
--- a/gcc/testsuite/gcc.dg/analyzer/sock-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/sock-1.c
@@ -5,7 +5,9 @@  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;
@@ -76,12 +78,12 @@  struct sock {
 
 static ktime_t sock_read_timestamp(struct sock *sk)
 {
-  return *(const volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp);
+  return *(const volatile ktime_t *)&(sk->sk_stamp);
 }
 
 static void sock_write_timestamp(struct sock *sk, ktime_t kt)
 {
-  *(volatile typeof(sk->sk_stamp) *)&(sk->sk_stamp) = kt;
+  *(volatile ktime_t *)&(sk->sk_stamp) = kt;
 }
 
 /* [...snip...] */
@@ -108,5 +110,5 @@  int sock_gettstamp(struct socket *sock, void *userstamp,
 
  if (time32)
   return put_old_timespec32(&ts, userstamp);
- return put_timespec64(&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 00000000000..ab4d63cae0e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-2.c
@@ -0,0 +1,58 @@ 
+/* 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__));
+
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
+
+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'" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c b/gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c
similarity index 74%
rename from gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c
rename to gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c
index 0094f3e6449..3623244faa2 100644
--- a/gcc/testsuite/gcc.dg/analyzer/sprintf-concat.c
+++ b/gcc/testsuite/c-c++-common/analyzer/sprintf-concat.c
@@ -1,6 +1,13 @@ 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
-
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 extern size_t
 strlen(const char* __s) __attribute__((__nothrow__, __leaf__))
 __attribute__((__pure__)) __attribute__((__nonnull__(1)));
@@ -17,7 +24,7 @@  char *
 test_1 (const char *a, const char *b)
 {
   size_t sz = strlen (a) + strlen (b) + 2;
-  char *p = malloc (sz);
+  char *p = (char *) malloc (sz);
   if (!p)
     return NULL;
   sprintf (p, "%s/%s", a, b);
@@ -28,7 +35,7 @@  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" } */
+  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/gcc.dg/analyzer/string-ops-concat-pair.c b/gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c
similarity index 80%
rename from gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c
rename to gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c
index f5bcd67594f..1ee3d44ae4b 100644
--- a/gcc/testsuite/gcc.dg/analyzer/string-ops-concat-pair.c
+++ b/gcc/testsuite/c-c++-common/analyzer/string-ops-concat-pair.c
@@ -1,5 +1,13 @@ 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 /* Concatenating a pair of strings.  */
 
@@ -9,7 +17,7 @@  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);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, __builtin_strlen (x));
@@ -25,7 +33,7 @@  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);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, __builtin_strlen (x));
@@ -42,7 +50,7 @@  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);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, len_x);
@@ -57,7 +65,8 @@  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" } */
+  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);
diff --git a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c b/gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c
similarity index 79%
rename from gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c
rename to gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c
index 44c4e9dc67e..6969d220d39 100644
--- a/gcc/testsuite/gcc.dg/analyzer/string-ops-dup.c
+++ b/gcc/testsuite/c-c++-common/analyzer/string-ops-dup.c
@@ -1,6 +1,13 @@ 
 typedef __SIZE_TYPE__ size_t;
-#define NULL ((void *)0)
-
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 /* Duplicating a string.  */
 
 /* Correct but poor implementation with repeated __builtin_strlen calls.  */
@@ -9,7 +16,7 @@  char *
 alloc_dup_1_correct (const char *x)
 {
   size_t sz = __builtin_strlen (x) + 1;
-  char *result = __builtin_malloc (sz);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, __builtin_strlen (x));
@@ -24,7 +31,7 @@  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);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, __builtin_strlen (x));
@@ -39,7 +46,7 @@  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);
+  char *result = (char *) __builtin_malloc (sz);
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, len_x);
@@ -52,7 +59,7 @@  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" } */
+  char *result = (char *) __builtin_malloc (sz); /* { dg-message "capacity: 'len_x' bytes" } */
   if (!result)
     return NULL;
   __builtin_memcpy (result, x, len_x);
diff --git a/gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c b/gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c
rename to gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c
index 336222759e3..bb1ef085691 100644
--- a/gcc/testsuite/gcc.dg/analyzer/switch-enum-pr105273-git-vreportf-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/switch-enum-pr105273-git-vreportf-2.c
@@ -34,7 +34,7 @@  static void __analyzer_vreportf(enum usage_kind kind)
 
 int main(void)
 {
-	__analyzer_vreportf(42);
+	__analyzer_vreportf((enum usage_kind) 42);
 
 	return 0;
 }
diff --git a/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c b/gcc/testsuite/c-c++-common/analyzer/symbolic-12.c
similarity index 90%
rename from gcc/testsuite/gcc.dg/analyzer/symbolic-12.c
rename to gcc/testsuite/c-c++-common/analyzer/symbolic-12.c
index d7c50de9f27..a5b90e0fe4c 100644
--- a/gcc/testsuite/gcc.dg/analyzer/symbolic-12.c
+++ b/gcc/testsuite/c-c++-common/analyzer/symbolic-12.c
@@ -10,7 +10,7 @@  struct st_1
 
 void test_1a (void *p, unsigned next_off)
 {
-  struct st_1 *r = p;
+  struct st_1 *r = (struct st_1 *) p;
 
   external_fn();
 
@@ -24,7 +24,7 @@  void test_1a (void *p, unsigned next_off)
 
 void test_1b (void *p, unsigned next_off)
 {
-  struct st_1 *r = p;
+  struct st_1 *r = (struct st_1 *) p;
 
   if (next_off >= r->size)
     return;
@@ -58,7 +58,7 @@  void test_1d (struct st_1 *r, unsigned next_off)
 
 void test_1e (void *p, unsigned next_off)
 {
-  struct st_1 *r = p;
+  struct st_1 *r = (struct st_1 *) p;
 
   while (1)
     {
@@ -79,7 +79,7 @@  struct st_2
 
 void test_2a (void *p, unsigned next_off)
 {
-  struct st_2 *r = p;
+  struct st_2 *r = (struct st_2 *) p;
 
   external_fn();
 
@@ -93,7 +93,7 @@  void test_2a (void *p, unsigned next_off)
 
 void test_2b (void *p, unsigned next_off, int idx)
 {
-  struct st_2 *r = p;
+  struct st_2 *r = (struct st_2 *) p;
 
   external_fn();
 
diff --git a/gcc/testsuite/c-c++-common/analyzer/test-alloca.h b/gcc/testsuite/c-c++-common/analyzer/test-alloca.h
new file mode 100644
index 00000000000..f4045f92adc
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/test-alloca.h
@@ -0,0 +1,3 @@ 
+#pragma GCC system_header
+
+#define alloca(X) __builtin_alloca(X)
diff --git a/gcc/testsuite/c-c++-common/analyzer/test-assert.h b/gcc/testsuite/c-c++-common/analyzer/test-assert.h
new file mode 100644
index 00000000000..4a24b720ac8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/test-assert.h
@@ -0,0 +1,7 @@ 
+#pragma GCC system_header
+
+extern void __assert_fail (const char *expr, const char *file, int line)
+  __attribute__ ((__noreturn__));
+
+#define assert(EXPR) \
+  do { if (!(EXPR)) __assert_fail (#EXPR, __FILE__, __LINE__); } while (0)
diff --git a/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h b/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h
new file mode 100644
index 00000000000..52c57d02b70
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/test-setjmp.h
@@ -0,0 +1,27 @@ 
+/* Various integration tests for setjmp-handling expect a precise
+   multiline output.
+   
+   The outputs from -fdiagnostics-path-format=inline-events for such
+   setjmp tests are dependent on whether setjmp is a macro or a function
+   (and whether that macro is defined in a system header).
+
+   setjmp is a function on some systems and a macro on others.
+   This header provides a SETJMP macro in a (fake) system header,
+   along with precanned decls of setjmp, for consistency of output across
+   different systems.  */
+
+#pragma GCC system_header
+
+struct __jmp_buf_tag {
+  char buf[1];
+};
+typedef struct __jmp_buf_tag jmp_buf[1];
+typedef struct __jmp_buf_tag sigjmp_buf[1];
+
+extern int setjmp(jmp_buf env);
+extern int sigsetjmp(sigjmp_buf env, int savesigs);
+
+extern void longjmp(jmp_buf env, int val);
+extern void siglongjmp(sigjmp_buf env, int val);
+
+#define SETJMP(E) setjmp(E)
diff --git a/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h b/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
new file mode 100644
index 00000000000..70c9d6309ef
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/test-uaccess.h
@@ -0,0 +1,15 @@ 
+/* Shared header for testcases for copy_from_user/copy_to_user.  */
+
+/* Adapted from include/linux/compiler.h  */
+
+#define __user
+
+/* Adapted from include/asm-generic/uaccess.h  */
+
+extern int copy_from_user(void *to, const void __user *from, long n)
+  __attribute__((access (write_only, 1, 3),
+		 access (read_only, 2, 3)));
+
+extern long copy_to_user(void __user *to, const void *from, unsigned long n)
+  __attribute__((access (write_only, 1, 3),
+		 access (read_only, 2, 3)));
diff --git a/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c b/gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c
similarity index 57%
rename from gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
rename to gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c
index 5dd3f8522d2..d8c842171a8 100644
--- a/gcc/testsuite/gcc.dg/analyzer/uninit-alloca.c
+++ b/gcc/testsuite/c-c++-common/analyzer/uninit-alloca.c
@@ -2,6 +2,6 @@ 
 
 int test_1 (void)
 {
-  int *p = __builtin_alloca (sizeof (int)); /* { dg-message "region created on stack here" } */
+  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/gcc.dg/analyzer/untracked-2.c b/gcc/testsuite/c-c++-common/analyzer/untracked-2.c
similarity index 76%
rename from gcc/testsuite/gcc.dg/analyzer/untracked-2.c
rename to gcc/testsuite/c-c++-common/analyzer/untracked-2.c
index 565a9ccd58e..8c6d9d6f023 100644
--- a/gcc/testsuite/gcc.dg/analyzer/untracked-2.c
+++ b/gcc/testsuite/c-c++-common/analyzer/untracked-2.c
@@ -2,6 +2,6 @@  typedef unsigned char u8;
 extern int foo(const u8 *key, unsigned int keylen);
 int test (void)
 {
-  static const u8 default_salt[64];
+  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/c-c++-common/analyzer/vasprintf-1.c
similarity index 90%
rename from gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c
rename to gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c
index 061cd008c13..50667dd4ca1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/vasprintf-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/vasprintf-1.c
@@ -1,6 +1,14 @@ 
 /* { dg-additional-options "-Wno-analyzer-too-complex" } */
 
-#define NULL ((void *)0)
+#ifdef __cplusplus
+  #if __cplusplus >= 201103L
+  #define NULL nullptr
+  #else
+  #define NULL 0
+  #endif
+#else
+  #define NULL ((void *)0)
+#endif
 
 extern int printf (const char *__restrict __format, ...);
 extern int vasprintf (char **__restrict __ptr, const char *__restrict __f,
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c
similarity index 91%
rename from gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c
rename to gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c
index dc724e29185..c74442af267 100644
--- a/gcc/testsuite/gcc.dg/analyzer/write-to-const-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-const-1.c
@@ -9,7 +9,7 @@  int test_1 (void)
 
 /* Example of writing to a subregion (an element within a const array).  */
 
-const int c2[10]; /* { dg-message "declared here" } */
+const int c2[10] = {}; /* { dg-message "declared here" } */
 int test_2 (void)
 {
   ((int*) &c2)[5] = 10; /* { dg-warning "write to 'const' object 'c2'" } */
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-function-1.c
similarity index 81%
rename from gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c
rename to gcc/testsuite/c-c++-common/analyzer/write-to-function-1.c
index c1bece632ce..dd4adc13141 100644
--- a/gcc/testsuite/gcc.dg/analyzer/write-to-function-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-function-1.c
@@ -1,3 +1,5 @@ 
+/* { dg-skip-if "c++ does not allow for conversion from function pointer to 'void *'" { c++ } } */
+
 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/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 00000000000..87f9943b155
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1.c
@@ -0,0 +1,15 @@ 
+#include <string.h>
+
+#ifdef __cplusplus
+#define CONST_CAST(type) const_cast<type>
+#else
+#define CONST_CAST(type) 
+#endif
+
+/* 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" } */
+}
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
similarity index 86%
rename from gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
rename to gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
index 092500e066f..7d06febba77 100644
--- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-1.c
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-1bis.c
@@ -1,20 +1,21 @@ 
 #include <string.h>
 
+#ifdef __cplusplus
+#define CONST_CAST(type) const_cast<type>
+#else
+#define CONST_CAST(type)
+#endif
+
 /* PR analyzer/95007.  */
 
 void test_1 (void)
 {
-  char *s = "foo";
+  char *s = CONST_CAST(char *)("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)
 {
diff --git a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c
similarity index 94%
rename from gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c
rename to gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c
index fa21af13341..868c39368e1 100644
--- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-4-disabled.c
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-4-disabled.c
@@ -16,7 +16,7 @@  void test (int flag)
   char *buf;
 
   if (flag)
-    buf = __builtin_malloc (1024);
+    buf = (char *) __builtin_malloc (1024);
   else
     buf = (char *)""; /* { dg-bogus "here" } */
 
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 00000000000..971e8f38574
--- /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/gcc.dg/analyzer/write-to-string-literal-5.c b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c
similarity index 62%
rename from gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c
rename to gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c
index 42efc49fb22..0072d451229 100644
--- a/gcc/testsuite/gcc.dg/analyzer/write-to-string-literal-5.c
+++ b/gcc/testsuite/c-c++-common/analyzer/write-to-string-literal-5.c
@@ -8,7 +8,9 @@ 
 
 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\\)'" } */
+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)));
 
@@ -18,9 +20,9 @@  void *test (int flag)
 {
   char *ptr;
   if (flag)
-    ptr = __builtin_malloc (1024);
+    ptr = (char *) __builtin_malloc (1024);
   else
-    ptr = __builtin_alloca (1024);
+    ptr = (char *) __builtin_alloca (1024);
 
   __analyzer_dump_exploded_nodes (0); /* { dg-warning "2 processed enodes" } */
 
diff --git a/gcc/testsuite/g++.dg/analyzer/analyzer.exp b/gcc/testsuite/g++.dg/analyzer/analyzer.exp
index 9551d827c65..848bea616df 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/allocation-size-multiline-1.c b/gcc/testsuite/gcc.dg/analyzer/allocation-size-multiline-1.c
deleted file mode 100644
index 7251665105d..00000000000
--- 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 <stdint.h>
-
-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 7cadbb74751..00000000000
--- 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 <stdint.h>
-
-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 b3de582368f..00000000000
--- 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 <stdint.h>
-#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.exp b/gcc/testsuite/gcc.dg/analyzer/analyzer.exp
index af05c98fa16..cedf3c0466f 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/data-model-11.c b/gcc/testsuite/gcc.dg/analyzer/data-model-11.c
deleted file mode 100644
index 27663247c32..00000000000
--- 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/inlining-3.c b/gcc/testsuite/gcc.dg/analyzer/inlining-3.c
deleted file mode 100644
index 7a292ac87fa..00000000000
--- 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.c b/gcc/testsuite/gcc.dg/analyzer/inlining-4.c
deleted file mode 100644
index f4e42084c91..00000000000
--- 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/pr61861.c b/gcc/testsuite/gcc.dg/analyzer/pr61861.c
deleted file mode 100644
index a85e7438905..00000000000
--- a/gcc/testsuite/gcc.dg/analyzer/pr61861.c
+++ /dev/null
@@ -1,2 +0,0 @@ 
-/* { dg-additional-options "-Wno-int-conversion" } */
-#include "../pr61861.c"
diff --git a/gcc/testsuite/gcc.dg/analyzer/pr93457.c b/gcc/testsuite/gcc.dg/analyzer/pr93457.c
deleted file mode 100644
index b77911ba789..00000000000
--- 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/pr97568.c b/gcc/testsuite/gcc.dg/analyzer/pr97568.c
deleted file mode 100644
index 22d574b5fbd..00000000000
--- 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/sprintf-1.c b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
index f8dc806d619..e94c0561665 100644
--- a/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
+++ b/gcc/testsuite/gcc.dg/analyzer/sprintf-1.c
@@ -1,53 +1,14 @@ 
 /* See e.g. https://en.cppreference.com/w/c/io/fprintf
    and https://www.man7.org/linux/man-pages/man3/sprintf.3.html */
 
+/* { dg-skip-if "C++ fpermissive already throws an error" { c++ } } */
+
 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)
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 a8f600f81a3..00000000000
--- 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);
-}