From 87cb2950392e95065dbc9f9e56b4d10952fa7cad Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Thu, 3 Jan 2019 19:33:01 -0500
Subject: [PATCH 3/4] FIXME: start adding test coverage for checkers from old
 sm code

---
 .../sm/assignments/dereference-on-lhs/input.c      |  27 +++
 .../sm/assignments/dereference-on-lhs/script.py    |  37 ++++
 .../sm/assignments/dereference-on-lhs/stderr.txt   |   4 +
 .../sm/assignments/dereference-on-lhs/stdout.txt   |   0
 .../sm/assignments/dereference-on-rhs/input.c      |  28 +++
 .../sm/assignments/dereference-on-rhs/script.py    |  23 +++
 .../sm/assignments/dereference-on-rhs/stderr.txt   |   4 +
 .../sm/assignments/dereference-on-rhs/stdout.txt   |   0
 .../gcc.dg/checker/sm/assignments/phi/input.c      |  38 +++++
 .../gcc.dg/checker/sm/assignments/phi/script.py    |  34 ++++
 .../gcc.dg/checker/sm/assignments/phi/stderr.txt   |   7 +
 .../gcc.dg/checker/sm/assignments/phi/stdout.txt   |   0
 .../malloc-checker/arg_must_not_be_null/input.c    |  30 ++++
 .../malloc-checker/arg_must_not_be_null/script.py  |  23 +++
 .../malloc-checker/arg_must_not_be_null/stderr.txt |   4 +
 .../malloc-checker/arg_must_not_be_null/stdout.txt |   0
 .../checkers/malloc-checker/correct_usage/input.c  |  31 ++++
 .../correct_usage/input.c.cpychecker-log.txt       |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../malloc-checker/correct_usage/script.py         |  23 +++
 .../malloc-checker/correct_usage/stdout.txt        |   0
 .../sm/checkers/malloc-checker/double_free/input.c |  29 ++++
 .../double_free/input.c.cpychecker-log.txt         |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../checkers/malloc-checker/double_free/script.py  |  23 +++
 .../checkers/malloc-checker/double_free/stderr.txt |   7 +
 .../checkers/malloc-checker/double_free/stdout.txt |   0
 .../malloc-checker/fancy_control_flow/input.c      |  42 +++++
 .../fancy_control_flow/input.c.cpychecker-log.txt  |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../malloc-checker/fancy_control_flow/script.py    |  23 +++
 .../malloc-checker/fancy_control_flow/stderr.txt   |   4 +
 .../malloc-checker/fancy_control_flow/stdout.txt   |   0
 .../input.c.cpychecker-log.txt                     |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../leaks/not-a-leak/input.c.cpychecker-log.txt    |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../leaks/simple-leak/input.c.cpychecker-log.txt   |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../unchecked-return/input.c.cpychecker-log.txt    |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../multiple-errors/deref-of-null/input.c          |  41 +++++
 .../multiple-errors/deref-of-null/script.py        |  46 +++++
 .../multiple-errors/deref-of-null/stderr.txt       |   4 +
 .../multiple-errors/deref-of-null/stdout.txt       |   0
 .../multiple-errors/unchecked_malloc/input.c       |  41 +++++
 .../multiple-errors/unchecked_malloc/script.py     |  46 +++++
 .../multiple-errors/unchecked_malloc/stderr.txt    |   4 +
 .../multiple-errors/unchecked_malloc/stdout.txt    |   0
 .../sm/checkers/malloc-checker/two_ptrs/input.c    |  35 ++++
 .../two_ptrs/input.c.cpychecker-log.txt            |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../sm/checkers/malloc-checker/two_ptrs/script.py  |  23 +++
 .../sm/checkers/malloc-checker/two_ptrs/stderr.txt |   4 +
 .../sm/checkers/malloc-checker/two_ptrs/stdout.txt |   0
 .../malloc-checker/unchecked_malloc/input.c        |  28 +++
 .../unchecked_malloc/input.c.cpychecker-log.txt    |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../malloc-checker/unchecked_malloc/script.py      |  23 +++
 .../malloc-checker/unchecked_malloc/stderr.txt     |   4 +
 .../malloc-checker/unchecked_malloc/stdout.txt     |   0
 .../checkers/malloc-checker/use_after_free/input.c |  34 ++++
 .../use_after_free/input.c.cpychecker-log.txt      |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../malloc-checker/use_after_free/script.py        |  23 +++
 .../malloc-checker/use_after_free/stderr.txt       |   4 +
 .../malloc-checker/use_after_free/stdout.txt       |   0
 .../sm/checkers/points_to_stack/putenv/input.c     |  31 ++++
 .../sm/checkers/points_to_stack/putenv/script.py   |  31 ++++
 .../sm/checkers/points_to_stack/putenv/stderr.txt  |  22 +++
 .../sm/checkers/points_to_stack/putenv/stdout.txt  |   0
 .../points_to_stack/return_of_ptr_to_local/input.c |  69 ++++++++
 .../return_of_ptr_to_local/script.py               |  30 ++++
 .../return_of_ptr_to_local/stderr.txt              |   5 +
 .../return_of_ptr_to_local/stdout.txt              |   0
 .../sm/checkers/signal_handler/example/input.c     |  52 ++++++
 .../sm/checkers/signal_handler/example/script.py   |  30 ++++
 .../sm/checkers/signal_handler/example/stderr.txt  |   5 +
 .../sm/checkers/signal_handler/example/stdout.txt  |   0
 .../sizeof_allocation/calloc_too_small/input.c     |  34 ++++
 .../sizeof_allocation/calloc_too_small/script.py   |  23 +++
 .../sizeof_allocation/calloc_too_small/stderr.txt  |   2 +
 .../sizeof_allocation/calloc_too_small/stdout.txt  |   0
 .../sizeof_allocation/malloc_correct_size/input.c  |  31 ++++
 .../malloc_correct_size/script.py                  |  23 +++
 .../malloc_correct_size/stdout.txt                 |   0
 .../sizeof_allocation/malloc_too_large/input.c     |  36 ++++
 .../sizeof_allocation/malloc_too_large/script.py   |  23 +++
 .../sizeof_allocation/malloc_too_large/stdout.txt  |   0
 .../sizeof_allocation/malloc_too_small/input.c     |  34 ++++
 .../sizeof_allocation/malloc_too_small/script.py   |  23 +++
 .../sizeof_allocation/malloc_too_small/stderr.txt  |   2 +
 .../sizeof_allocation/malloc_too_small/stdout.txt  |   0
 .../stateful_malloc_too_small/input.c              |  36 ++++
 .../stateful_malloc_too_small/script.py            |  40 +++++
 .../stateful_malloc_too_small/stderr.txt           |   4 +
 .../stateful_malloc_too_small/stdout.txt           |   0
 .../sizeof_allocation/unknown_size/input.c         |  32 ++++
 .../sizeof_allocation/unknown_size/script.py       |  38 +++++
 .../sizeof_allocation/unknown_size/stdout.txt      |   0
 .../checker/sm/checkers/taint/example/input.c      | 131 ++++++++++++++
 .../checker/sm/checkers/taint/example/script.py    |  71 ++++++++
 .../checker/sm/checkers/taint/example/stderr.txt   |  22 +++
 .../checker/sm/checkers/taint/example/stdout.txt   |   0
 gcc/testsuite/gcc.dg/checker/sm/dot/input.c        |   1 +
 .../checker/sm/dot/input.c.cpychecker-log.txt      |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 gcc/testsuite/gcc.dg/checker/sm/dot/script.py      |  55 ++++++
 gcc/testsuite/gcc.dg/checker/sm/dot/stdout.txt     |  83 +++++++++
 .../checker/sm/facts/infinite-recursion/input.c    |  40 +++++
 .../checker/sm/facts/infinite-recursion/script.py  |  32 ++++
 .../checker/sm/facts/infinite-recursion/stdout.txt |   0
 gcc/testsuite/gcc.dg/checker/sm/facts/loop/input.c |  36 ++++
 .../gcc.dg/checker/sm/facts/loop/script.py         |  42 +++++
 .../gcc.dg/checker/sm/facts/loop/stdout.txt        |   0
 gcc/testsuite/gcc.dg/checker/sm/facts/meet/input.c |  41 +++++
 .../gcc.dg/checker/sm/facts/meet/script.py         |  46 +++++
 .../gcc.dg/checker/sm/facts/meet/stdout.txt        |   0
 .../gcc.dg/checker/sm/facts/noreturn/abort/input.c |  38 +++++
 .../checker/sm/facts/noreturn/abort/script.py      |  33 ++++
 .../checker/sm/facts/noreturn/abort/stdout.txt     |   0
 .../checker/sm/facts/noreturn/assert/input.c       |  37 ++++
 .../checker/sm/facts/noreturn/assert/script.py     |  33 ++++
 .../checker/sm/facts/noreturn/assert/stdout.txt    |   0
 .../checker/sm/facts/noreturn/custom_abort/input.c |  42 +++++
 .../sm/facts/noreturn/custom_abort/script.py       |  33 ++++
 .../sm/facts/noreturn/custom_abort/stdout.txt      |   0
 .../custom_abort_with_noreturn_attribute/input.c   |  44 +++++
 .../custom_abort_with_noreturn_attribute/script.py |  33 ++++
 .../stdout.txt                                     |   0
 .../gcc.dg/checker/sm/facts/operations/input.c     |  69 ++++++++
 .../gcc.dg/checker/sm/facts/operations/script.py   |  51 ++++++
 .../gcc.dg/checker/sm/facts/operations/stdout.txt  |   0
 .../gcc.dg/checker/sm/facts/params/input.c         |  53 ++++++
 .../gcc.dg/checker/sm/facts/params/script.py       |  54 ++++++
 .../gcc.dg/checker/sm/facts/params/stdout.txt      |   0
 .../checker/sm/facts/switch/various-cases/input.c  |  57 +++++++
 .../sm/facts/switch/various-cases/script.py        |  62 +++++++
 .../sm/facts/switch/various-cases/stdout.txt       |   0
 .../gcc.dg/checker/sm/facts/unittests/input.c      |   1 +
 .../gcc.dg/checker/sm/facts/unittests/metadata.ini |   4 +
 .../gcc.dg/checker/sm/facts/unittests/script.py    | 118 +++++++++++++
 .../gcc.dg/checker/sm/facts/unittests/stderr.txt   |  12 ++
 .../gcc.dg/checker/sm/facts/unittests/stdout.txt   |   0
 .../arg-affected-by-usage-as-param/input.c         |  34 ++++
 .../arg-affected-by-usage-as-param/script.py       |  36 ++++
 .../arg-affected-by-usage-as-param/stderr.txt      |  11 ++
 .../arg-affected-by-usage-as-param/stdout.txt      |   0
 .../callsite-lhs-inherits-from-return-val/input.c  |  35 ++++
 .../script.py                                      |  37 ++++
 .../stderr.txt                                     |   6 +
 .../stdout.txt                                     |   0
 .../checker/sm/interprocedural/complex/input.c     |  56 ++++++
 .../checker/sm/interprocedural/complex/script.py   |  23 +++
 .../checker/sm/interprocedural/complex/stderr.txt  |  13 ++
 .../checker/sm/interprocedural/complex/stdout.txt  |   0
 .../sm/interprocedural/input.c.cpychecker-log.txt  |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../param-inherits-from-arg/input.c                |  34 ++++
 .../param-inherits-from-arg/script.py              |  33 ++++
 .../param-inherits-from-arg/stderr.txt             |   5 +
 .../param-inherits-from-arg/stdout.txt             |   0
 gcc/testsuite/gcc.dg/checker/sm/json/input.c       |  27 +++
 gcc/testsuite/gcc.dg/checker/sm/json/script.py     | 104 ++++++++++++
 gcc/testsuite/gcc.dg/checker/sm/json/stdout.txt    |   2 +
 gcc/testsuite/gcc.dg/checker/sm/looping/input.c    |  36 ++++
 gcc/testsuite/gcc.dg/checker/sm/looping/script.py  |  23 +++
 gcc/testsuite/gcc.dg/checker/sm/looping/stderr.txt |  13 ++
 gcc/testsuite/gcc.dg/checker/sm/looping/stdout.txt |   0
 gcc/testsuite/gcc.dg/checker/sm/lto/input-f.c      |  34 ++++
 gcc/testsuite/gcc.dg/checker/sm/lto/input-g.c      |  31 ++++
 gcc/testsuite/gcc.dg/checker/sm/lto/input-h.c      |  31 ++++
 gcc/testsuite/gcc.dg/checker/sm/lto/script.py      |  25 +++
 gcc/testsuite/gcc.dg/checker/sm/lto/stderr.txt     |  29 ++++
 gcc/testsuite/gcc.dg/checker/sm/lto/stdout.txt     |   0
 gcc/testsuite/gcc.dg/checker/sm/lto/test.h         |  22 +++
 .../checker/sm/parser/malloc-checker/input.c       |  91 ++++++++++
 .../malloc-checker/input.c.cpychecker-log.txt      |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../checker/sm/parser/malloc-checker/metadata.ini  |   4 +
 .../checker/sm/parser/malloc-checker/script.py     | 189 +++++++++++++++++++++
 .../checker/sm/parser/malloc-checker/stderr.txt    |   6 +
 .../checker/sm/parser/malloc-checker/stdout.txt    |   0
 .../checker/sm/patterns/arg-of-fn-call/input.c     |  25 +++
 .../arg-of-fn-call/input.c.cpychecker-log.txt      |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../checker/sm/patterns/arg-of-fn-call/script.py   |  32 ++++
 .../checker/sm/patterns/arg-of-fn-call/stderr.txt  |   2 +
 .../checker/sm/patterns/arg-of-fn-call/stdout.txt  |   0
 .../sm/patterns/arg_must_not_be_null/input.c       |  44 +++++
 .../sm/patterns/arg_must_not_be_null/script.py     |  39 +++++
 .../sm/patterns/arg_must_not_be_null/stderr.txt    |  21 +++
 .../sm/patterns/arg_must_not_be_null/stdout.txt    |   0
 .../checker/sm/patterns/args-of-fn-call/input.c    |  25 +++
 .../checker/sm/patterns/args-of-fn-call/script.py  |  34 ++++
 .../checker/sm/patterns/args-of-fn-call/stderr.txt |   2 +
 .../checker/sm/patterns/args-of-fn-call/stdout.txt |   0
 .../gcc.dg/checker/sm/patterns/array/input.c       |  25 +++
 .../gcc.dg/checker/sm/patterns/array/script.py     |  33 ++++
 .../gcc.dg/checker/sm/patterns/array/stderr.txt    |   2 +
 .../gcc.dg/checker/sm/patterns/array/stdout.txt    |   0
 .../gcc.dg/checker/sm/patterns/conditional/input.c |  30 ++++
 .../conditional/input.c.cpychecker-log.txt         |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../checker/sm/patterns/conditional/script.py      |  35 ++++
 .../checker/sm/patterns/conditional/stderr.txt     |   2 +
 .../checker/sm/patterns/conditional/stdout.txt     |   0
 .../checker/sm/patterns/named-pattern/input.c      |  30 ++++
 .../checker/sm/patterns/named-pattern/script.py    |  34 ++++
 .../checker/sm/patterns/named-pattern/stderr.txt   |   2 +
 .../checker/sm/patterns/named-pattern/stdout.txt   |   0
 .../gcc.dg/checker/sm/patterns/or/input.c          |  39 +++++
 .../gcc.dg/checker/sm/patterns/or/script.py        |  32 ++++
 .../gcc.dg/checker/sm/patterns/or/stderr.txt       |   4 +
 .../gcc.dg/checker/sm/patterns/or/stdout.txt       |   0
 .../checker/sm/patterns/result-of-fn-call/input.c  |  30 ++++
 .../result-of-fn-call/input.c.cpychecker-log.txt   |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../sm/patterns/result-of-fn-call/script.py        |  32 ++++
 .../sm/patterns/result-of-fn-call/stderr.txt       |   2 +
 .../sm/patterns/result-of-fn-call/stdout.txt       |   0
 .../checker/sm/patterns/var-dereference/input.c    |  32 ++++
 .../var-dereference/input.c.cpychecker-log.txt     |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../checker/sm/patterns/var-dereference/script.py  |  32 ++++
 .../checker/sm/patterns/var-dereference/stderr.txt |   4 +
 .../checker/sm/patterns/var-dereference/stdout.txt |   0
 .../gcc.dg/checker/sm/patterns/var-usage/input.c   |  23 +++
 .../patterns/var-usage/input.c.cpychecker-log.txt  |   1 +
 ...ough_uninitialized_pointer-refcount-errors.html | 175 +++++++++++++++++++
 .../gcc.dg/checker/sm/patterns/var-usage/script.py |  34 ++++
 .../checker/sm/patterns/var-usage/stderr.txt       |   3 +
 .../checker/sm/patterns/var-usage/stdout.txt       |   0
 .../configure-with-exceptions/getopts.py           |   1 +
 .../regression/configure-with-exceptions/input.c   |  14 ++
 .../regression/configure-with-exceptions/script.py |  23 +++
 .../configure-with-exceptions/stdout.txt           |   0
 .../configure-without-exceptions/getopts.py        |   1 +
 .../configure-without-exceptions/input.c           |  14 ++
 .../configure-without-exceptions/script.py         |  23 +++
 .../configure-without-exceptions/stdout.txt        |   0
 .../optimization/dead-code-elimination/getopts.py  |  17 ++
 .../optimization/dead-code-elimination/input.c     |   9 +
 .../optimization/dead-code-elimination/script.py   |  23 +++
 .../optimization/dead-code-elimination/stdout.txt  |   0
 .../checker/sm/regression/return-0/getopts.py      |  23 +++
 .../gcc.dg/checker/sm/regression/return-0/input.c  |   4 +
 .../checker/sm/regression/return-0/script.py       |  23 +++
 .../checker/sm/regression/return-0/stdout.txt      |   0
 .../checker/sm/regression/rhs-is-vardecl/input.c   |   8 +
 .../checker/sm/regression/rhs-is-vardecl/script.py |  23 +++
 .../sm/regression/rhs-is-vardecl/stdout.txt        |   0
 252 files changed, 7879 insertions(+)
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/phi/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/phi/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/dot/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/dot/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/dot/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/dot/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/dot/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/loop/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/loop/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/loop/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/meet/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/meet/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/meet/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/operations/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/operations/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/operations/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/params/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/params/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/params/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/unittests/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/unittests/metadata.ini
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/unittests/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/json/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/json/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/json/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/looping/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/looping/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/looping/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/looping/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/input-f.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/input-g.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/input-h.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/lto/test.h
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/metadata.ini
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/array/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/array/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/array/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/array/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/or/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/or/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/or/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/or/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.cpychecker-log.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stderr.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/getopts.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/getopts.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/getopts.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/return-0/getopts.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/return-0/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/return-0/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/return-0/stdout.txt
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/input.c
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/script.py
 create mode 100644 gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/stdout.txt

diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/input.c b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/input.c
new file mode 100644
index 0000000..8234afa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/input.c
@@ -0,0 +1,27 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+int *test(int i)
+{
+  int *foo = (int*)malloc(sizeof(int*));
+  *foo = i; /* BUG: result of malloc could be NULL */
+  return foo;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/script.py b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/script.py
new file mode 100644
index 0000000..5c59776
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/script.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that the:
+    #    foo = malloc()
+    # transitions "foo" from "ptr.start" to "ptr.unchecked"
+    node = ctxt.find_call_of('malloc')
+    ctxt.assert_statenames_for_varname(node, 'foo', {'ptr.start'})
+
+    node = ctxt.get_successor(node)
+    ctxt.assert_statenames_for_varname(node, 'foo', {'ptr.unchecked'})
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stderr.txt
new file mode 100644
index 0000000..10b4b24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/assignments/dereference-on-lhs/input.c: In function 'test':
+tests/sm/assignments/dereference-on-lhs/input.c:25:nn: error: dereference of possibly-NULL pointer foo [CWE-690]
+tests/sm/assignments/dereference-on-lhs/input.c:24:nn: note: foo assigned to the result of malloc()
+tests/sm/assignments/dereference-on-lhs/input.c:25:nn: note: dereference of possibly-NULL pointer foo
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-lhs/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/input.c b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/input.c
new file mode 100644
index 0000000..6a1c472
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/input.c
@@ -0,0 +1,28 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+int *test(int i)
+{
+  int *foo = (int*)malloc(sizeof(int*));
+  i = *foo; /* BUG: result of malloc could be NULL
+               (fwiw it's also uninitialized) */
+  return foo;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/script.py b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stderr.txt
new file mode 100644
index 0000000..dd63384
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/assignments/dereference-on-rhs/input.c: In function 'test':
+tests/sm/assignments/dereference-on-rhs/input.c:25:nn: error: dereference of possibly-NULL pointer foo [CWE-690]
+tests/sm/assignments/dereference-on-rhs/input.c:24:nn: note: foo assigned to the result of malloc()
+tests/sm/assignments/dereference-on-rhs/input.c:25:nn: note: dereference of possibly-NULL pointer foo
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/dereference-on-rhs/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/input.c b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/input.c
new file mode 100644
index 0000000..b1c939a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/input.c
@@ -0,0 +1,38 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+extern void marker(char *buffer);
+
+char *test(int flag)
+{
+  char *buffer;
+
+  if (flag) {
+    buffer = (char*)malloc(4096);
+  } else {
+    buffer = NULL;
+  }
+
+  marker(buffer);
+  buffer[0] = 'a';
+
+  return buffer;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/script.py b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/script.py
new file mode 100644
index 0000000..6de41ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/script.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that at
+    #    marker(buffer)
+    # that we have the states from both paths:
+    node = ctxt.find_call_of('marker')
+    ctxt.assert_statenames_for_varname(node, 'buffer', {'ptr.unchecked', 'ptr.null'})
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stderr.txt
new file mode 100644
index 0000000..13d76ca
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stderr.txt
@@ -0,0 +1,7 @@
+tests/sm/assignments/phi/input.c: In function 'test':
+tests/sm/assignments/phi/input.c:35:nn: error: dereference of NULL pointer buffer [CWE-690]
+tests/sm/assignments/phi/input.c:31:nn: note: buffer assigned to 0
+tests/sm/assignments/phi/input.c:35:nn: note: dereference of NULL pointer buffer
+tests/sm/assignments/phi/input.c:35:nn: error: dereference of possibly-NULL pointer buffer [CWE-690]
+tests/sm/assignments/phi/input.c:29:nn: note: buffer assigned to the result of malloc()
+tests/sm/assignments/phi/input.c:35:nn: note: dereference of possibly-NULL pointer buffer
diff --git a/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/assignments/phi/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/input.c
new file mode 100644
index 0000000..141e55c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/input.c
@@ -0,0 +1,30 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+extern void foo(void *ptrA, void *ptrB, void *ptrC)
+  __attribute__((nonnull (1, 3)));
+
+void test(void *p, void *q, void *r)
+{
+  p = NULL;
+
+  foo(p, q, r);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stderr.txt
new file mode 100644
index 0000000..cc5466f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/arg_must_not_be_null/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/arg_must_not_be_null/input.c:29:nn: error: NULL pointer p passed as argument 1 to foo [CWE-690]
+tests/sm/checkers/malloc-checker/arg_must_not_be_null/input.c:27:nn: note: p assigned to 0
+tests/sm/checkers/malloc-checker/arg_must_not_be_null/input.c:29:nn: note: NULL pointer p passed as argument 1 to foo
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/arg_must_not_be_null/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c
new file mode 100644
index 0000000..c357663
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c
@@ -0,0 +1,31 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+int test(void)
+{
+  void *ptr = malloc(4096);
+  if (!ptr)
+    return -1; /* FIXME: with a plain return we have a BB with no gimple, and that breaks my checker */
+  memset(ptr, 0, 4096);
+  free(ptr);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/correct_usage/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c
new file mode 100644
index 0000000..56385c3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c
@@ -0,0 +1,29 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+void test(void *ptr)
+{
+  free(ptr);
+
+  /* BUG: double-free: */
+  free(ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stderr.txt
new file mode 100644
index 0000000..6bdd7a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stderr.txt
@@ -0,0 +1,7 @@
+tests/sm/checkers/malloc-checker/double_free/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/double_free/input.c:28:nn: error: double-free of ptr [CWE-415]
+tests/sm/checkers/malloc-checker/double_free/input.c:25:nn: note: ptr passed to free()
+tests/sm/checkers/malloc-checker/double_free/input.c:28:nn: note: double-free of ptr
+tests/sm/checkers/malloc-checker/double_free/input.c:28:nn: error: use-after-free of ptr [CWE-416]
+tests/sm/checkers/malloc-checker/double_free/input.c:25:nn: note: ptr passed to free()
+tests/sm/checkers/malloc-checker/double_free/input.c:28:nn: note: use-after-free of ptr
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/double_free/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c
new file mode 100644
index 0000000..01a2387
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c
@@ -0,0 +1,42 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+void test(int i, int j)
+{
+  int k;
+  void *ptr;
+  for (k = i; k < j; k++) {
+    switch(k) {
+    case 0:
+      ptr = malloc(1024);
+      break;
+    case 1:
+      break;
+    case 2:
+      break;
+    default:
+      break;
+    }
+  }
+  memset(ptr, 0, 4096);
+  free(ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stderr.txt
new file mode 100644
index 0000000..2744fa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/fancy_control_flow/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/fancy_control_flow/input.c:40:nn: error: possibly-NULL pointer ptr passed as argument 1 to memset [CWE-690]
+tests/sm/checkers/malloc-checker/fancy_control_flow/input.c:30:nn: note: ptr assigned to the result of malloc()
+tests/sm/checkers/malloc-checker/fancy_control_flow/input.c:40:nn: note: possibly-NULL pointer ptr passed as argument 1 to memset
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/fancy_control_flow/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/leak-in-error-handling/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/not-a-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/simple-leak/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/leaks/unchecked-return/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c
new file mode 100644
index 0000000..7db1b58
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c
@@ -0,0 +1,41 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+struct foo {
+  int i;
+  int j;
+  int k;
+};
+
+struct foo *test(void)
+{
+  struct foo *p = NULL;
+
+  /* BUG: dereference of NULL ptr: */
+  p->i = 1;
+
+  /* Only the first such usage should be reported: */
+  p->j = 2;
+  p->k = 3;
+
+  return p;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/script.py
new file mode 100644
index 0000000..71617ba
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/script.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node_write_to_p = ctxt.get_nodes().assigning_constant(0).one()
+    ssaname = node_write_to_p.stmt.lhs
+
+    p = ctxt.find_var(node_write_to_p, 'p')
+    node_write_to_p_i = ctxt.get_nodes().assigning_constant(1).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_i, p,
+                                    frozenset(['ptr.null']))
+
+    # It should now have given up, with the p in the "ptr.stop" state:
+    node_write_to_p_j = ctxt.get_nodes().assigning_constant(2).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_j, p,
+                                    frozenset(['ptr.stop']))
+
+    node_write_to_p_k = ctxt.get_nodes().assigning_constant(3).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_k, p,
+                                    frozenset(['ptr.stop']))
+
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stderr.txt
new file mode 100644
index 0000000..c1d6d40
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c:34:nn: error: dereference of NULL pointer p [CWE-690]
+tests/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c:31:nn: note: p assigned to 0
+tests/sm/checkers/malloc-checker/multiple-errors/deref-of-null/input.c:34:nn: note: dereference of NULL pointer p
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/deref-of-null/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c
new file mode 100644
index 0000000..e1b0e28
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c
@@ -0,0 +1,41 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+struct foo {
+  int i;
+  int j;
+  int k;
+};
+
+struct foo *test(void)
+{
+  struct foo *p = (struct foo*)malloc(4096);
+
+  /* BUG: usage of p without checking if malloc return NULL: */
+  p->i = 1;
+
+  /* Only the first such usage should be reported: */
+  p->j = 2;
+  p->k = 3;
+
+  return p;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/script.py
new file mode 100644
index 0000000..263594c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/script.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node_call = ctxt.find_call_of('malloc')
+    ssaname = node_call.stmt.lhs
+
+    p = ctxt.find_var(node_call, 'p')
+    node_write_to_p_i = ctxt.get_nodes().assigning_constant(1).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_i, p,
+                                    frozenset(['ptr.unchecked']))
+
+    # It should now have given up, with the p in the "ptr.nonnull" state:
+    node_write_to_p_j = ctxt.get_nodes().assigning_constant(2).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_j, p,
+                                    frozenset(['ptr.nonnull']))
+
+    node_write_to_p_k = ctxt.get_nodes().assigning_constant(3).one()
+    ctxt.assert_statenames_for_expr(node_write_to_p_k, p,
+                                    frozenset(['ptr.nonnull']))
+
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stderr.txt
new file mode 100644
index 0000000..7861bb4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c:34:nn: error: dereference of possibly-NULL pointer p [CWE-690]
+tests/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c:31:nn: note: p assigned to the result of malloc()
+tests/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/input.c:34:nn: note: dereference of possibly-NULL pointer p
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/multiple-errors/unchecked_malloc/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c
new file mode 100644
index 0000000..28a1cdd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c
@@ -0,0 +1,35 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+int test(void)
+{
+  void *p = malloc(4096);
+  void *q = malloc(4096);
+  if (p) {
+    memset(p, 0, 4096); /* Not a bug: checked */
+  } else {
+    memset(q, 0, 4096); /* BUG: not checked */
+  }
+  free(p);
+  free(q);
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stderr.txt
new file mode 100644
index 0000000..7f11a6a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/two_ptrs/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/two_ptrs/input.c:30:nn: error: possibly-NULL pointer q passed as argument 1 to memset [CWE-690]
+tests/sm/checkers/malloc-checker/two_ptrs/input.c:26:nn: note: q assigned to the result of malloc()
+tests/sm/checkers/malloc-checker/two_ptrs/input.c:30:nn: note: possibly-NULL pointer q passed as argument 1 to memset
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/two_ptrs/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c
new file mode 100644
index 0000000..358f4c9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c
@@ -0,0 +1,28 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+void *test(void)
+{
+  void *ptr = malloc(4096);
+  memset(ptr, 0, 4096);
+  return ptr;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stderr.txt
new file mode 100644
index 0000000..c08d698
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/unchecked_malloc/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/unchecked_malloc/input.c:26:nn: error: possibly-NULL pointer ptr passed as argument 1 to memset [CWE-690]
+tests/sm/checkers/malloc-checker/unchecked_malloc/input.c:25:nn: note: ptr assigned to the result of malloc()
+tests/sm/checkers/malloc-checker/unchecked_malloc/input.c:26:nn: note: possibly-NULL pointer ptr passed as argument 1 to memset
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/unchecked_malloc/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c
new file mode 100644
index 0000000..ca01596
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+void foo(void *ptr);
+
+void test(int i)
+{
+  void *p;
+
+  p = malloc(1024);
+  if (p) {
+    free(p);
+    foo(p);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stderr.txt
new file mode 100644
index 0000000..f0ce7d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/malloc-checker/use_after_free/input.c: In function 'test':
+tests/sm/checkers/malloc-checker/use_after_free/input.c:32:nn: error: use-after-free of p [CWE-416]
+tests/sm/checkers/malloc-checker/use_after_free/input.c:31:nn: note: p passed to free()
+tests/sm/checkers/malloc-checker/use_after_free/input.c:32:nn: note: use-after-free of p
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/malloc-checker/use_after_free/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/input.c
new file mode 100644
index 0000000..b400778
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/input.c
@@ -0,0 +1,31 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+void test_bad_putenv(const char *key, const char *value)
+{
+  char buffer[1024];
+  
+  snprintf(buffer, 1024, "%s=%s", key, value);
+
+  /* BUG: buffer is on the stack, and some implementations of putenv only
+     store a pointer to the string: */
+  (void)putenv(buffer);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/script.py
new file mode 100644
index 0000000..ef77626
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/script.py
@@ -0,0 +1,31 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import gcc
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 1:
+        import sys
+        solution.dump(sys.stderr)
+
+checker = parse_file('sm/checkers/points_to_stack.sm')
+print(checker)
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stderr.txt
new file mode 100644
index 0000000..f0976f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stderr.txt
@@ -0,0 +1,22 @@
+tests/sm/checkers/taint/example/input.c: In function 'test':
+tests/sm/checkers/taint/example/input.c:37:nn: error: use of tainted value tmp.i in array lookup without bounds checking [CWE-129]
+tests/sm/checkers/taint/example/input.c:34:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:37:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:37:nn: note: use of tainted value tmp.i in array lookup without bounds checking
+tests/sm/checkers/taint/example/input.c: In function 'test4':
+tests/sm/checkers/taint/example/input.c:68:nn: error: use of tainted value tmp.i in array lookup without upper-bound check [CWE-129]
+tests/sm/checkers/taint/example/input.c:65:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:66:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:66:nn: note: tmp.i compared against 0
+tests/sm/checkers/taint/example/input.c:68:nn: note: use of tainted value tmp.i in array lookup without upper-bound check
+tests/sm/checkers/taint/example/input.c: In function 'test5':
+tests/sm/checkers/taint/example/input.c:81:nn: error: use of tainted value tmp.i in array lookup without lower-bound check [CWE-129]
+tests/sm/checkers/taint/example/input.c:78:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:79:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:79:nn: note: tmp.i compared against 255
+tests/sm/checkers/taint/example/input.c:81:nn: note: use of tainted value tmp.i in array lookup without lower-bound check
+tests/sm/checkers/taint/example/input.c: In function 'test6':
+tests/sm/checkers/taint/example/input.c:101:nn: error: use of tainted value tmp.i in array lookup without bounds checking [CWE-129]
+tests/sm/checkers/taint/example/input.c:98:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:101:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:101:nn: note: use of tainted value tmp.i in array lookup without bounds checking
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/putenv/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c
new file mode 100644
index 0000000..730a400
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c
@@ -0,0 +1,69 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+
+char *test(const char *name)
+{
+  char buffer[1024];
+  char *result = NULL;
+
+  snprintf(buffer, 1024, "hello %s", name);
+
+  /* Note that if we simply
+       "return buffer;"
+     gcc is smart enough by itself to issue
+        "warning: function returns address of local variable [enabled by default]"
+     from c-typeck.c:c_finish_return as it builds the return statement.
+
+     However, if we introduce some dataflow, this warning isn't issued by
+     that code - but our points_to_stack.sm script can it:
+  */
+  result = buffer;
+
+  /* BUG: returns pointer to variable on the stack: */
+  return result;
+}
+
+char *test2(const char *name)
+{
+  static char buffer[1024];
+  char *result = NULL;
+
+  snprintf(buffer, 1024, "hello %s", name);
+
+  result = buffer;
+
+  /* Not a bug: buffer is static */
+  return result;
+}
+
+char other_buffer[1024];
+
+char *test3(const char *name)
+{
+  char *result = NULL;
+
+  snprintf(other_buffer, 1024, "hello %s", name);
+
+  result = other_buffer;
+
+  /* Not a bug: other_buffer is global */
+  return result;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/script.py
new file mode 100644
index 0000000..60feca7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/script.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import gcc
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+checker = parse_file('sm/checkers/points_to_stack.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stderr.txt
new file mode 100644
index 0000000..55b4ce0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stderr.txt
@@ -0,0 +1,5 @@
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c: In function 'test':
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: error: return of "result" returns address within stack of local variable "buffer" [CWE-562]
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:38:nn: note: assignment of result to &buffer
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: note: state of result ("State('ptr.points_to_stack', 'var_pointed_to'=gcc.VarDecl('buffer'))") propagated to result
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: note: return of "result" returns address within stack of local variable "buffer"
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/points_to_stack/return_of_ptr_to_local/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/input.c
new file mode 100644
index 0000000..282c9bc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/input.c
@@ -0,0 +1,52 @@
+/*
+   Copyright 2013 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2013 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <signal.h>
+
+extern void body_of_program(void);
+
+int logging = 1;
+
+void custom_logger(const char *msg)
+{
+  if (logging) {
+    (void)fprintf(stderr, "LOG: %s", msg);
+  }
+}
+
+void handler(int signum)
+{
+  /* BUG: log calls fprintf, and this is not allowed from a signal
+     handler: */
+  custom_logger("got signal");
+}
+
+int main(int argc, const char *argv)
+{
+  custom_logger("started");
+
+  signal(SIGINT, handler);
+
+  body_of_program();
+
+  custom_logger("stopped");
+
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/script.py
new file mode 100644
index 0000000..80fe4ad
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/script.py
@@ -0,0 +1,30 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import gcc
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 1:
+        import sys
+        solution.dump(sys.stderr)
+
+checker = parse_file('sm/checkers/signal_handler.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stderr.txt
new file mode 100644
index 0000000..55b4ce0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stderr.txt
@@ -0,0 +1,5 @@
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c: In function 'test':
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: error: return of "result" returns address within stack of local variable "buffer" [CWE-562]
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:38:nn: note: assignment of result to &buffer
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: note: state of result ("State('ptr.points_to_stack', 'var_pointed_to'=gcc.VarDecl('buffer'))") propagated to result
+tests/sm/checkers/points_to_stack/return_of_ptr_to_local/input.c:41:nn: note: return of "result" returns address within stack of local variable "buffer"
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/signal_handler/example/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/input.c
new file mode 100644
index 0000000..e5053c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/input.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[1024];
+};
+
+struct bar {
+  char buffer[128];
+};
+
+struct foo *test(void)
+{
+  return (struct foo*)calloc(4, sizeof(struct bar));
+  /* BUG: sizeof(bar), rather than sizeof(foo), hence not enough space */
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/script.py
new file mode 100644
index 0000000..cd01c16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stderr.txt
new file mode 100644
index 0000000..f62e50e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/checkers/sizeof_allocation/calloc_too_small/input.c: In function 'test':
+tests/sm/checkers/sizeof_allocation/calloc_too_small/input.c:32:nn: error: allocation too small: pointer to struct foo (1024 bytes) initialized with allocation of 512 bytes [CWE-131]
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/calloc_too_small/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/input.c
new file mode 100644
index 0000000..e0a994e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/input.c
@@ -0,0 +1,31 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[256];
+  int i, j, k;
+  float x, y, z;
+};
+
+struct foo *test(void)
+{
+  return (struct foo*)malloc(sizeof(struct foo));
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/script.py
new file mode 100644
index 0000000..cd01c16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_correct_size/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/input.c
new file mode 100644
index 0000000..71b619e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/input.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[128];
+};
+
+struct bar {
+  char buffer[256];
+};
+
+struct foo *test(void)
+{
+  return (struct foo*)malloc(sizeof(struct bar));
+  /* not a reportable bug: although the sizeof() is wrong, the size is large
+     enough, and some code does runtime size calculation that we don't want to
+     issue a false positive over */
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/script.py
new file mode 100644
index 0000000..cd01c16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_large/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/input.c
new file mode 100644
index 0000000..948a2de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/input.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[256];
+};
+
+struct bar {
+  char buffer[128];
+};
+
+struct foo *test(void)
+{
+  return (struct foo*)malloc(sizeof(struct bar));
+  /* BUG: sizeof(bar), rather than sizeof(foo), hence not enough space */
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/script.py
new file mode 100644
index 0000000..cd01c16
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stderr.txt
new file mode 100644
index 0000000..fcb1fd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/checkers/sizeof_allocation/malloc_too_small/input.c: In function 'test':
+tests/sm/checkers/sizeof_allocation/malloc_too_small/input.c:32:nn: error: allocation too small: pointer to struct foo (256 bytes) initialized with allocation of 128 bytes [CWE-131]
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/malloc_too_small/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c
new file mode 100644
index 0000000..a3b3f9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[256];
+};
+
+struct bar {
+  char buffer[128];
+};
+
+struct foo *test(void)
+{
+  void *ptr;
+  ptr = malloc(sizeof(struct bar));
+  /* BUG: sizeof(bar), rather than sizeof(foo), hence not enough space */
+  return ptr;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/script.py
new file mode 100644
index 0000000..4f333a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/script.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+from sm.solver import State
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that the set_state() due to the pattern match for:
+    #     ptr = malloc(sizeof(struct bar));
+    # transitions the state of ptr from "ptr.start" to a "ptr.sized" instance
+    # with the correct size
+    node = ctxt.find_call_of('malloc')
+    ctxt.assert_statenames_for_varname(node, 'ptr', {'ptr.start'})
+
+    node = ctxt.get_successor(node)
+    ctxt.assert_states_for_varname(node, 'ptr',
+                                   {State('ptr.sized', size=128)})
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stderr.txt
new file mode 100644
index 0000000..59aeba1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c: In function 'test':
+tests/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c:35:nn: error: allocation too small: pointer to struct foo (256 bytes) initialized with allocation of 128 bytes [CWE-131]
+tests/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c:33:nn: note: ptr assigned to the result of malloc(128)
+tests/sm/checkers/sizeof_allocation/stateful_malloc_too_small/input.c:35:nn: note: allocation too small: pointer to struct foo (256 bytes) initialized with allocation of 128 bytes
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/stateful_malloc_too_small/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/input.c
new file mode 100644
index 0000000..ffaab54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/input.c
@@ -0,0 +1,32 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+struct foo {
+  char buffer[256];
+};
+
+struct foo *test(int i)
+{
+  void *ptr;
+  ptr = malloc(i);
+  /* might or might not be a bug; we don't know, so don't issue a bug */
+  return ptr;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/script.py
new file mode 100644
index 0000000..02f3146
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/script.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+from sm.solver import State
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that ptr doesn't change state due to
+    #     ptr = malloc(i);
+    # since the checker only tracks constant integer values:
+    node = ctxt.find_call_of('malloc')
+    ctxt.assert_statenames_for_varname(node, 'ptr', {'ptr.start'})
+
+    node = ctxt.get_successor(node)
+    ctxt.assert_statenames_for_varname(node, 'ptr', {'ptr.start'})
+
+checker = parse_file('sm/checkers/sizeof_allocation.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/sizeof_allocation/unknown_size/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/input.c b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/input.c
new file mode 100644
index 0000000..ef9acb5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/input.c
@@ -0,0 +1,131 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+struct foo
+{
+  signed int i;
+  char buf[256];
+};
+
+char test(FILE *f)
+{
+  struct foo tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    /* BUG: the following array lookup trusts that the input data's index is
+       in the range 0 <= i < 256; otherwise it's accessing the stack */
+    return tmp.buf[tmp.i];
+  }
+  return 0;
+}
+
+char test2(struct foo *f, int i)
+{
+  /* not a bug: the data is not known to be tainted: */
+  return f->buf[f->i];
+}
+
+char test3(FILE *f)
+{
+  struct foo tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i >= 0 && tmp.i < 256) {
+      /* not a bug: the access is guarded by upper and lower bounds: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
+
+char test4(FILE *f)
+{
+  struct foo tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i >= 0) {
+      /* BUG: has a lower bound, but not an upper bound: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
+
+char test5(FILE *f)
+{
+  struct foo tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i < 256) {
+      /* BUG: has an upper bound, but not a lower bound: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
+
+/* unsigned types have a natural lower bound of 0 */
+struct bar
+{
+  unsigned int i;
+  char buf[256];
+};
+
+char test6(FILE *f)
+{
+  struct bar tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i >= 0) {
+      /* BUG: has an implicit lower bound, but not an upper bound: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
+
+char test7(FILE *f)
+{
+  struct bar tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i < 256) {
+      /* not a bug: has an upper bound, and an implicit lower bound: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
+
+char test8(FILE *f)
+{
+  struct foo tmp;
+
+  if (1 == fread(&tmp, sizeof(tmp), 1, f)) {
+    if (tmp.i == 42) {
+      /* not a bug: tmp.i compared against a specific value: */
+      return tmp.buf[tmp.i];
+    }
+  }
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/script.py b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/script.py
new file mode 100644
index 0000000..9287534
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/script.py
@@ -0,0 +1,71 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import gcc
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify the various state transitions within "test3"
+
+    # Verify that the:
+    #    D.2837_3 = fread (&tmp, 260, 1, f_2(D));
+    # transitions "tmp" from "x.start" to "x.tainted"
+    node = ctxt.find_call_of('fread', within='test3')
+    ctxt.assert_statenames_for_varname(node, 'tmp', {'x.start'})
+
+    node = ctxt.get_successor(node)
+    ctxt.assert_statenames_for_varname(node, 'tmp', {'x.tainted'})
+
+    # Verify that the:
+    #    if (D.n >= 0)
+    # transitions "D.n" from "x.tainted" to "x.has_lb"
+    node = ctxt.find_comparison_against(gcc.GeExpr, 0, within='test3')
+    tempvar = node.stmt.lhs
+    ctxt.assert_statenames_for_expr(node, tempvar, {'x.tainted'})
+
+    node = ctxt.get_true_successor(node)
+    ctxt.assert_statenames_for_expr(node, tempvar, {'x.has_lb'})
+
+    # Verify that the:
+    #    if (D.n <= 255)
+    # transitions "D.n" from "x.has_lb" to "x.ok"
+    node = ctxt.find_comparison_against(gcc.LeExpr, 255, within='test3')
+    tempvar = node.stmt.lhs
+    ctxt.assert_statenames_for_expr(node, tempvar, {'x.has_lb'})
+
+    node = ctxt.get_true_successor(node)
+    ctxt.assert_statenames_for_expr(node, tempvar, {'x.ok'})
+
+    # Verify that it's within the same equivcls as "tmp.i"
+    tmp_i = ctxt.get_expr_by_str(node, 'tmp.i')
+    ctxt.assert_statenames_for_expr(node, tmp_i, {'x.ok'})
+
+checker = parse_file('sm/checkers/taint.sm')
+#print(checker)
+dot = checker.to_dot('test_script')
+#print(dot)
+if 0:
+    from gccutils import invoke_dot
+    invoke_dot(dot)
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stderr.txt
new file mode 100644
index 0000000..f0976f0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stderr.txt
@@ -0,0 +1,22 @@
+tests/sm/checkers/taint/example/input.c: In function 'test':
+tests/sm/checkers/taint/example/input.c:37:nn: error: use of tainted value tmp.i in array lookup without bounds checking [CWE-129]
+tests/sm/checkers/taint/example/input.c:34:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:37:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:37:nn: note: use of tainted value tmp.i in array lookup without bounds checking
+tests/sm/checkers/taint/example/input.c: In function 'test4':
+tests/sm/checkers/taint/example/input.c:68:nn: error: use of tainted value tmp.i in array lookup without upper-bound check [CWE-129]
+tests/sm/checkers/taint/example/input.c:65:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:66:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:66:nn: note: tmp.i compared against 0
+tests/sm/checkers/taint/example/input.c:68:nn: note: use of tainted value tmp.i in array lookup without upper-bound check
+tests/sm/checkers/taint/example/input.c: In function 'test5':
+tests/sm/checkers/taint/example/input.c:81:nn: error: use of tainted value tmp.i in array lookup without lower-bound check [CWE-129]
+tests/sm/checkers/taint/example/input.c:78:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:79:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:79:nn: note: tmp.i compared against 255
+tests/sm/checkers/taint/example/input.c:81:nn: note: use of tainted value tmp.i in array lookup without lower-bound check
+tests/sm/checkers/taint/example/input.c: In function 'test6':
+tests/sm/checkers/taint/example/input.c:101:nn: error: use of tainted value tmp.i in array lookup without bounds checking [CWE-129]
+tests/sm/checkers/taint/example/input.c:98:nn: note: tmp passed to fread()
+tests/sm/checkers/taint/example/input.c:101:nn: note: state of tmp ("x.tainted") propagated to tmp.i
+tests/sm/checkers/taint/example/input.c:101:nn: note: use of tainted value tmp.i in array lookup without bounds checking
diff --git a/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/checkers/taint/example/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/dot/input.c b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c
@@ -0,0 +1 @@
+
diff --git a/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/dot/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/dot/script.py b/gcc/testsuite/gcc.dg/checker/sm/dot/script.py
new file mode 100644
index 0000000..450cdd6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/dot/script.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+SCRIPT = '''
+sm malloc_checker {
+  state decl any_pointer ptr;
+
+  ptr.all:
+    { ptr = malloc() } =>  ptr.unknown;
+
+  ptr.unknown, ptr.null, ptr.nonnull:
+      { ptr == 0 } => true=ptr.null, false=ptr.nonnull
+    | { ptr != 0 } => true=ptr.nonnull, false=ptr.null
+    ;
+
+  ptr.unknown:
+    { *ptr } => { error('use of possibly-NULL pointer %s' % ptr)};
+
+  ptr.null:
+    { *ptr } => { error('use of NULL pointer %s' % ptr)};
+
+  ptr.all, ptr.unknown, ptr.null, ptr.nonnull:
+    { free(ptr) } => ptr.free;
+
+  ptr.free:
+      { free(ptr) } => { error('double-free of %s' % ptr)}
+    | { ptr } => {error('use-after-free of %s' % ptr)}
+    ;
+}
+'''
+
+from sm.parser import parse_file
+ch = parse_file('sm/checkers/malloc_checker.sm')
+if 0:
+    print(ch)
+dot = ch.to_dot('test_script')
+print(dot)
+if 0:
+    from gccutils import invoke_dot
+    invoke_dot(dot)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/dot/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/dot/stdout.txt
new file mode 100644
index 0000000..15abf23
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/dot/stdout.txt
@@ -0,0 +1,83 @@
+digraph test_script {
+  subgraph malloc_checker {
+    ptr_unchecked [label=<ptr.unchecked>];
+    ptr_null [label=<ptr.null>];
+    ptr_start [label=<ptr.start>];
+    ptr_nonnull [label=<ptr.nonnull>];
+    ptr_free [label=<ptr.free>];
+
+    ptr_unchecked -> ptr_unchecked [label=<{ ptr = malloc() }>];
+    ptr_null -> ptr_unchecked [label=<{ ptr = malloc() }>];
+    ptr_start -> ptr_unchecked [label=<{ ptr = malloc() }>];
+    ptr_nonnull -> ptr_unchecked [label=<{ ptr = malloc() }>];
+    ptr_free -> ptr_unchecked [label=<{ ptr = malloc() }>];
+    ptr_unchecked -> ptr_null [label=<{ ptr = 0 }>];
+    ptr_null -> ptr_null [label=<{ ptr = 0 }>];
+    ptr_start -> ptr_null [label=<{ ptr = 0 }>];
+    ptr_nonnull -> ptr_null [label=<{ ptr = 0 }>];
+    ptr_free -> ptr_null [label=<{ ptr = 0 }>];
+    ptr_unchecked -> ptr_null [label=<{ ptr == 0 } is True>];
+    ptr_unchecked -> ptr_nonnull [label=<{ ptr == 0 } is False>];
+    ptr_unchecked -> ptr_nonnull [label=<{ ptr != 0 } is True>];
+    ptr_unchecked -> ptr_null [label=<{ ptr != 0 } is False>];
+    ptr_null -> ptr_null [label=<{ ptr == 0 } is True>];
+    ptr_null -> ptr_nonnull [label=<{ ptr == 0 } is False>];
+    ptr_null -> ptr_nonnull [label=<{ ptr != 0 } is True>];
+    ptr_null -> ptr_null [label=<{ ptr != 0 } is False>];
+    ptr_start -> ptr_null [label=<{ ptr == 0 } is True>];
+    ptr_start -> ptr_nonnull [label=<{ ptr == 0 } is False>];
+    ptr_start -> ptr_nonnull [label=<{ ptr != 0 } is True>];
+    ptr_start -> ptr_null [label=<{ ptr != 0 } is False>];
+    ptr_nonnull -> ptr_null [label=<{ ptr == 0 } is True>];
+    ptr_nonnull -> ptr_nonnull [label=<{ ptr == 0 } is False>];
+    ptr_nonnull -> ptr_nonnull [label=<{ ptr != 0 } is True>];
+    ptr_nonnull -> ptr_null [label=<{ ptr != 0 } is False>];
+    ptr_free -> ptr_null [label=<{ ptr == 0 } is True>];
+    ptr_free -> ptr_nonnull [label=<{ ptr == 0 } is False>];
+    ptr_free -> ptr_nonnull [label=<{ ptr != 0 } is True>];
+    ptr_free -> ptr_null [label=<{ ptr != 0 } is False>];
+    ptr_unchecked -> ptr_unchecked [label=<{ *ptr }: 
+            error(&apos;dereference of possibly-NULL pointer %s&apos; % ptr,
+                  # &quot;CWE-690: Unchecked Return Value to NULL Pointer Dereference&quot;
+                  cwe=&apos;CWE-690&apos;)
+         >];
+    ptr_unchecked -> ptr_nonnull [label=<{ *ptr }>];
+    ptr_null -> ptr_null [label=<{ *ptr }: 
+            error(&apos;dereference of NULL pointer %s&apos; % ptr,
+                  # &quot;CWE-690: Unchecked Return Value to NULL Pointer Dereference&quot;
+                  cwe=&apos;CWE-690&apos;)
+         >];
+    ptr_null -> ptr_stop [label=<{ *ptr }>];
+    ptr_start -> ptr_free [label=<{ free(ptr) } >];
+    ptr_unchecked -> ptr_free [label=<{ free(ptr) } >];
+    ptr_null -> ptr_free [label=<{ free(ptr) } >];
+    ptr_nonnull -> ptr_free [label=<{ free(ptr) } >];
+    ptr_free -> ptr_free [label=<{ free(ptr) } : 
+                error(&apos;double-free of %s&apos; % ptr,
+                      # &quot;CWE-415: Double Free&quot;
+                      cwe=&apos;CWE-415&apos;)
+             >];
+    ptr_free -> ptr_stop [label=<{ free(ptr) } >];
+    ptr_free -> ptr_free [label=<{ ptr }: 
+                error(&apos;use-after-free of %s&apos; % ptr,
+                      # &quot;CWE-416: Use After Free&quot;
+                      cwe=&apos;CWE-416&apos;)
+             >];
+    ptr_free -> ptr_stop [label=<{ ptr }>];
+    ptr_unchecked -> ptr_unchecked [label=<$arg_must_not_be_null$: 
+            error(&apos;possibly-NULL pointer %s passed as argument %i to %s&apos;
+                  % (ptr, argnumber, function),
+                  # &quot;CWE-690: Unchecked Return Value to NULL Pointer Dereference&quot;
+                  cwe=&apos;CWE-690&apos;)
+          >];
+    ptr_unchecked -> ptr_nonnull [label=<$arg_must_not_be_null$>];
+    ptr_null -> ptr_null [label=<$arg_must_not_be_null$: 
+            error(&apos;NULL pointer %s passed as argument %i to %s&apos;
+                  % (ptr, argnumber, function),
+                  # &quot;CWE-690: Unchecked Return Value to NULL Pointer Dereference&quot;
+                  cwe=&apos;CWE-690&apos;)
+         >];
+    ptr_null -> ptr_stop [label=<$arg_must_not_be_null$>];
+  }
+}
+
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/input.c
new file mode 100644
index 0000000..8749bd3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/input.c
@@ -0,0 +1,40 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+
+void test(int flag)
+{
+  marker_A();
+
+  if (flag) {
+    marker_B();
+
+    /* Recurse, infinitely, as it happens: */
+    test(flag);
+
+    marker_C();
+  }
+
+  marker_D();
+
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/script.py
new file mode 100644
index 0000000..baa3f21
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/script.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # All the fact-finder knows is that flag != 0 at marker_B:
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'flag', '!=', 0)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/infinite-recursion/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/loop/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/loop/input.c
new file mode 100644
index 0000000..40a0dc6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/loop/input.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+
+void test(void)
+{
+  int i;
+
+  marker_A();
+
+  for (i=0; i<256; i++) {
+    marker_B();
+  }
+
+  marker_C();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/loop/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/loop/script.py
new file mode 100644
index 0000000..9e0681d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/loop/script.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    # Check that we know the constraints on i within the loop:
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'i', '<=', 255)
+    ctxt.assert_not_fact(node, 'i', '==', 0)
+
+    # Check that we know the constraints on i after the loop:
+    node = ctxt.find_call_of('marker_C')
+    ctxt.assert_fact(node, 'i', '>', 255)
+
+    # TODO: we don't yet do interval analysis, so we can't prove
+    # that (i == 256) after the loop.
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/loop/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/loop/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/meet/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/meet/input.c
new file mode 100644
index 0000000..b222c95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/meet/input.c
@@ -0,0 +1,41 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+
+void test(int flag, unsigned int i)
+{
+  if (!flag) {
+    return;
+  }
+  
+  marker_A();
+
+  if (i>0) {
+    marker_B();
+  } else {
+    marker_C();
+  }
+
+  marker_D();
+
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/meet/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/meet/script.py
new file mode 100644
index 0000000..6574be7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/meet/script.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that we know flag != 0 at marker_A:
+    node = ctxt.find_call_of('marker_A')
+    ctxt.assert_fact(node, 'flag', '!=', 0)
+
+    # We should also know it after the conditionals:
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'flag', '!=', 0)
+    ctxt.assert_fact(node, 'i', '!=', 0)
+
+    # and that due to the restricted range of i that i == 0 when !(i>0):
+    node = ctxt.find_call_of('marker_C')
+    ctxt.assert_fact(node, 'flag', '!=', 0)
+    ctxt.assert_fact(node, 'i', '==', 0)
+
+    # We should also know (flag != 0) when control flow merges:
+    node = ctxt.find_call_of('marker_D')
+    ctxt.assert_fact(node, 'flag', '!=', 0)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/meet/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/meet/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/input.c
new file mode 100644
index 0000000..cd13c29
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/input.c
@@ -0,0 +1,38 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+extern void marker_A(void);
+extern void marker_B(void);
+
+void test(void *ptr)
+{
+  marker_A();
+
+  /*
+     abort() is labelled with __attribute__ ((__noreturn__))
+  */
+  if (!ptr) {
+    abort();
+  }
+
+  /* Hence the fact-finder ought to know (ptr != 0) here: */
+  marker_B();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/script.py
new file mode 100644
index 0000000..e71cf1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'ptr', '!=', 0)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/abort/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/input.c
new file mode 100644
index 0000000..15c932a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/input.c
@@ -0,0 +1,37 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <assert.h>
+
+extern void marker_A(void);
+extern void marker_B(void);
+
+void test(int i)
+{
+  marker_A();
+
+  /*
+     We have not defined NDEBUG, so this will call __assert_fail if
+     i <= 10, which is labelled with __attribute__ ((__noreturn__))
+  */
+  assert(i > 10);
+
+  /* Hence the fact-finder ought to know (i > 10) here: */
+  marker_B();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/script.py
new file mode 100644
index 0000000..51ea56f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'i', '>', 10)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/assert/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/input.c
new file mode 100644
index 0000000..79c7c4e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/input.c
@@ -0,0 +1,42 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void marker_A(void);
+extern void marker_B(void);
+
+void custom_abort(const char *msg)
+{
+  fprintf(stderr, "%s", msg);
+  abort();
+}
+
+void test(void *ptr)
+{
+  marker_A();
+
+  if (!ptr) {
+    custom_abort("ptr was NULL");
+  }
+
+  /* Hence the fact-finder ought to know (ptr != 0) here: */
+  marker_B();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/script.py
new file mode 100644
index 0000000..e71cf1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'ptr', '!=', 0)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
new file mode 100644
index 0000000..0d82dd8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/input.c
@@ -0,0 +1,44 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void marker_A(void);
+extern void marker_B(void);
+
+void custom_abort(const char *msg)  __attribute__ ((__noreturn__));
+
+void custom_abort(const char *msg)
+{
+  fprintf(stderr, "%s", msg);
+  abort();
+}
+
+void test(void *ptr)
+{
+  marker_A();
+
+  if (!ptr) {
+    custom_abort("ptr was NULL");
+  }
+
+  /* Hence the fact-finder ought to know (ptr != 0) here: */
+  marker_B();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
new file mode 100644
index 0000000..e71cf1d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'ptr', '!=', 0)
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/noreturn/custom_abort_with_noreturn_attribute/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/operations/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/operations/input.c
new file mode 100644
index 0000000..b326aff
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/operations/input.c
@@ -0,0 +1,69 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+extern void marker_E(void);
+extern void marker_F(void);
+
+/*
+  Ensure that the fact-finder can sanely propagate information about
+  arithmetic operations
+*/
+
+void test(int i, int j)
+{
+  int k, m;
+
+  if (i > 42) {
+    marker_A();
+
+    i += 3;
+
+    /* (we should now know that i > 45) */
+    marker_B();
+
+    i -= 1;
+
+    /* (and now have i > 44) */
+    marker_C();
+
+    i = 3 * i;
+
+    /* (likewise now i > 132) */
+    marker_D();
+
+    i /= 2;
+
+    /* (should now have i > 66: */
+    marker_E();
+
+    /* We don't know anything about j, so we don't know anything about k: */
+    k = i + j;
+
+    /* However, we should now know that m > 67: */
+    m = i + 1;
+
+    marker_F();
+
+  }
+
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/operations/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/operations/script.py
new file mode 100644
index 0000000..bb020af
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/operations/script.py
@@ -0,0 +1,51 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that we know i > 42 at marker_A:
+    node = ctxt.find_call_of('marker_A')
+    ctxt.assert_fact(node, 'i', '>', 42)
+
+    # Verify the effect of the various arithmetic operations on the
+    # factfinder:
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'i', '>', 45)
+
+    node = ctxt.find_call_of('marker_C')
+    ctxt.assert_fact(node, 'i', '>', 44)
+
+    node = ctxt.find_call_of('marker_D')
+    ctxt.assert_fact(node, 'i', '>', 132)
+
+    node = ctxt.find_call_of('marker_E')
+    ctxt.assert_fact(node, 'i', '>', 66)
+
+    node = ctxt.find_call_of('marker_F')
+    ctxt.assert_fact(node, 'i', '>', 66)
+    ctxt.assert_fact(node, 'm', '>', 67)
+    # though we don't know anything about the relationship of i and m
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/operations/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/operations/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/params/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/params/input.c
new file mode 100644
index 0000000..e63270c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/params/input.c
@@ -0,0 +1,53 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+extern void marker_E(void);
+
+static int called_function(int j)
+{
+  int k;
+
+  marker_C();
+
+  k = j - 1;
+
+  marker_D();
+
+  return k;
+}
+
+void test(int i)
+{
+  marker_A();
+
+  if (i > 4) {
+
+    marker_B();
+
+    i = called_function(i);
+
+    marker_E();
+  }
+
+  marker_F();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/params/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/params/script.py
new file mode 100644
index 0000000..da8ac34
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/params/script.py
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main, Options
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'i', '>', 4)
+
+    # Within called_function(),
+    # arg i was passed to param j:
+    node = ctxt.find_call_of('marker_C')
+    #ctxt.assert_fact(node, 'i', '>', 4)
+    ctxt.assert_fact(node, 'j', '>', 4)
+
+    node = ctxt.find_call_of('marker_D')
+    #ctxt.assert_fact(node, 'i', '>', 4)
+    ctxt.assert_fact(node, 'j', '>', 4)
+    ctxt.assert_fact(node, 'k', '>', 3)
+
+    # Back to test:
+    # return value k was returned to i:
+    node = ctxt.find_call_of('marker_E')
+    ctxt.assert_fact(node, 'i', '>', 3)
+
+    # After control merges, we have no information:
+    node = ctxt.find_call_of('marker_F')
+    ctxt.assert_no_facts(node)
+
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/params/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/params/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/input.c
new file mode 100644
index 0000000..98632c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/input.c
@@ -0,0 +1,57 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void marker_A(void);
+extern void marker_B(void);
+extern void marker_C(void);
+extern void marker_D(void);
+extern void marker_E(void);
+extern void marker_F(void);
+extern void marker_G(void);
+
+void test(int i)
+{
+  marker_A();
+
+  switch (i) {
+    case 0 ... 10: /* GCC's "case ranges" extension to C */
+    case 20 ... 30:
+      marker_B();
+      break;
+
+    case 0x42:
+    case 42:
+      marker_C();
+      break;
+
+    case 70:
+      marker_D();
+      /* fallthrough: */
+    case 80:
+      marker_E();
+      break;
+
+    default:
+      marker_F();
+      break;
+
+  }
+
+  marker_G();
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/script.py
new file mode 100644
index 0000000..3fecff0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/script.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    node = ctxt.find_call_of('marker_A')
+
+    # Check that we know the constraints on i at each case label
+
+    # Combination of case ranges: 0 ... 10 and 20 ... 30
+    node = ctxt.find_call_of('marker_B')
+    ctxt.assert_fact(node, 'i', '>=', 0)
+    ctxt.assert_fact(node, 'i', '<=', 30)
+
+    # Combination of case labels 0x42 and 42:
+    node = ctxt.find_call_of('marker_C')
+    ctxt.assert_fact(node, 'i', '>=', 42)
+    ctxt.assert_fact(node, 'i', '<=', 0x42)
+
+    # Single case labels 70:
+    node = ctxt.find_call_of('marker_D')
+    ctxt.assert_fact(node, 'i', '==', 70)
+
+    # Case label 80 plus fallthrough of case label 70:
+    node = ctxt.find_call_of('marker_E')
+    # currently the fact-finder gives no information for the combination of
+    # the two:
+    ctxt.assert_no_facts(node)
+
+    # "default" gives no information:
+    node = ctxt.find_call_of('marker_F')
+    ctxt.assert_no_facts(node)
+
+    # Similarly, we have no information after control merges from all of
+    # the cases:
+    node = ctxt.find_call_of('marker_G')
+    ctxt.assert_no_facts(node)
+
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/switch/various-cases/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/input.c b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/input.c
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/input.c
@@ -0,0 +1 @@
+
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/metadata.ini b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/metadata.ini
new file mode 100644
index 0000000..ba7428c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/metadata.ini
@@ -0,0 +1,4 @@
+[ExpectedBehavior]
+# This test case emits warnings on stderr;
+# don't treat the stderr output as leading to an expected failure:
+exitcode = 0
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/script.py b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/script.py
new file mode 100644
index 0000000..55013d5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/script.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from sm.facts import Facts, Fact
+
+def make_facts(factlist):
+    f = Facts()
+    f.set_ = set(factlist)
+    return f
+
+class FactsTests(unittest.TestCase):
+    def test_str(self):
+        f = make_facts([Fact('b', '==', 'c'),
+                        Fact('a', '==', 'b')])
+        self.assertEqual(str(f),
+                         '(a == b && b == c)')
+
+    def test_equivclasses(self):
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('b', '==', 'c')])
+        self.assertEqual(f.get_equiv_classes(),
+                         frozenset([frozenset(['a', 'b', 'c'])]))
+
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('c', '>', 0)])
+        self.assertEqual(f.get_equiv_classes(),
+                         frozenset([frozenset(['a', 'b'])]))
+
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('c', '==', 0)])
+        self.assertEqual(f.get_equiv_classes(),
+                         frozenset([frozenset(['a', 'b']),
+                                    frozenset(['c', 0])]))
+
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('c', '==', 'd'),
+                        Fact('c', '==', 'b')])
+        self.assertEqual(f.get_equiv_classes(),
+                         frozenset([frozenset(['a', 'b', 'c', 'd'])]))
+
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('b', '==', 0),
+                        Fact('b', '!=', 1)])
+        self.assertEqual(f.get_equiv_classes(),
+                         frozenset([frozenset(['a', 'b', 0])]))
+
+    def test_aliases(self):
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('b', '==', 'c')])
+        self.assertEqual(f.get_aliases('a'),
+                         frozenset(['a', 'b', 'c']))
+        self.assertEqual(f.get_aliases('d'),
+                         frozenset(['d']))
+
+class FakeContext:
+    def __init__(self, verbose=0):
+        self.verbose = verbose
+    def debug(self, msg, *args):
+        if self.verbose:
+            print(msg % args)
+
+class IsPossibleTests(unittest.TestCase):
+    def assertPossible(self, f):
+        self.assertEqual(f.is_possible(FakeContext()), True)
+
+    def assertNotPossible(self, f):
+        self.assertEqual(f.is_possible(FakeContext()), False)
+
+    def test_empty(self):
+        f = make_facts([])
+        self.assertPossible(f)
+
+    def test_single_values(self):
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('b', '==', 0)])
+        self.assertPossible(f)
+
+    def test_inconsistent_equalities(self):
+        f = make_facts([Fact('a', '==', 'b'),
+                        Fact('b', '==', 0),
+                        Fact('b', '==', 1)])
+        self.assertNotPossible(f)
+
+    def test_inequalities(self):
+        f = make_facts([Fact('b', '==', 0),
+                        Fact('b', '!=', 1)])
+        self.assertPossible(f)
+
+        f = make_facts([Fact('b', '==', 0),
+                        Fact('b', '!=', 0)])
+        self.assertNotPossible(f)
+
+        f = make_facts([Fact('b', '==', 0),
+                        Fact('b', '>', 0)])
+        self.assertNotPossible(f)
+
+
+import sys
+sys.argv = ['foo', '-v']
+
+unittest.main()
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stderr.txt
new file mode 100644
index 0000000..d8f2681
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stderr.txt
@@ -0,0 +1,12 @@
+test_aliases (__main__.FactsTests) ... ok
+test_equivclasses (__main__.FactsTests) ... ok
+test_str (__main__.FactsTests) ... ok
+test_empty (__main__.IsPossibleTests) ... ok
+test_inconsistent_equalities (__main__.IsPossibleTests) ... ok
+test_inequalities (__main__.IsPossibleTests) ... ok
+test_single_values (__main__.IsPossibleTests) ... ok
+
+----------------------------------------------------------------------
+Ran 7 tests in #s
+
+OK
diff --git a/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/facts/unittests/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/input.c b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/input.c
new file mode 100644
index 0000000..958038a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/input.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+static void calls_free(int *q)
+{
+  free(q);
+}
+
+void test(void *p)
+{
+  calls_free(p);
+
+  /* BUG: double-free of p: already freed within calls_free() above */
+  free(p);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/script.py b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/script.py
new file mode 100644
index 0000000..063e9c4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/script.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that calls_free() converts "p" within the caller from "ptr.start"
+    # to "ptr.free":
+    node = ctxt.find_call_of('calls_free')
+    ctxt.assert_statenames_for_varname(node, 'p', {'ptr.start'})
+
+    node = ctxt.get_intraprocedural_successor(node)
+    ctxt.assert_statenames_for_varname(node, 'p', {'ptr.free'})
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stderr.txt
new file mode 100644
index 0000000..4cc823c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stderr.txt
@@ -0,0 +1,11 @@
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c: In function 'test':
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:33:nn: error: double-free of p [CWE-415]
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:30:nn: note: call from test() to calls_free()
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:25:nn: note: q passed to free()
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:30:nn: note: return from calls_free() to test(): state of q ("ptr.free") propagated to p
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:33:nn: note: double-free of p
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:33:nn: error: use-after-free of p [CWE-416]
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:30:nn: note: call from test() to calls_free()
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:25:nn: note: q passed to free()
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:30:nn: note: return from calls_free() to test(): state of q ("ptr.free") propagated to p
+tests/sm/interprocedural/arg-affected-by-usage-as-param/input.c:33:nn: note: use-after-free of p
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/arg-affected-by-usage-as-param/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c
new file mode 100644
index 0000000..3ae8558
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c
@@ -0,0 +1,35 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+static int *calls_malloc(void)
+{
+  return malloc(sizeof(int));
+}
+
+int *test(void)
+{
+    int *p = calls_malloc();
+    /* BUG: malloc could have returned NULL */
+    *p = 42;
+    return p;
+}
+
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/script.py b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/script.py
new file mode 100644
index 0000000..096ac60
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/script.py
@@ -0,0 +1,37 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that the:
+    #   int *p = calls_malloc();
+    # transitions "p" from "ptr.start" to "ptr.unknown"
+    node = ctxt.find_call_of('calls_malloc')
+    ctxt.assert_statenames_for_varname(node, 'p', {'ptr.start'})
+
+    node = ctxt.get_intraprocedural_successor(node)
+    ctxt.assert_statenames_for_varname(node, 'p', {'ptr.unchecked'})
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stderr.txt
new file mode 100644
index 0000000..338e9b4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stderr.txt
@@ -0,0 +1,6 @@
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c: In function 'test':
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c:32:nn: error: dereference of possibly-NULL pointer p [CWE-690]
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c:30:nn: note: call from test() to calls_malloc()
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c:25:nn: note: return value assigned to the result of malloc()
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c:30:nn: note: return from calls_malloc() to test(): state of return value ("ptr.unchecked") propagated to p
+tests/sm/interprocedural/callsite-lhs-inherits-from-return-val/input.c:32:nn: note: dereference of possibly-NULL pointer p
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/callsite-lhs-inherits-from-return-val/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/input.c b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/input.c
new file mode 100644
index 0000000..5a01138
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/input.c
@@ -0,0 +1,56 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+static void *f(int a)
+{
+  if (a) {
+    void *p = malloc(4096);
+    return p;
+  } else {
+    return NULL;
+  }
+}
+
+static void g(int b, void *q)
+{
+  if (b==2) {
+    g(b, q); /* contrived infinite recursion */
+  }
+  free(q);
+}
+
+void h(int c)
+{
+  int *r = (int*)f(c);
+  r[0] = 42; /* BUG: the malloc in f could have failed */
+  g(c, r);
+  free(r); /* BUG: doublefree here, given that g frees the ptr */
+}
+
+static int factorial(int n)
+{
+  if (n < 2) {
+    return 1;
+  } else {
+    return n * factorial(n-1);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/script.py b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/script.py
new file mode 100644
index 0000000..d6390c5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stderr.txt
new file mode 100644
index 0000000..c219105
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stderr.txt
@@ -0,0 +1,13 @@
+tests/sm/interprocedural/complex/input.c: In function 'h':
+tests/sm/interprocedural/complex/input.c:44:nn: error: dereference of NULL pointer r [CWE-690]
+tests/sm/interprocedural/complex/input.c:44:nn: note: dereference of NULL pointer r
+tests/sm/interprocedural/complex/input.c:44:nn: error: dereference of possibly-NULL pointer r [CWE-690]
+tests/sm/interprocedural/complex/input.c:44:nn: note: dereference of possibly-NULL pointer r
+tests/sm/interprocedural/complex/input.c:46:nn: error: double-free of r [CWE-415]
+tests/sm/interprocedural/complex/input.c:44:nn: note: dereference of r
+tests/sm/interprocedural/complex/input.c:38:nn: note: q passed to free()
+tests/sm/interprocedural/complex/input.c:46:nn: note: double-free of r
+tests/sm/interprocedural/complex/input.c:46:nn: error: use-after-free of r [CWE-416]
+tests/sm/interprocedural/complex/input.c:44:nn: note: dereference of r
+tests/sm/interprocedural/complex/input.c:38:nn: note: q passed to free()
+tests/sm/interprocedural/complex/input.c:46:nn: note: use-after-free of r
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/complex/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/input.c b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/input.c
new file mode 100644
index 0000000..062cf99
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/input.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+static void uses_ptr(int *q)
+{
+  /* BUG: ptr came from unchecked malloc in test() */
+  *q = 42;
+}
+
+int *test(void)
+{
+  int *p = (int*)malloc(sizeof(int));
+  uses_ptr(p);
+  return p;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/script.py b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/script.py
new file mode 100644
index 0000000..78a1740
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify that uses_ptr()'s "q" param  inherits "ptr.unchecked"
+    # from the argument "p"
+    node = ctxt.find_implementation_of('uses_ptr')
+    ctxt.assert_statenames_for_varname(node, 'q', {'ptr.unchecked'})
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], selftest=selftest)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stderr.txt
new file mode 100644
index 0000000..4f59744
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stderr.txt
@@ -0,0 +1,5 @@
+tests/sm/interprocedural/param-inherits-from-arg/input.c: In function 'uses_ptr':
+tests/sm/interprocedural/param-inherits-from-arg/input.c:26:nn: error: dereference of possibly-NULL pointer q [CWE-690]
+tests/sm/interprocedural/param-inherits-from-arg/input.c:31:nn: note: p assigned to the result of malloc()
+tests/sm/interprocedural/param-inherits-from-arg/input.c:32:nn: note: call from test() to uses_ptr(): state of p ("ptr.unchecked") propagated to q
+tests/sm/interprocedural/param-inherits-from-arg/input.c:26:nn: note: dereference of possibly-NULL pointer q
diff --git a/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/interprocedural/param-inherits-from-arg/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/json/input.c b/gcc/testsuite/gcc.dg/checker/sm/json/input.c
new file mode 100644
index 0000000..8234afa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/json/input.c
@@ -0,0 +1,27 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+int *test(int i)
+{
+  int *foo = (int*)malloc(sizeof(int*));
+  *foo = i; /* BUG: result of malloc could be NULL */
+  return foo;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/json/script.py b/gcc/testsuite/gcc.dg/checker/sm/json/script.py
new file mode 100644
index 0000000..281ccc9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/json/script.py
@@ -0,0 +1,104 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+###########################################################################
+# Selftest of JSON report dumping
+#
+# This is the same code and checker as:
+#    tests/sm/assignments/dereference-on-lhs
+# but with the output sent to JSON
+###########################################################################
+
+import glob
+import json
+
+from sm import main
+from sm.options import Options
+from sm.parser import parse_file
+
+def get_json_reports():
+    return glob.glob('tests/sm/json/input.c.*.sm.json')
+
+def delete_json_reports():
+    for jsonfile in get_json_reports():
+        os.unlink(jsonfile)
+
+def selftest(ctxt, solution):
+    if 0:
+        import sys
+        solution.dump(sys.stderr)
+
+    # Verify the JSON version of the report directly from the Error object:
+    assert len(ctxt._errors) == 1
+    err = ctxt._errors[0]
+    report = err.make_report(ctxt, solution)
+
+    jsonobj = report.as_json()
+    verify_json(jsonobj)
+    print('OK: verified in-memory JSON object')
+
+    # Verify that a JSON file was written and check its contents:
+    jsonfiles = get_json_reports()
+    assert len(jsonfiles) == 1
+    with open(jsonfiles[0], 'r') as f:
+        jsonobj = json.load(f)
+    verify_json(jsonobj)
+    print('OK: verified JSON object parsed from disk')
+
+    # On success, keep the directory clean:
+    if 1:
+        delete_json_reports()
+
+def verify_json(jsonobj):
+    if 0:
+        print(json.dumps(jsonobj,
+                         sort_keys=True,
+                         indent=4, separators=(',', ': ')))
+
+    # Verify jsonobj['cwe']:
+    assert jsonobj['cwe'] == 'CWE-690'
+
+    # Verify jsonobj['sm']:
+    assert jsonobj['sm']['name'] == 'malloc_checker'
+    assert jsonobj['sm']['filename'] == 'sm/checkers/malloc_checker.sm'
+    assert jsonobj['sm']['line'] == 23
+
+    # Verify jsonobj['loc']:
+    assert 'input.c' in jsonobj['loc']['actualfilename']
+    assert jsonobj['loc']['givenfilename'] == "tests/sm/json/input.c"
+    assert jsonobj['loc']['line'] == 25
+    assert jsonobj['loc']['column'] == 8
+
+    # Verify jsonobj['message']:
+    assert jsonobj['message'] == "dereference of possibly-NULL pointer foo"
+
+    # Verify jsonobj['notes']:
+    assert len(jsonobj['notes']) == 2
+    note = jsonobj['notes'][0]
+    assert jsonobj['loc']['givenfilename'] == "tests/sm/json/input.c"
+    assert note['loc']['line'] == 24
+    assert note['message'] == "foo assigned to the result of malloc()"
+
+# Preprocessing: remove any existing json error reports:
+delete_json_reports()
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker],
+     # Dump JSON files rather than writing to stderr:
+     options=Options(dump_json=True),
+     selftest=selftest, )
diff --git a/gcc/testsuite/gcc.dg/checker/sm/json/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/json/stdout.txt
new file mode 100644
index 0000000..ad3aa19
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/json/stdout.txt
@@ -0,0 +1,2 @@
+OK: verified in-memory JSON object
+OK: verified JSON object parsed from disk
diff --git a/gcc/testsuite/gcc.dg/checker/sm/looping/input.c b/gcc/testsuite/gcc.dg/checker/sm/looping/input.c
new file mode 100644
index 0000000..1bf8f6f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/looping/input.c
@@ -0,0 +1,36 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+void test(int c)
+{
+  int i;
+  char *buffer = (char*)malloc(256);
+
+  for (i=0; i<255; i++) {
+    buffer[i] = c; /* BUG: the malloc could have failed
+                    TODO: the checker doesn't yet pick up on this due to
+                    the pointer arithmetic not picking up on the state */
+                   /* BUG use-after-free the second time through the loop */
+
+    free(buffer); /* BUG: doublefree here on second time through the  loop */
+  }
+
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/looping/script.py b/gcc/testsuite/gcc.dg/checker/sm/looping/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/looping/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/looping/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/looping/stderr.txt
new file mode 100644
index 0000000..ce8212e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/looping/stderr.txt
@@ -0,0 +1,13 @@
+tests/sm/looping/input.c: In function 'test':
+tests/sm/looping/input.c:28:nn: error: use-after-free of buffer [CWE-416]
+tests/sm/looping/input.c:25:nn: note: buffer assigned to the result of malloc()
+tests/sm/looping/input.c:33:nn: note: buffer passed to free()
+tests/sm/looping/input.c:28:nn: note: use-after-free of buffer
+tests/sm/looping/input.c:33:nn: error: double-free of buffer [CWE-415]
+tests/sm/looping/input.c:25:nn: note: buffer assigned to the result of malloc()
+tests/sm/looping/input.c:33:nn: note: buffer passed to free()
+tests/sm/looping/input.c:33:nn: note: double-free of buffer
+tests/sm/looping/input.c:33:nn: error: use-after-free of buffer [CWE-416]
+tests/sm/looping/input.c:25:nn: note: buffer assigned to the result of malloc()
+tests/sm/looping/input.c:33:nn: note: buffer passed to free()
+tests/sm/looping/input.c:33:nn: note: use-after-free of buffer
diff --git a/gcc/testsuite/gcc.dg/checker/sm/looping/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/looping/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/input-f.c b/gcc/testsuite/gcc.dg/checker/sm/lto/input-f.c
new file mode 100644
index 0000000..3a2360c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/input-f.c
@@ -0,0 +1,34 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+
+void *f(int a)
+{
+  if (a) {
+    void *p = malloc(4096);
+    return p;
+  } else {
+    return NULL;
+  }
+}
+
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/input-g.c b/gcc/testsuite/gcc.dg/checker/sm/lto/input-g.c
new file mode 100644
index 0000000..816527d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/input-g.c
@@ -0,0 +1,31 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+
+void g(int b, void *q)
+{
+  if (b==2) {
+    g(b, q); /* contrived infinite recursion */
+  }
+  free(q);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/input-h.c b/gcc/testsuite/gcc.dg/checker/sm/lto/input-h.c
new file mode 100644
index 0000000..0ae7fd3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/input-h.c
@@ -0,0 +1,31 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "test.h"
+
+void h(int c)
+{
+  int *r = (int*)f(c);
+  r[0] = 42; /* BUG: the malloc in f could have failed */
+  g(c, r);
+  free(r); /* BUG: doublefree here, given that g frees the ptr */
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/script.py b/gcc/testsuite/gcc.dg/checker/sm/lto/script.py
new file mode 100644
index 0000000..e0cf5db
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/script.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.options import Options
+from sm.parser import parse_file
+
+opt = Options(during_lto=True)
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker], options=opt)
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/lto/stderr.txt
new file mode 100644
index 0000000..28afeb9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/stderr.txt
@@ -0,0 +1,29 @@
+tests/sm/lto/input-g.c: In function 'g':
+tests/sm/lto/input-g.c:30:7: error: double-free of q [CWE-415]
+tests/sm/lto/input-g.c:30:7: note: q passed to free()
+tests/sm/lto/input-g.c:28:6: note: return from g() to g()
+tests/sm/lto/input-g.c:30:7: note: double-free of q
+tests/sm/lto/input-g.c:30:7: error: use-after-free of q [CWE-416]
+tests/sm/lto/input-g.c:30:7: note: q passed to free()
+tests/sm/lto/input-g.c:28:6: note: return from g() to g()
+tests/sm/lto/input-g.c:30:7: note: use-after-free of q
+tests/sm/lto/input-h.c: In function 'h':
+tests/sm/lto/input-h.c:28:8: error: dereference of NULL pointer r [CWE-690]
+tests/sm/lto/input-f.c:31:5: note: return value assigned to 0
+tests/sm/lto/input-h.c:27:8: note: return from f() to h(): state of return value ("ptr.null") propagated to r
+tests/sm/lto/input-h.c:28:8: note: dereference of NULL pointer r
+tests/sm/lto/input-h.c:28:8: error: dereference of possibly-NULL pointer r [CWE-690]
+tests/sm/lto/input-f.c:28:11: note: p assigned to the result of malloc()
+tests/sm/lto/input-h.c:27:8: note: return from f() to h(): state of return value ("ptr.unchecked") propagated to r
+tests/sm/lto/input-h.c:28:8: note: dereference of possibly-NULL pointer r
+tests/sm/lto/input-h.c:30:7: error: double-free of r [CWE-415]
+tests/sm/lto/input-g.c:30:7: note: q passed to free()
+tests/sm/lto/input-h.c:29:4: note: return from g() to h(): state of q ("ptr.free") propagated to r
+tests/sm/lto/input-h.c:30:7: note: double-free of r
+tests/sm/lto/input-h.c:30:7: error: use-after-free of r [CWE-416]
+tests/sm/lto/input-g.c:30:7: note: q passed to free()
+tests/sm/lto/input-h.c:29:4: note: return from g() to h(): state of q ("ptr.free") propagated to r
+tests/sm/lto/input-h.c:30:7: note: use-after-free of r
+lto-wrapper: gcc returned 1 exit status
+/usr/bin/ld: lto-wrapper failed
+collect2: error: ld returned 1 exit status
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/lto/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/lto/test.h b/gcc/testsuite/gcc.dg/checker/sm/lto/test.h
new file mode 100644
index 0000000..f5825c8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/lto/test.h
@@ -0,0 +1,22 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void *f(int a);
+extern void g(int b, void *q);
+extern void h(int c);
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c
new file mode 100644
index 0000000..aafcadd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c
@@ -0,0 +1,91 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+#include <string.h>
+
+#if 1
+void double_free(void *ptr)
+{
+  free(ptr);
+
+  /* BUG: double-free: */
+  free(ptr);
+}
+#endif
+
+
+#if 1
+void unchecked_malloc(void)
+{
+  void *ptr = malloc(4096);
+  memset(ptr, 0, 4096);
+}
+#endif
+
+#if 1
+int correct_usage(void)
+{
+  void *ptr = malloc(4096);
+  if (!ptr)
+    return -1; /* FIXME: with a plain return we have a BB with no gimple, and that breaks my checker */
+  memset(ptr, 0, 4096);
+  free(ptr);
+  return 0;
+}
+#endif
+
+#if 1
+int two_ptrs(void)
+{
+  void *p = malloc(4096);
+  void *q = malloc(4096);
+  if (p) {
+    memset(p, 0, 4096); /* Not a bug: checked */
+  } else {
+    memset(q, 0, 4096); /* BUG: not checked */
+  }
+  free(p);
+  free(q);
+  return 0;
+}
+#endif
+
+#if 1
+void fancy_control_flow(int i, int j)
+{
+  int k;
+  void *ptr;
+  for (k = i; k < j; k++) {
+    switch(k) {
+    case 0:
+      ptr = malloc(1024);
+      break;
+    case 1:
+      break;
+    case 2:
+      break;
+    default:
+      break;
+    }
+  }
+  memset(ptr, 0, 4096);
+  free(ptr);
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/metadata.ini b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/metadata.ini
new file mode 100644
index 0000000..ba7428c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/metadata.ini
@@ -0,0 +1,4 @@
+[ExpectedBehavior]
+# This test case emits warnings on stderr;
+# don't treat the stderr output as leading to an expected failure:
+exitcode = 0
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/script.py b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/script.py
new file mode 100644
index 0000000..a75230a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/script.py
@@ -0,0 +1,189 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+import unittest
+
+from sm.checker import Checker, Sm, AnyPointer, StateClause, PatternRule, \
+    ResultOfFnCall, ArgsOfFnCall, Comparison, VarDereference, VarUsage, \
+    TransitionTo, BooleanOutcome, PythonOutcome
+from sm.parser import parse_string
+
+#parse('tests/sm/parser/malloc-checker.sm')
+
+class ParserTests(unittest.TestCase):
+    def test_complex_example(self):
+        ch = parse_string('''
+sm malloc_checker {
+  stateful decl any_pointer ptr;
+
+  ptr.all:
+    { ptr = malloc() } =>  ptr.unknown;
+
+  ptr.unknown, ptr.null, ptr.nonnull:
+      { ptr == 0 } => true=ptr.null, false=ptr.nonnull
+    | { ptr != 0 } => true=ptr.nonnull, false=ptr.null
+    ;
+
+  ptr.unknown:
+    { *ptr } => {{ error('use of possibly-NULL pointer %s' % ptr) }};
+
+  ptr.null:
+    { *ptr } => {{ error('use of NULL pointer %s' % ptr) }};
+
+  ptr.all, ptr.unknown, ptr.null, ptr.nonnull:
+    { free(ptr) } => ptr.free;
+
+  ptr.free:
+      { free(ptr) } => {{ error('double-free of %s' % ptr) }}
+    | { ptr } => {{ error('use-after-free of %s' % ptr) }}
+    ;
+}
+''')
+        self.assert_(isinstance(ch, Checker))
+
+        # Verify that the str() of the parsed Checker looks sane:
+        self.assertEqual(str(ch).splitlines(),
+'''sm malloc_checker {
+  stateful decl any_pointer ptr;
+
+  ptr.all:
+    { ptr = malloc() } => ptr.unknown;
+
+  ptr.unknown, ptr.null, ptr.nonnull:
+    { ptr == 0 } => true=ptr.null, false=ptr.nonnull;
+    | { ptr != 0 } => true=ptr.nonnull, false=ptr.null;
+
+  ptr.unknown:
+    { *ptr } => {{ error('use of possibly-NULL pointer %s' % ptr) }};
+
+  ptr.null:
+    { *ptr } => {{ error('use of NULL pointer %s' % ptr) }};
+
+  ptr.all, ptr.unknown, ptr.null, ptr.nonnull:
+    { free(ptr) }  => ptr.free;
+
+  ptr.free:
+    { free(ptr) }  => {{ error('double-free of %s' % ptr) }};
+    | { ptr } => {{ error('use-after-free of %s' % ptr) }};
+
+}'''.splitlines())
+
+        self.assertEqual(len(ch.sms), 1)
+        sm = ch.sms[0]
+        self.assertEqual(sm.name, 'malloc_checker')
+        self.assertEqual(len(sm.clauses), 7)
+
+        decl = sm.clauses[0]
+        self.assertEqual(decl, AnyPointer(has_state=True, name='ptr'))
+
+        # Verify parsing of:
+        #   ptr.all:
+        #     { ptr = malloc() } =>  ptr.unknown;
+        sc = sm.clauses[1]
+        self.assertEqual(sc.statelist, ['ptr.all'])
+        self.assertEqual(len(sc.patternrulelist), 1)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern,
+                         ResultOfFnCall(lhs='ptr',
+                                        fnname='malloc',
+                                        args=[]))
+        self.assertEqual(pr.outcomes,
+                         [TransitionTo(statename='ptr.unknown')])
+
+        # Verify parsing of:
+        #   ptr.unknown, ptr.null, ptr.nonnull:
+        #       { ptr == 0 } => true=ptr.null, false=ptr.nonnull
+        #     | { ptr != 0 } => true=ptr.nonnull, false=ptr.null
+        #     ;
+        sc = sm.clauses[2]
+        self.assertEqual(sc.statelist,
+                         ['ptr.unknown', 'ptr.null', 'ptr.nonnull'])
+        self.assertEqual(len(sc.patternrulelist), 2)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern, Comparison(lhs='ptr', op='==', rhs=0))
+        self.assertEqual(pr.outcomes,
+                         [BooleanOutcome(guard=True, outcome=TransitionTo(statename='ptr.null')),
+                          BooleanOutcome(guard=False, outcome=TransitionTo(statename='ptr.nonnull'))])
+        pr = sc.patternrulelist[1]
+        self.assertEqual(pr.pattern, Comparison(lhs='ptr', op='!=', rhs=0))
+        self.assertEqual(pr.outcomes,
+                         [BooleanOutcome(guard=True, outcome=TransitionTo(statename='ptr.nonnull')),
+                          BooleanOutcome(guard=False, outcome=TransitionTo(statename='ptr.null'))])
+
+
+        # Verify parsing of:
+        #   ptr.unknown:
+        #     { *ptr } => {{ error('use of possibly-NULL pointer %s' % ptr) }};
+        sc = sm.clauses[3]
+        self.assertEqual(sc.statelist,
+                         ['ptr.unknown'])
+        self.assertEqual(len(sc.patternrulelist), 1)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern, VarDereference(var='ptr'))
+        self.assertEqual(pr.outcomes,
+                         [PythonOutcome(src=(" error('use of possibly-NULL pointer %s' % ptr) "),
+                                        lineoffset=13)])
+
+        # Verify parsing of:
+        #   ptr.null:
+        #     { *ptr } => {{ error('use of NULL pointer %s' % ptr) }};
+        sc = sm.clauses[4]
+        self.assertEqual(sc.statelist,
+                         ['ptr.null'])
+        self.assertEqual(len(sc.patternrulelist), 1)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern, VarDereference(var='ptr'))
+        self.assertEqual(pr.outcomes,
+                         [PythonOutcome(src=(" error('use of NULL pointer %s' % ptr) "),
+                                        lineoffset=16)])
+
+        # Verify parsing of:
+        #   ptr.all, ptr.unknown, ptr.null, ptr.nonnull:
+        #     { free(ptr) } => ptr.free;
+        sc = sm.clauses[5]
+        self.assertEqual(sc.statelist,
+                         ['ptr.all', 'ptr.unknown', 'ptr.null', 'ptr.nonnull'])
+        self.assertEqual(len(sc.patternrulelist), 1)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern, ArgsOfFnCall(fnname='free', args=['ptr']))
+        self.assertEqual(pr.outcomes,
+                         [TransitionTo(statename='ptr.free')])
+
+        # Verify parsing of:
+        #   ptr.free:
+        #     { free(ptr) } => {{ error('double-free of %s' % ptr) }}
+        #     | { ptr } => {{ error('use-after-free of %s' % ptr) }}
+        sc = sm.clauses[6]
+        self.assertEqual(sc.statelist,
+                         ['ptr.free'])
+        self.assertEqual(len(sc.patternrulelist), 2)
+        pr = sc.patternrulelist[0]
+        self.assertEqual(pr.pattern, ArgsOfFnCall(fnname='free', args=['ptr']))
+        self.assertEqual(pr.outcomes,
+                         [PythonOutcome(src=" error('double-free of %s' % ptr) ",
+                                        lineoffset=22)])
+        pr = sc.patternrulelist[1]
+        self.assertEqual(pr.pattern, VarUsage(var='ptr'))
+        self.assertEqual(pr.outcomes,
+                         [PythonOutcome(src=" error('use-after-free of %s' % ptr) ",
+                                        lineoffset=23)])
+
+import sys
+sys.argv = ['foo', '-v']
+
+unittest.main()
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stderr.txt
new file mode 100644
index 0000000..eb60ae5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stderr.txt
@@ -0,0 +1,6 @@
+test_complex_example (__main__.ParserTests) ... ok
+
+----------------------------------------------------------------------
+Ran 1 test in #s
+
+OK
diff --git a/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/parser/malloc-checker/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c
new file mode 100644
index 0000000..04a6880
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c
@@ -0,0 +1,25 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void test2(void *);
+
+void test1(void *ptr)
+{
+  test2(ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/script.py
new file mode 100644
index 0000000..b9f41c2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/script.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm arg_of_fn_call {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { test2(ptr) } => {{ error('test2() was called with %s' % ptr) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stderr.txt
new file mode 100644
index 0000000..1c2cba2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/arg-of-fn-call/input.c: In function 'test1':
+tests/sm/patterns/arg-of-fn-call/input.c:24:nn: error: test2() was called with ptr
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg-of-fn-call/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/input.c
new file mode 100644
index 0000000..fdef90c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/input.c
@@ -0,0 +1,44 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdlib.h>
+
+extern void foo(void *ptrA, void *ptrB, void *ptrC)
+  __attribute__((nonnull (1, 3)));
+
+extern void bar(void *ptrA, void *ptrB, void *ptrC)
+  __attribute__((nonnull (1, 3)));
+
+void foo(void *ptrA, void *ptrB, void *ptrC)
+{
+}
+
+void test(void)
+{
+  void *p;
+  void *q;
+  void *r;
+
+  p = NULL;
+  q = NULL;
+  r = NULL;
+
+  foo(p, q, r);
+  bar(p, q, r);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/script.py
new file mode 100644
index 0000000..a270eb0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/script.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm example_usage_of_nonnull_arg {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { ptr = 0 } => ptr.null;
+
+  ptr.null:
+    $arg_must_not_be_null$
+      => {{
+            error('%s() was called with NULL %s as argument %i/index %i: %r'
+                  % (function, ptr, argnumber, argindex, parameter))
+         }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stderr.txt
new file mode 100644
index 0000000..554a1aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stderr.txt
@@ -0,0 +1,21 @@
+tests/sm/patterns/arg_must_not_be_null/input.c: In function 'test':
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: error: foo() was called with NULL p as argument 1/index 0: gcc.ParmDecl('ptrA')
+tests/sm/patterns/arg_must_not_be_null/input.c:38:nn: note: p assigned to 0
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: call from test() to foo(): state of p ("ptr.null") propagated to ptrA
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: return from foo() to test(): state of ptrA ("ptr.null") propagated to p
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: foo() was called with NULL p as argument 1/index 0: gcc.ParmDecl('ptrA')
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: error: foo() was called with NULL r as argument 3/index 2: gcc.ParmDecl('ptrC')
+tests/sm/patterns/arg_must_not_be_null/input.c:40:nn: note: r assigned to 0
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: call from test() to foo(): state of p ("ptr.null") propagated to ptrC
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: return from foo() to test(): state of ptrC ("ptr.null") propagated to r
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: foo() was called with NULL r as argument 3/index 2: gcc.ParmDecl('ptrC')
+tests/sm/patterns/arg_must_not_be_null/input.c:43:nn: error: bar() was called with NULL p as argument 1/index 0: None
+tests/sm/patterns/arg_must_not_be_null/input.c:40:nn: note: r assigned to 0
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: call from test() to foo(): state of p ("ptr.null") propagated to ptrA
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: return from foo() to test(): state of ptrA ("ptr.null") propagated to p
+tests/sm/patterns/arg_must_not_be_null/input.c:43:nn: note: bar() was called with NULL p as argument 1/index 0: None
+tests/sm/patterns/arg_must_not_be_null/input.c:43:nn: error: bar() was called with NULL r as argument 3/index 2: None
+tests/sm/patterns/arg_must_not_be_null/input.c:39:nn: note: q assigned to 0
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: call from test() to foo(): state of p ("ptr.null") propagated to ptrC
+tests/sm/patterns/arg_must_not_be_null/input.c:42:nn: note: return from foo() to test(): state of ptrC ("ptr.null") propagated to r
+tests/sm/patterns/arg_must_not_be_null/input.c:43:nn: note: bar() was called with NULL r as argument 3/index 2: None
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/arg_must_not_be_null/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/input.c
new file mode 100644
index 0000000..6c912b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/input.c
@@ -0,0 +1,25 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void test2(void *param0, int param1, char param2);
+
+void test1(void *ptr, int i)
+{
+  test2(ptr, 0, 'A');
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/script.py
new file mode 100644
index 0000000..691e9a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/script.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm arg_of_fn_call {
+  stateful decl any_pointer arg0;
+  decl any_expr arg1;
+  decl any_expr arg2;
+
+  arg0.*:
+    { test2(arg0, arg1, arg2) } => {{ error('test2() was called with arg0:%s arg1:%s arg2:%s' % (arg0, arg1, arg2)) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stderr.txt
new file mode 100644
index 0000000..798cb97
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/args-of-fn-call/input.c: In function 'test1':
+tests/sm/patterns/args-of-fn-call/input.c:24:nn: error: test2() was called with arg0:ptr arg1:0 arg2:65
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/args-of-fn-call/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/array/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/input.c
new file mode 100644
index 0000000..6ce27ac
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/input.c
@@ -0,0 +1,25 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+void test1(void)
+{
+  char buf[256];
+
+  buf[0] = 42;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/array/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/script.py
new file mode 100644
index 0000000..4f72951
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/script.py
@@ -0,0 +1,33 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm array_access {
+  decl any_expr idx;
+  stateful decl any_expr arr;
+
+  arr.*:
+    { arr[idx] } => {{ error('lookup within array "%s" at index %s' % (arr, idx)) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/array/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/stderr.txt
new file mode 100644
index 0000000..ff30854
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/array/input.c: In function 'test1':
+tests/sm/patterns/array/input.c:24:nn: error: lookup within array "buf" at index 0
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/array/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/array/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c
new file mode 100644
index 0000000..a6f25ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c
@@ -0,0 +1,30 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void foo(void *);
+extern void bar(void *);
+
+void test1(void *ptr)
+{
+  if (ptr) {
+    foo(ptr);
+  } else {
+    bar(ptr);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/script.py
new file mode 100644
index 0000000..696d51a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/script.py
@@ -0,0 +1,35 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm checked_against_null {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { ptr != 0 } => {{ error('%s was checked against NULL' % ptr) }};
+}
+'''
+
+# TODO: this currently emits the warning for both the true and the false path
+# from the conditional, rather than just once.
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stderr.txt
new file mode 100644
index 0000000..546bf95
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/conditional/input.c: In function 'test1':
+tests/sm/patterns/conditional/input.c:25:nn: error: ptr was checked against NULL
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/conditional/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/input.c
new file mode 100644
index 0000000..a6f25ed
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/input.c
@@ -0,0 +1,30 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void foo(void *);
+extern void bar(void *);
+
+void test1(void *ptr)
+{
+  if (ptr) {
+    foo(ptr);
+  } else {
+    bar(ptr);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/script.py
new file mode 100644
index 0000000..63b19b7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/script.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm checked_against_null {
+  stateful decl any_pointer ptr;
+
+  pat checked_against_null { ptr != 0 };
+
+  ptr.*:
+    checked_against_null => {{ error('%s was checked against NULL' % ptr) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stderr.txt
new file mode 100644
index 0000000..4802151
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/named-pattern/input.c: In function 'test1':
+tests/sm/patterns/named-pattern/input.c:25:nn: error: ptr was checked against NULL
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/named-pattern/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/or/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/input.c
new file mode 100644
index 0000000..bb9c38c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/input.c
@@ -0,0 +1,39 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void foo(void *);
+extern void bar(void *);
+
+void test1(void *ptr)
+{
+  if (ptr) {
+    foo(ptr);
+  } else {
+    bar(ptr);
+  }
+}
+
+void test2(void *ptr)
+{
+  if (!ptr) {
+    foo(ptr);
+  } else {
+    bar(ptr);
+  }
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/or/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/script.py
new file mode 100644
index 0000000..833ef78
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/script.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm checked_against_null {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { ptr != 0 } | {ptr == 0 } => {{ error('%s was checked against NULL' % ptr) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/or/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/stderr.txt
new file mode 100644
index 0000000..2eb5619
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/patterns/or/input.c: In function 'test1':
+tests/sm/patterns/or/input.c:25:nn: error: ptr was checked against NULL
+tests/sm/patterns/or/input.c: In function 'test2':
+tests/sm/patterns/or/input.c:34:nn: error: ptr was checked against NULL
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/or/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/or/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c
new file mode 100644
index 0000000..b39c880
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c
@@ -0,0 +1,30 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+extern void *never_call_this(void);
+
+void test1(void)
+{
+  void *ptr = never_call_this();
+}
+
+void test2(void)
+{
+  /* empty */
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/script.py
new file mode 100644
index 0000000..eea7ef8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/script.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm result_of_fn_call {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { ptr = never_call_this() } => {{ error('never_call_this was called %s' % ptr) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stderr.txt
new file mode 100644
index 0000000..ff49839
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stderr.txt
@@ -0,0 +1,2 @@
+tests/sm/patterns/result-of-fn-call/input.c: In function 'test1':
+tests/sm/patterns/result-of-fn-call/input.c:24:nn: error: never_call_this was called ptr
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/result-of-fn-call/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c
new file mode 100644
index 0000000..346f675
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c
@@ -0,0 +1,32 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+int test1(int *p)
+{
+  return *p;
+}
+
+struct foo {
+  int i;
+};
+
+int test2(struct foo *f)
+{
+  return f->i;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/script.py
new file mode 100644
index 0000000..4e29c27
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/script.py
@@ -0,0 +1,32 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm var_dereference {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { *ptr } => {{ error('%s was dereferenced' % ptr) }};
+}
+'''
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stderr.txt
new file mode 100644
index 0000000..65da25e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stderr.txt
@@ -0,0 +1,4 @@
+tests/sm/patterns/var-dereference/input.c: In function 'test1':
+tests/sm/patterns/var-dereference/input.c:22:nn: error: p was dereferenced
+tests/sm/patterns/var-dereference/input.c: In function 'test2':
+tests/sm/patterns/var-dereference/input.c:31:nn: error: f was dereferenced
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-dereference/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c
new file mode 100644
index 0000000..3518530
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c
@@ -0,0 +1,23 @@
+/*
+   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+   Copyright 2012 Red Hat, Inc.
+
+   This is free software: you can redistribute it and/or modify it
+   under the terms of the GNU General Public License as published by
+   the Free Software Foundation, either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see
+   <http://www.gnu.org/licenses/>.
+*/
+
+void *test1(void *ptr)
+{
+  return ptr;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.cpychecker-log.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.cpychecker-log.txt
new file mode 100644
index 0000000..7499d84
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.cpychecker-log.txt
@@ -0,0 +1 @@
+gcc.Function('test')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
new file mode 100644
index 0000000..b92b8e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/input.c.test_read_through_uninitialized_pointer-refcount-errors.html
@@ -0,0 +1,175 @@
+<html>
+  <head>
+    <title>test_read_through_uninitialized_pointer</title>
+    <style type="text/css">
+.unreached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-line {
+    #margin:1em;
+    #border:0.1em dotted #00aa00;
+    border: 0.1em solid blue;
+    font-weight: bold;
+
+    opacity:1.0;
+    filter:alpha(opacity=0);
+    #color:black;
+}
+
+.reached-lineno {
+    border: 0.1em solid blue;
+    font-weight: bold;
+}
+
+pre {
+    #line-height:200%
+}
+
+._jsPlumb_connector { z-index: -2; }
+._jsPlumb_endpoint { z-index: -1; }
+
+.transition {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.error {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #cc0000;
+    -moz-box-shadow: 2px 2px 2px #cc0000;
+    -webkit-box-shadow: 2px 2px 2px #cc0000;
+    box-shadow: 2px 2px 2px #cc0000;
+    margin-left: 5em;
+    color: red;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.note {
+    #border: 0.1em dotted #ddffdd;
+    #padding: 1em;
+    border: 0.1em solid #ccc;
+    -moz-box-shadow: 2px 2px 2px #ccc;
+    -webkit-box-shadow: 2px 2px 2px #ccc;
+    box-shadow: 2px 2px 2px #ccc;
+    margin-left: 5em;
+    font-family: proportional;
+    font-weight: bold;
+    font-style: italic;
+    font-size: 90%;
+}
+
+.hll { background-color: #ffffcc }
+.source_c { color: #408080; font-style: italic } /* Comment */
+.source_err { border: 1px solid #FF0000 } /* Error */
+.source_k { color: #008000; font-weight: bold } /* Keyword */
+.source_o { color: #666666 } /* Operator */
+.source_cm { color: #408080; font-style: italic } /* Comment.Multiline */
+.source_cp { color: #BC7A00 } /* Comment.Preproc */
+.source_c1 { color: #408080; font-style: italic } /* Comment.Single */
+.source_cs { color: #408080; font-style: italic } /* Comment.Special */
+.source_gd { color: #A00000 } /* Generic.Deleted */
+.source_ge { font-style: italic } /* Generic.Emph */
+.source_gr { color: #FF0000 } /* Generic.Error */
+.source_gh { color: #000080; font-weight: bold } /* Generic.Heading */
+.source_gi { color: #00A000 } /* Generic.Inserted */
+.source_go { color: #808080 } /* Generic.Output */
+.source_gp { color: #000080; font-weight: bold } /* Generic.Prompt */
+.source_gs { font-weight: bold } /* Generic.Strong */
+.source_gu { color: #800080; font-weight: bold } /* Generic.Subheading */
+.source_gt { color: #0040D0 } /* Generic.Traceback */
+.source_kc { color: #008000; font-weight: bold } /* Keyword.Constant */
+.source_kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
+.source_kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
+.source_kp { color: #008000 } /* Keyword.Pseudo */
+.source_kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
+.source_kt { color: #B00040 } /* Keyword.Type */
+.source_m { color: #666666 } /* Literal.Number */
+.source_s { color: #BA2121 } /* Literal.String */
+.source_na { color: #7D9029 } /* Name.Attribute */
+.source_nb { color: #008000 } /* Name.Builtin */
+.source_nc { color: #0000FF; font-weight: bold } /* Name.Class */
+.source_no { color: #880000 } /* Name.Constant */
+.source_nd { color: #AA22FF } /* Name.Decorator */
+.source_ni { color: #999999; font-weight: bold } /* Name.Entity */
+.source_ne { color: #D2413A; font-weight: bold } /* Name.Exception */
+.source_nf { color: #0000FF } /* Name.Function */
+.source_nl { color: #A0A000 } /* Name.Label */
+.source_nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
+.source_nt { color: #008000; font-weight: bold } /* Name.Tag */
+.source_nv { color: #19177C } /* Name.Variable */
+.source_ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
+.source_w { color: #bbbbbb } /* Text.Whitespace */
+.source_mf { color: #666666 } /* Literal.Number.Float */
+.source_mh { color: #666666 } /* Literal.Number.Hex */
+.source_mi { color: #666666 } /* Literal.Number.Integer */
+.source_mo { color: #666666 } /* Literal.Number.Oct */
+.source_sb { color: #BA2121 } /* Literal.String.Backtick */
+.source_sc { color: #BA2121 } /* Literal.String.Char */
+.source_sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
+.source_s2 { color: #BA2121 } /* Literal.String.Double */
+.source_se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
+.source_sh { color: #BA2121 } /* Literal.String.Heredoc */
+.source_si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
+.source_sx { color: #008000 } /* Literal.String.Other */
+.source_sr { color: #BB6688 } /* Literal.String.Regex */
+.source_s1 { color: #BA2121 } /* Literal.String.Single */
+.source_ss { color: #19177C } /* Literal.String.Symbol */
+.source_bp { color: #008000 } /* Name.Builtin.Pseudo */
+.source_vc { color: #19177C } /* Name.Variable.Class */
+.source_vg { color: #19177C } /* Name.Variable.Global */
+.source_vi { color: #19177C } /* Name.Variable.Instance */
+.source_il { color: #666666 } /* Literal.Number.Integer.Long */    </style>
+  </head>
+  <body>
+<script type="text/javascript" src="http://explorercanvas.googlecode.com/svn/trunk/excanvas.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
+<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.13/jquery-ui.min.js"></script>
+<script type="text/javascript" src="http://jsplumb.googlecode.com/files/jquery.jsPlumb-1.2.6-all-min.js"></script>
+<div id="report-0">
+<table>
+  <tr><td>File:</td> <td><b>tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c</b></td></tr>
+  <tr><td>Function:</td> <td><b>test_read_through_uninitialized_pointer</b></td></tr>
+  <tr><td>Error:</td> <td><b>dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</b></td></tr>
+</table>
+<div class="highlight"><pre><span class="lineno">30</span> <span id="trace0-line30" class="unreached-line"><span class="source_kt">int</span> <span class="source_nf">test_read_through_uninitialized_pointer</span><span class="source_p">(</span><span class="source_kt">void</span><span class="source_p">)</span></span>
+<span class="lineno">31</span> <span id="trace0-line31" class="unreached-line"><span class="source_p">{</span></span>
+<span class="lineno">32</span> <span id="trace0-line32" class="unreached-line">    <span class="source_k">struct</span> <span class="source_n">coord</span> <span class="source_o">*</span><span class="source_n">coord_ptr</span><span class="source_p">;</span></span>
+<span class="lineno">33</span> <span id="trace0-line33" class="unreached-line"></span>
+<span class="lineno">34</span> <span id="trace0-line34" class="unreached-line">    <span class="source_k">return</span> <span class="source_n">coord_ptr</span><span class="source_o">-&gt;</span><span class="source_n">x</span><span class="source_p">;</span></span>
+<span class="reached-lineno">35</span> <span id="trace0-line35" class="reached-line"><span class="source_p">}</span></span>
+<span class="error">dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35</span>
+<span class="lineno">36</span> <span id="trace0-line36" class="unreached-line"></pre></div></span>
+</pre></div>
+
+<script type="text/javascript">
+  jsPlumb.bind("ready", function() {
+    /* Set up defaults: */
+    jsPlumb.Defaults.Connector = [ "Bezier", 1 ];
+    jsPlumb.Defaults.Connector = [ "Straight" ];
+    jsPlumb.Defaults.PaintStyle = { strokeStyle:"blue", lineWidth:1 };
+    jsPlumb.Defaults.EndpointStyle = { radius:2, fillStyle:"red" };
+    jsPlumb.Defaults.Anchors =  [ "BottomCenter", "TopCenter" ];
+
+    /* Add lines: */
+  })
+</script>
+<hr/></div>
+  </body>
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/script.py b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/script.py
new file mode 100644
index 0000000..013cf5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/script.py
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_string
+
+SCRIPT = '''
+sm result_of_fn_call {
+  stateful decl any_pointer ptr;
+
+  ptr.*:
+    { ptr } => {{ error('%s was used' % ptr) }};
+}
+'''
+
+# TODO: for now this picks up on uses of temporaries
+
+checker = parse_string(SCRIPT)
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stderr.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stderr.txt
new file mode 100644
index 0000000..f253b50
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stderr.txt
@@ -0,0 +1,3 @@
+tests/sm/patterns/var-usage/input.c: In function 'test1':
+tests/sm/patterns/var-usage/input.c:22:nn: error: ptr was used
+tests/sm/patterns/var-usage/input.c:22:nn: error: return value was used
diff --git a/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/patterns/var-usage/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/getopts.py b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/getopts.py
new file mode 100644
index 0000000..6803180
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/getopts.py
@@ -0,0 +1 @@
+print('-fexceptions')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/input.c b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/input.c
new file mode 100644
index 0000000..f5711bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/input.c
@@ -0,0 +1,14 @@
+/*
+   Taken from autoconf test
+*/
+
+#include <stdio.h>
+int
+main ()
+{
+  FILE *f = fopen ("conftest.out", "w");
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/script.py b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-with-exceptions/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/getopts.py b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/getopts.py
new file mode 100644
index 0000000..964cadd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/getopts.py
@@ -0,0 +1 @@
+print('-O2')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/input.c b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/input.c
new file mode 100644
index 0000000..f5711bf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/input.c
@@ -0,0 +1,14 @@
+/*
+   Taken from autoconf test
+*/
+
+#include <stdio.h>
+int
+main ()
+{
+  FILE *f = fopen ("conftest.out", "w");
+  return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/script.py b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/regression/configure-without-exceptions/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/getopts.py b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/getopts.py
new file mode 100644
index 0000000..1584aa4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/getopts.py
@@ -0,0 +1,17 @@
+print('-O2')
+
+# With optimization, the whole of test() goes away, and hence we get no error
+# message
+#
+# Specifically, what's happening is dead-code elimination (the "cddce" pass
+# in tree-ssa-dce.c)
+# Invoking gcc with -fdump-tree-all-details shows this within input.c.031t.cddce1:
+#   Eliminating unnecessary statements:
+#   Deleting : free (ptr_1);
+#
+#   Deleting : free (ptr_1);
+#
+#   Deleting : ptr_1 = malloc (512);
+#
+# and the whole of the function has been optimized away before the analysis
+# pass sees it
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/input.c b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/input.c
new file mode 100644
index 0000000..384ae24
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/input.c
@@ -0,0 +1,9 @@
+#include <stdlib.h>
+
+void test(void)
+{
+    void *ptr = malloc(512);
+    free(ptr);
+    /* BUG: this is a double-free: */
+    free(ptr);
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/script.py b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/regression/optimization/dead-code-elimination/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/getopts.py b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/getopts.py
new file mode 100644
index 0000000..8dd3ec3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/getopts.py
@@ -0,0 +1,23 @@
+"""
+Seeing this error:
+
+    tests/sm/regression/return-0/input.c:4:3: error: Unhandled Python exception raised calling 'execute' method
+    Traceback (most recent call last):
+      File "sm/__init__.py", line 53, in execute
+        solve(ctxt, 'solution')
+      File "sm/solver.py", line 586, in solve
+        solution = ctxt.solve(name)
+      File "sm/solver.py", line 544, in solve
+        find_leaks(self)
+      File "sm/leaks.py", line 59, in find_leaks
+        retval_aliases = get_retval_aliases(ctxt, edge.dstnode)
+      File "sm/leaks.py", line 33, in get_retval_aliases
+        retval = retval.var
+    AttributeError: 'gcc.IntegerCst' object has no attribute 'var'
+with:
+  -O2
+
+With optimization, the return statement directly returns a constant, rather
+than a temporary.
+"""
+print('-O2')
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/input.c b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/input.c
new file mode 100644
index 0000000..115ae04
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/input.c
@@ -0,0 +1,4 @@
+int test(void)
+{
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/script.py b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/regression/return-0/stdout.txt
new file mode 100644
index 0000000..e69de29
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/input.c b/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/input.c
new file mode 100644
index 0000000..37458de
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/input.c
@@ -0,0 +1,8 @@
+extern const char *char_ptr;
+
+int test(void)
+{
+  if (strcmp("literal", char_ptr))
+    return 1;
+  return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/script.py b/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/script.py
new file mode 100644
index 0000000..f5439a2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/script.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+#   Copyright 2012, 2013 David Malcolm <dmalcolm@redhat.com>
+#   Copyright 2012, 2013 Red Hat, Inc.
+#
+#   This is free software: you can redistribute it and/or modify it
+#   under the terms of the GNU General Public License as published by
+#   the Free Software Foundation, either version 3 of the License, or
+#   (at your option) any later version.
+#
+#   This program is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU General Public License
+#   along with this program.  If not, see
+#   <http://www.gnu.org/licenses/>.
+
+from sm import main
+from sm.parser import parse_file
+
+checker = parse_file('sm/checkers/malloc_checker.sm')
+main([checker])
diff --git a/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/stdout.txt b/gcc/testsuite/gcc.dg/checker/sm/regression/rhs-is-vardecl/stdout.txt
new file mode 100644
index 0000000..e69de29
-- 
1.8.5.3

