expose 'inform' function
by Tom Tromey
This exposes the GCC 'inform' function as gcc.inform.
Tom
diff --git a/docs/basics.rst b/docs/basics.rst
index d51947b..2c9b344 100644
--- a/docs/basics.rst
+++ b/docs/basics.rst
@@ -429,6 +429,25 @@ Generating custom errors and warnings
Returns True if the warning was actually printed, False otherwise
+.. py:function:: gcc.inform(loc, str)
+
+ This is a wrapper around GCC's `inform` function.
+
+ Expects an instance of :py:class:`gcc.Location` (not None) and a string
+
+ Emit an informational message at that location.
+
+ For example::
+
+ gcc.inform(stmt.loc, 'this is where X was defined')
+
+ would lead to this informational message being printed:
+
+ .. code-block:: bash
+
+ $ ./gcc-with-python script.py input.c
+ input.c:23:3: note: this is where X was defined
+
Global data access
==================
diff --git a/gcc-python.c b/gcc-python.c
index 4e35456..79262ab 100644
--- a/gcc-python.c
+++ b/gcc-python.c
@@ -373,6 +373,27 @@ gcc_python_warning(PyObject *self, PyObject *args, PyObject *kwargs)
}
static PyObject *
+gcc_python_inform(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ PyGccLocation *loc_obj;
+ const char *msg;
+ char *keywords[] = {"location",
+ "message",
+ NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs,
+ "O!s:inform", keywords,
+ &gcc_LocationType, &loc_obj,
+ &msg)) {
+ return NULL;
+ }
+
+ inform(loc_obj->loc, "%s", msg);
+
+ Py_RETURN_NONE;
+}
+
+static PyObject *
gcc_python_get_option_list(PyObject *self, PyObject *args)
{
PyObject *result;
@@ -533,6 +554,11 @@ static PyMethodDef GccMethods[] = {
(METH_VARARGS | METH_KEYWORDS),
("Report a warning\n"
"FIXME\n")},
+ {"inform",
+ (PyCFunction)gcc_python_inform,
+ (METH_VARARGS | METH_KEYWORDS),
+ ("Report an information message\n"
+ "FIXME\n")},
/* Options: */
{"get_option_list",
12 years, 10 months
make html from top-level
by Tom Tromey
I've tried to 'make html' at the top level a few times now, so I thought
I'd send the obvious patch...
Tom
diff --git a/Makefile b/Makefile
index e050dfc..15d6114 100644
--- a/Makefile
+++ b/Makefile
@@ -134,3 +134,6 @@ test-suite: plugin
show-ssa: plugin
./gcc-with-python show-ssa.py test.c
+
+html:
+ cd docs && $(MAKE) html
12 years, 10 months
patch to add new write_dot_image utility function
by Tom Tromey
I wanted to be able to write out a dot image with a given file name, so
I could generate CFG images for certain functions during the course of a
'make'.
I came up with the appended.
Tom
diff --git a/gccutils.py b/gccutils.py
index fa21012..bb891b1 100644
--- a/gccutils.py
+++ b/gccutils.py
@@ -37,7 +37,7 @@ def get_variables_as_dict():
result[var.decl.name] = var
return result
-def invoke_dot(dot):
+def write_dot_image(dot, basename):
from subprocess import Popen, PIPE
if 1:
@@ -53,10 +53,12 @@ def invoke_dot(dot):
# Presumably a font selection/font metrics issue
fmt = 'svg'
- p = Popen(['dot', '-T%s' % fmt, '-o', 'test.%s' % fmt],
+ p = Popen(['dot', '-T%s' % fmt, '-o', '%s.%s' % (basename, fmt)],
stdin=PIPE)
p.communicate(dot.encode('ascii'))
+def invoke_dot(dot):
+ write_dot_image(dot, 'test')
p = Popen(['xdg-open', 'test.%s' % fmt])
p.communicate()
12 years, 10 months
cfg_to_dot problems
by Tom Tromey
I ran into a couple of problems with cfg_to_dot.
First, cfg_to_dot seems to pass arguments reversed to CfgPrettyPrinter.
I changed how cfg_to_dot is defined to match CfgPrettyPrinter.
Second, I got errors in block_to_dot_label. Apparently I have a
statement without a location; this winds up as a None object which
doesn't work with get_src_for_loc, or have line or column attributes.
I patched this in a kind of dumb way, maybe something better is possible.
Tom
diff --git a/gccutils.py b/gccutils.py
index fa21012..68a0476 100644
--- a/gccutils.py
+++ b/gccutils.py
@@ -283,14 +283,21 @@ class CfgPrettyPrinter(DotPrettyPrinter):
for stmtidx, stmt in enumerate(bb.gimple):
if curloc != stmt.loc:
curloc = stmt.loc
- code = get_src_for_loc(stmt.loc).rstrip()
+ if curloc:
+ code = get_src_for_loc(curloc).rstrip()
+ line = curloc.line
+ column = curloc.column
+ else:
+ code = '<<no code>>'
+ line = 0
+ column = 0
pseudohtml = self.code_to_html(code)
# print('pseudohtml: %r' % pseudohtml)
result += ('<tr><td align="left">'
- + self.to_html('%4i ' % stmt.loc.line)
+ + self.to_html('%4i ' % line)
+ pseudohtml
+ '<br/>'
- + (' ' * (5 + stmt.loc.column-1)) + '^'
+ + (' ' * (5 + column-1)) + '^'
+ '</td></tr>')
result += '<tr><td></td>' + self.stmt_to_html(stmt, stmtidx) + '</tr>\n'
@@ -454,8 +461,8 @@ class TreePrettyPrinter(DotPrettyPrinter):
result += '}\n'
return result
-def cfg_to_dot(name, cfg):
- pp = CfgPrettyPrinter(name, cfg)
+def cfg_to_dot(cfg, name = None):
+ pp = CfgPrettyPrinter(cfg, name)
return pp.to_dot()
12 years, 10 months
a question about -fdiagnostics-show-option
by Tom Tromey
Right now I get errors like this:
../../archer/gdb/python/python.c:415:25: error: Mismatching type in call to PyArg_ParseTuple with format code "L" [-fpermissive]
Note the [-fpermissive]. This is shown by -fdiagnostics-show-option,
which lets users know how to disable a message.
The particular option here comes because the plugin calls permerror
instead of one of the more generic functions, like error or warning.
Is this intentional?
It seems to me that it would be better to expose all the gcc machinery
here. It isn't ideal (I'm not sure if a plugin can add a new -W
option), but better I think than putting all errors into one bucket.
Tom
12 years, 10 months
IntegerCst suggestion
by Tom Tromey
Just a random suggestion...
Right now to convert an IntegerCst to an int I have to use 'obj.constant'.
It seems natural to let int(obj) work as well; that is the first thing I
tried (without thinking much about it...)
Tom
12 years, 10 months
patchlet
by Tom Tromey
I ran the checker against gdb and got an error:
Traceback (most recent call last):
File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/__init__.py", line 33, in on_pass_execution
check_pyargs(fun)
File "/home/tromey/Space/Trunk/gcc-python-plugin/libcpychecker/PyArg_ParseTuple.py", line 469, in check_pyargs
if stmt.fndecl.name == 'PyArg_ParseTuple':
AttributeError: 'NoneType' object has no attribute 'name'
../../archer/gdb/cli/cli-dump.c: In function ‘call_dump_func’:
../../archer/gdb/cli/cli-dump.c:787:1: fatal error: Unhandled Python exception raised within callback
compilation terminated.
I am not certain, but perhaps this happens due to a call via a function
pointer.
The appended patch worked for me, at least in the sense that it removed
the error.
Also, the error location could be better here. E.g., in this case, if
it used the location of the call statement, I could more easily see what
exactly the problem is. As it is the location refers to the closing
brace of the function.
Tom
diff --git a/libcpychecker/PyArg_ParseTuple.py b/libcpychecker/PyArg_ParseTuple.py
index 13efbf1..2908460 100644
--- a/libcpychecker/PyArg_ParseTuple.py
+++ b/libcpychecker/PyArg_ParseTuple.py
@@ -466,7 +466,9 @@ def check_pyargs(fun):
if isinstance(stmt, gcc.GimpleCall):
#log('stmt.fn: %s %r' % (stmt.fn, stmt.fn))
#log('stmt.fndecl: %s %r' % (stmt.fndecl, stmt.fndecl))
- if stmt.fndecl.name == 'PyArg_ParseTuple':
+ if not hasattr(stmt.fndecl, 'name'):
+ pass
+ elif stmt.fndecl.name == 'PyArg_ParseTuple':
check_callsite(stmt, 'PyArg_ParseTuple', 1, 2)
elif stmt.fndecl.name == 'PyArg_ParseTupleAndKeywords':
check_callsite(stmt, 'PyArg_ParseTupleAndKeywords', 2, 4)
12 years, 10 months
FYI: some cleanup fixes
by Tom Tromey
CC'd to gcc-python-plugin.
I am checking this in on the trunk.
I implemented a GCC plugin that does some checking of cleanup use in
GDB. This was relatively easy since I used David Malcolm's generic
Python plugin.
The plugin code is attached -- it is not perfect by any means, but it
does an ok job for most of GDB.
This patch fixes a number of problems found by this plugin. Most of
them were cases where a function that intended to be good about cleanups
instead left some dangling along some path.
The plugin also found a couple of cases of the invalid:
if (something)
do_cleanups (something);
anti-idiom.
Finally, the plugin found a real bug, probably a crasher, in
mi-cmd-var.c.
Built and regtested by the buildbot.
Tom
2011-06-27 Tom Tromey <tromey(a)redhat.com>
* valops.c (find_overload_match): Call do_cleanups before early
return.
* top.c (execute_command): Call do_cleanups before early return.
(command_loop): Likewise.
* stack.c (backtrace_command): Make a null cleanup early. Don't
conditionally call do_cleanups.
* python/py-value.c (TRY_CATCH): Move cleanup handling into
TRY_CATCH.
* python/py-breakpoint.c (gdbpy_breakpoint_has_py_cond): Rearrange
so cleanups are always run.
* mi/mi-cmd-var.c (mi_cmd_var_delete): Reset old_cleanups.
* findcmd.c (parse_find_args): Call do_cleanups on early return
path.
* dbxread.c (elfstab_build_psymtabs): Make a null cleanup early.
Don't conditionally call do_cleanups.
* cli/cli-script.c (execute_user_command): Initialize 'old_chain'
later.
diff --git a/gdb/cli/cli-script.c b/gdb/cli/cli-script.c
index 2d1afe5..c94f7ee 100644
--- a/gdb/cli/cli-script.c
+++ b/gdb/cli/cli-script.c
@@ -317,13 +317,13 @@ execute_user_command (struct cmd_list_element *c, char *args)
static int user_call_depth = 0;
extern int max_user_call_depth;
- old_chain = setup_user_args (args);
-
cmdlines = c->user_commands;
if (cmdlines == 0)
/* Null command */
return;
+ old_chain = setup_user_args (args);
+
if (++user_call_depth > max_user_call_depth)
error (_("Max user call depth exceeded -- command aborted."));
diff --git a/gdb/dbxread.c b/gdb/dbxread.c
index 0c5dc02..33c776f 100644
--- a/gdb/dbxread.c
+++ b/gdb/dbxread.c
@@ -3433,7 +3433,7 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
bfd *sym_bfd = objfile->obfd;
char *name = bfd_get_filename (sym_bfd);
struct dbx_symfile_info *info;
- struct cleanup *back_to = NULL;
+ struct cleanup *back_to = make_cleanup (null_cleanup, NULL);
/* There is already a dbx_symfile_info allocated by our caller.
It might even contain some info from the ELF symtab to help us. */
@@ -3477,7 +3477,7 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
symbuf_left = bfd_section_size (objfile->obfd, stabsect);
stabs_data = symfile_relocate_debug_section (objfile, stabsect, NULL);
if (stabs_data)
- back_to = make_cleanup (free_current_contents, (void *) &stabs_data);
+ make_cleanup (free_current_contents, (void *) &stabs_data);
/* In an elf file, we've already installed the minimal symbols that came
from the elf (non-stab) symbol table, so always act like an
@@ -3487,8 +3487,7 @@ elfstab_build_psymtabs (struct objfile *objfile, asection *stabsect,
case it does, it will install them itself. */
dbx_symfile_read (objfile, 0);
- if (back_to)
- do_cleanups (back_to);
+ do_cleanups (back_to);
}
/* Scan and build partial symbols for a file with special sections for stabs
diff --git a/gdb/findcmd.c b/gdb/findcmd.c
index c21c028..0255613 100644
--- a/gdb/findcmd.c
+++ b/gdb/findcmd.c
@@ -132,6 +132,7 @@ parse_find_args (char *args, ULONGEST *max_countp,
len = value_as_long (v);
if (len == 0)
{
+ do_cleanups (old_cleanups);
printf_filtered (_("Empty search range.\n"));
return;
}
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index a401846..aee6224 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -196,7 +196,7 @@ mi_cmd_var_delete (char *command, char **argv, int argc)
children_only_p = 1;
do_cleanups (old_cleanups);
name = xstrdup (argv[1]);
- make_cleanup (free_current_contents, &name);
+ old_cleanups = make_cleanup (free_current_contents, &name);
}
/* If we didn't error out, now NAME contains the name of the
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index e73dc24..294e648 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -771,10 +771,9 @@ gdbpy_breakpoint_has_py_cond (struct breakpoint_object *bp_obj)
get_current_arch ();
struct cleanup *cleanup = ensure_python_env (garch, current_language);
- if (py_bp == NULL)
- return 0;
+ if (py_bp != NULL)
+ has_func = PyObject_HasAttrString (py_bp, stop_func);
- has_func = PyObject_HasAttrString (py_bp, stop_func);
do_cleanups (cleanup);
return has_func;
diff --git a/gdb/python/py-value.c b/gdb/python/py-value.c
index 4381d52..fc5053a 100644
--- a/gdb/python/py-value.c
+++ b/gdb/python/py-value.c
@@ -553,8 +553,6 @@ static PyObject *
valpy_str (PyObject *self)
{
char *s = NULL;
- struct ui_file *stb;
- struct cleanup *old_chain;
PyObject *result;
struct value_print_options opts;
volatile struct gdb_exception except;
@@ -562,19 +560,19 @@ valpy_str (PyObject *self)
get_user_print_options (&opts);
opts.deref_ref = 0;
- stb = mem_fileopen ();
- old_chain = make_cleanup_ui_file_delete (stb);
-
TRY_CATCH (except, RETURN_MASK_ALL)
{
+ struct ui_file *stb = mem_fileopen ();
+ struct cleanup *old_chain = make_cleanup_ui_file_delete (stb);
+
common_val_print (((value_object *) self)->value, stb, 0,
&opts, python_language);
s = ui_file_xstrdup (stb, NULL);
+
+ do_cleanups (old_chain);
}
GDB_PY_HANDLE_EXCEPTION (except);
- do_cleanups (old_chain);
-
result = PyUnicode_Decode (s, strlen (s), host_charset (), NULL);
xfree (s);
diff --git a/gdb/stack.c b/gdb/stack.c
index 0888b69..1e44367 100644
--- a/gdb/stack.c
+++ b/gdb/stack.c
@@ -1425,7 +1425,7 @@ backtrace_command_stub (void *data)
static void
backtrace_command (char *arg, int from_tty)
{
- struct cleanup *old_chain = NULL;
+ struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
int fulltrace_arg = -1, arglen = 0, argc = 0;
struct backtrace_command_args btargs;
@@ -1435,7 +1435,7 @@ backtrace_command (char *arg, int from_tty)
int i;
argv = gdb_buildargv (arg);
- old_chain = make_cleanup_freeargv (argv);
+ make_cleanup_freeargv (argv);
argc = 0;
for (i = 0; argv[i]; i++)
{
@@ -1481,8 +1481,7 @@ backtrace_command (char *arg, int from_tty)
if (fulltrace_arg >= 0 && arglen > 0)
xfree (arg);
- if (old_chain)
- do_cleanups (old_chain);
+ do_cleanups (old_chain);
}
static void
diff --git a/gdb/top.c b/gdb/top.c
index 58c5075..ecb91f2 100644
--- a/gdb/top.c
+++ b/gdb/top.c
@@ -378,7 +378,10 @@ execute_command (char *p, int from_tty)
/* This can happen when command_line_input hits end of file. */
if (p == NULL)
- return;
+ {
+ do_cleanups (cleanup);
+ return;
+ }
target_log_command (p);
@@ -542,7 +545,10 @@ command_loop (void)
get_prompt () : (char *) NULL,
instream == stdin, "prompt");
if (command == 0)
- return;
+ {
+ do_cleanups (old_chain);
+ return;
+ }
make_command_stats_cleanup (1);
diff --git a/gdb/valops.c b/gdb/valops.c
index f5458ef..803b73c 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -2670,6 +2670,7 @@ find_overload_match (struct type **arg_types, int nargs,
if (func_name == NULL)
{
*symp = fsym;
+ do_cleanups (all_cleanups);
return 0;
}
12 years, 10 months
check NULL-termination of keyword arguments
by Tom Tromey
Here is a patch that adds checking for NULL-termination of keyword
arguments to PyArg_ParseTupleAndKeywords. This problem has bit us in
gdb a couple of times.
I've included a doc update and a test case.
Let me know what you think.
I needed to add an 'operand' field to Unary. After looking at it a
little, I think this code does not model GCC precisely enough.
E.g., 'location' is added just for 'Expression':
if localname == 'Expression':
add_simple_getter('location',
'gcc_python_make_wrapper_location(EXPR_LOCATION(self->t))',
"The source location of this expression")
But, I think this should actually be added for any class that uses
tree_exp as its representation: tcc_expression, tcc_comparison,
tcc_unary, tcc_binary, and tcc_statement.
Tom
diff --git a/docs/tree.rst b/docs/tree.rst
index 8a0a89f..4a8a0fd 100644
--- a/docs/tree.rst
+++ b/docs/tree.rst
@@ -503,6 +503,10 @@ Unary Expressions
Corresponds to the `tcc_unary` value of `enum tree_code_class` within
GCC's own C sources.
+ .. py:attribute:: operand
+
+ The operand of this operator, as a `gcc.Tree`.
+
====================================== ==================================================
Subclass Meaning; C/C++ operators
====================================== ==================================================
diff --git a/generate-tree-c.py b/generate-tree-c.py
index 419aaaa..4c52c63 100644
--- a/generate-tree-c.py
+++ b/generate-tree-c.py
@@ -253,6 +253,11 @@ PyObject*
pytype.tp_methods = methods.identifier
cu.add_defn(methods.c_defn())
+ if localname == 'Unary':
+ add_simple_getter('operand',
+ 'gcc_python_make_wrapper_tree(TREE_OPERAND (self->t, 0))',
+ 'The operand of this expression, as a gcc.Tree')
+
if localname == 'Expression':
add_simple_getter('location',
'gcc_python_make_wrapper_location(EXPR_LOCATION(self->t))',
diff --git a/libcpychecker/PyArg_ParseTuple.py b/libcpychecker/PyArg_ParseTuple.py
index bf99e35..8e0b977 100644
--- a/libcpychecker/PyArg_ParseTuple.py
+++ b/libcpychecker/PyArg_ParseTuple.py
@@ -542,6 +542,33 @@ def check_pyargs(fun):
if isinstance(operand, gcc.StringCst):
return operand.constant
+ def check_keyword_array(stmt, idx):
+ keywords = stmt.args[idx]
+ if isinstance(keywords, gcc.AddrExpr):
+ operand = keywords.operand
+ if isinstance(operand, gcc.VarDecl):
+ initial = operand.initial
+ if isinstance(initial, gcc.Constructor):
+ elements = [None] * len(initial.elements)
+ for elt in initial.elements:
+ (num, contents) = elt
+ elt_idx = num.constant
+ if isinstance(contents, gcc.NopExpr):
+ contents = contents.operand
+ if isinstance(contents, gcc.AddrExpr):
+ contents = contents.operand
+ if isinstance(contents, gcc.StringCst):
+ elements[elt_idx] = contents.constant
+ elif isinstance(contents, gcc.IntegerCst):
+ elements[elt_idx] = contents.constant
+ if elements[-1] != 0:
+ gcc.permerror(stmt.loc, 'keywords to PyArg_ParseTupleAndKeywords are not NULL-terminated')
+ i = 0
+ for elt in elements[0:-1]:
+ if not elt:
+ gcc.permerror(stmt.loc, 'keyword argument %d missing in PyArg_ParseTupleAndKeywords call' % i)
+ i = i + 1
+
def check_callsite(stmt, funcname, format_idx, varargs_idx):
log('got call at %s' % stmt.loc)
log(get_src_for_loc(stmt.loc))
@@ -607,5 +634,6 @@ def check_pyargs(fun):
if stmt.fndecl.name == 'PyArg_ParseTuple':
check_callsite(stmt, 'PyArg_ParseTuple', 1, 2)
elif stmt.fndecl.name == 'PyArg_ParseTupleAndKeywords':
+ check_keyword_array(stmt, 3)
check_callsite(stmt, 'PyArg_ParseTupleAndKeywords', 2, 4)
diff --git a/tests/cpychecker/PyArg_ParseTuple/keywords/input.c b/tests/cpychecker/PyArg_ParseTuple/keywords/input.c
new file mode 100644
index 0000000..d9d567e
--- /dev/null
+++ b/tests/cpychecker/PyArg_ParseTuple/keywords/input.c
@@ -0,0 +1,45 @@
+/*
+ Copyright 2011 David Malcolm <dmalcolm(a)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/>.
+*/
+
+/*
+ A simple check of PyArg_ParseTupleAndKeywords
+*/
+
+#include <Python.h>
+
+static PyObject *
+parse_to_a_typedef(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ int val;
+ static char *keywords[] = { "hi" }; /* Note no NULL terminator. */
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", keywords, &val)) {
+ return NULL;
+ }
+
+ Py_RETURN_NONE;
+}
+
+/*
+ PEP-7
+Local variables:
+c-basic-offset: 4
+indent-tabs-mode: nil
+End:
+*/
diff --git a/tests/cpychecker/PyArg_ParseTuple/keywords/script.py b/tests/cpychecker/PyArg_ParseTuple/keywords/script.py
new file mode 100644
index 0000000..e120c53
--- /dev/null
+++ b/tests/cpychecker/PyArg_ParseTuple/keywords/script.py
@@ -0,0 +1,19 @@
+# Copyright 2011 David Malcolm <dmalcolm(a)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()
diff --git a/tests/cpychecker/PyArg_ParseTuple/keywords/stderr.txt b/tests/cpychecker/PyArg_ParseTuple/keywords/stderr.txt
new file mode 100644
index 0000000..3168ae9
--- /dev/null
+++ b/tests/cpychecker/PyArg_ParseTuple/keywords/stderr.txt
@@ -0,0 +1,2 @@
+tests/cpychecker/PyArg_ParseTuple/keywords/input.c: In function ‘parse_to_a_typedef’:
+tests/cpychecker/PyArg_ParseTuple/keywords/input.c:32:37: error: keywords to PyArg_ParseTupleAndKeywords are not NULL-terminated [-fpermissive]
12 years, 10 months
question about 737eb35e6842e477cb139ec09826a0f2c777f00f
by Tom Tromey
I am curious about this commit:
commit 737eb35e6842e477cb139ec09826a0f2c777f00f
Author: David Malcolm <dmalcolm(a)redhat.com>
Date: Fri Jun 24 17:54:37 2011 -0400
Add a way of turning of const-correctness for "const char*" checking
This test was showing lots of (apparently) false positives when running
the checker against CPython 2.7
What are the false positives here?
Tom
12 years, 10 months