commit 930cb5aad48713c6ac0fae46e4761fd87e9a79c4 Author: David Malcolm dmalcolm@redhat.com Date: Thu Sep 1 16:50:08 2011 -0400
cpychecker: complain about deferences of uninitialized pointers
libcpychecker/absinterp.py | 15 +++++++ .../read-through-uninitialized-ptr/input.c | 44 ++++++++++++++++++++ .../read-through-uninitialized-ptr/script.py | 23 ++++++++++ .../read-through-uninitialized-ptr/stderr.txt | 3 + .../read-through-uninitialized-ptr/stdout.txt | 6 +++ 5 files changed, 91 insertions(+), 0 deletions(-) --- diff --git a/libcpychecker/absinterp.py b/libcpychecker/absinterp.py index 0c3eef6..2f8bbf7 100644 --- a/libcpychecker/absinterp.py +++ b/libcpychecker/absinterp.py @@ -161,6 +161,17 @@ class PredictedValueError(PredictedError): self.value = value self.isdefinite = isdefinite
+class UninitializedPtrDereference(PredictedValueError): + def __init__(self, state, expr, ptr): + check_isinstance(state, State) + check_isinstance(expr, gcc.Tree) + check_isinstance(ptr, AbstractValue) + PredictedValueError.__init__(self, state, expr, ptr, True) + + def __str__(self): + return ('dereferencing uninitialized pointer (%s) at %s' + % (self.expr, self.state.loc.get_stmt().loc)) + class NullPtrDereference(PredictedValueError): def __init__(self, state, expr, ptr, isdefinite): check_isinstance(state, State) @@ -832,6 +843,10 @@ class State: def raise_any_null_ptr_deref(self, expr, ptr): check_isinstance(expr, gcc.Tree) check_isinstance(ptr, AbstractValue) + + if isinstance(ptr, UninitializedData): + raise UninitializedPtrDereference(self, expr, ptr) + if isinstance(ptr, ConcreteValue): if ptr.is_null_ptr(): # Read through NULL diff --git a/tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c new file mode 100644 index 0000000..eaec5da --- /dev/null +++ b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c @@ -0,0 +1,44 @@ +/* + Copyright 2011 David Malcolm dmalcolm@redhat.com + Copyright 2011 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 <Python.h> + +/* + Ensure that the checker complains about reads through uninitialized + pointers +*/ +struct coord { + int x; + int y; +}; + +int test_read_through_uninitialized_pointer(void) +{ + struct coord *coord_ptr; + + return coord_ptr->x; +} + +/* + PEP-7 +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/tests/cpychecker/absinterp/read-through-uninitialized-ptr/script.py b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/script.py new file mode 100644 index 0000000..7683fd6 --- /dev/null +++ b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/script.py @@ -0,0 +1,23 @@ +# -*- coding: utf-8 -*- +# Copyright 2011 David Malcolm dmalcolm@redhat.com +# Copyright 2011 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 libcpychecker import main + +main(verify_refcounting=True, + dump_traces=True, + show_possible_null_derefs=True) diff --git a/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stderr.txt b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stderr.txt new file mode 100644 index 0000000..72a0877 --- /dev/null +++ b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stderr.txt @@ -0,0 +1,3 @@ +tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c: In function 'test_read_through_uninitialized_pointer': +tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35:5: error: dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35 +tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:32:1: note: graphical error report for function 'test_read_through_uninitialized_pointer' written out to 'tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c.test_read_through_uninitialized_pointer-refcount-errors.html' diff --git a/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stdout.txt b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stdout.txt new file mode 100644 index 0000000..b9da615 --- /dev/null +++ b/tests/cpychecker/absinterp/read-through-uninitialized-ptr/stdout.txt @@ -0,0 +1,6 @@ +Trace 0: + Transitions: + error: UninitializedPtrDereference() + error: dereferencing uninitialized pointer (coord_ptr->x) at tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:35 + Exception: + (struct PyObject *)0 from tests/cpychecker/absinterp/read-through-uninitialized-ptr/input.c:32
gcc-python-plugin-commits@lists.stg.fedorahosted.org