commit 1e226e4d6c76a300bbdded7e056cb463f7a8b011 Author: David Malcolm dmalcolm@redhat.com Date: Tue Sep 27 16:24:14 2011 -0400
cpychecker: cope with gimple that uses a gcc.ResultDecl
libcpychecker/absinterp.py | 12 +++- tests/cpychecker/absinterp/result-decl/input.c | 57 +++++++++++++++++++++ tests/cpychecker/absinterp/result-decl/script.py | 22 ++++++++ tests/cpychecker/absinterp/result-decl/stdout.txt | 8 +++ 4 files changed, 96 insertions(+), 3 deletions(-) --- diff --git a/libcpychecker/absinterp.py b/libcpychecker/absinterp.py index ec18149..6df46b6 100644 --- a/libcpychecker/absinterp.py +++ b/libcpychecker/absinterp.py @@ -688,7 +688,7 @@ class State: log('eval_lvalue: %r %s', expr, expr) if loc: check_isinstance(loc, gcc.Location) - if isinstance(expr, (gcc.VarDecl, gcc.ParmDecl)): + if isinstance(expr, (gcc.VarDecl, gcc.ParmDecl, gcc.ResultDecl)): region = self.var_region(expr) check_isinstance(region, Region) return region @@ -732,7 +732,7 @@ class State: return expr if isinstance(expr, gcc.IntegerCst): return ConcreteValue(expr.type, loc, expr.constant) - if isinstance(expr, (gcc.VarDecl, gcc.ParmDecl)): + if isinstance(expr, (gcc.VarDecl, gcc.ParmDecl, gcc.ResultDecl)): region = self.var_region(expr) check_isinstance(region, Region) value = self.get_store(region, expr.type, loc) @@ -795,7 +795,7 @@ class State: self.value_for_region[dest_region] = value
def var_region(self, var): - check_isinstance(var, (gcc.VarDecl, gcc.ParmDecl)) + check_isinstance(var, (gcc.VarDecl, gcc.ParmDecl, gcc.ResultDecl)) if var not in self.region_for_var: # Presumably a reference to a global variable: log('adding region for global var: %r', var) @@ -1000,6 +1000,12 @@ class State: region = RegionOnStack('region for %r' % local, stack) self.region_for_var[local] = region self.value_for_region[region] = UninitializedData(local.type, fun.start) + # Region for the gcc.ResultDecl, if any: + if fun.decl.result: + result = fun.decl.result + region = RegionOnStack('region for %s' % result, stack) + self.region_for_var[result] = region + self.value_for_region[region] = UninitializedData(result.type, fun.start) self.verify()
def mktrans_assignment(self, lhs, rhs, desc): diff --git a/tests/cpychecker/absinterp/result-decl/input.c b/tests/cpychecker/absinterp/result-decl/input.c new file mode 100644 index 0000000..395a4eb --- /dev/null +++ b/tests/cpychecker/absinterp/result-decl/input.c @@ -0,0 +1,57 @@ +/* + 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> + +/* + Test of returning a struct containing pointers, which seems + to gimple containing an assignment to a gcc.ResultDecl; + in the pretty-printed gimple it looks like: + assign to fields of a tmp value + <returnval> = tmp + return <returnval> + (this seems to only happen if there are 3 or more fields, and at least two + are pointers; not sure of exact conditions) +*/ + +struct foo { + void *x; + void *y; + int z; +}; + +struct foo +test(void *x, void *y, int z) +{ + struct foo result; + + result.x = x; + result.y = y; + result.z = z; + + return result; +} + +/* + PEP-7 +Local variables: +c-basic-offset: 4 +indent-tabs-mode: nil +End: +*/ diff --git a/tests/cpychecker/absinterp/result-decl/script.py b/tests/cpychecker/absinterp/result-decl/script.py new file mode 100644 index 0000000..fdd5ba3 --- /dev/null +++ b/tests/cpychecker/absinterp/result-decl/script.py @@ -0,0 +1,22 @@ +# -*- 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_traces=False) diff --git a/tests/cpychecker/absinterp/result-decl/stdout.txt b/tests/cpychecker/absinterp/result-decl/stdout.txt new file mode 100644 index 0000000..312b5e0 --- /dev/null +++ b/tests/cpychecker/absinterp/result-decl/stdout.txt @@ -0,0 +1,8 @@ +Trace 0: + Transitions: + 'returning' + Return value: + repr(): UninitializedData(gcctype='struct foo', loc=gcc.Location(file='tests/cpychecker/absinterp/result-decl/input.c', line=41)) + str(): uninitialized data at tests/cpychecker/absinterp/result-decl/input.c:41 + Exception: + (struct PyObject *)0 from tests/cpychecker/absinterp/result-decl/input.c:41
gcc-python-plugin-commits@lists.stg.fedorahosted.org