This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: Prevent seg fault on buggy input
- To: law at cygnus dot com
- Subject: Re: Prevent seg fault on buggy input
- From: Nick Clifton <nickc at cygnus dot com>
- Date: Tue, 16 May 2000 14:38:35 -0700
- CC: gcc-patches at gcc dot gnu dot org
Hi Jeff,
: > Given the following, buggy, C program as input, gcc will currently
: > generate a seg fault after emitting a few error messages:
: I didn't get a segfault (I wanted to add this to the testsuite which is
: why I was poking at it). What platform/configuration?
I was using arm-elf. However I am also able to reproduce this problem
under i686-pc-linux-gnu. I have not tried other targets, but I think
that the problem is quite generic.
: Some explanation of the bug would also help.
OK. Here is a simplified version of the input file that also
reproduces this bug:
main ()
{
int foo = & 0x10000 + bar;
The parser has issued error messages about taking the address of a
constant and the fact that bar is undefined:
fred.c:3: invalid lvalue in unary `&'
fred.c:3: `bar' undeclared (first use in this function)
Then it continues on to try to evaluate the assignment to foo. It
calls finish_decl() but the 'init' tree just contains an error decl
inside a NON_LVALUE_EXPR:
(gdb) call debug_tree (init)
<non_lvalue_expr 0x401168a0 type <error_mark 0x40015440>
arg 0 <error_mark 0x40015440>>
Since 'init' is non-null however, store_init_value() is called to
convert it to the correct type (if necessary) and to store it into
'decl'. The first thing store_init_valuye does is to call
digest_init() to convert the initialiser into a C expression. This
function checks to see if 'init' is an error node, but it does not
currently check to see if the expression inside the init is an error
mark, which then leads to the complications, and eventually a seg
fault when comptypes() tries to examine the type of an
error_mark_node.
So here is a revised version of the patch, which moves the check for
inside_init being an error node to earlier in digest_init().
Is this version OK to apply ?
Cheers
Nick
2000-05-16 Nick Clifton <nickc@cygnus.com>
* c-typeck.c (digest_init): Check for 'inside_init' being an
error mark.
Index: gcc/c-typeck.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/c-typeck.c,v
retrieving revision 1.65
diff -p -w -r1.65 c-typeck.c
*** c-typeck.c 2000/05/09 19:55:47 1.65
--- c-typeck.c 2000/05/16 21:21:16
*************** digest_init (type, init, require_constan
*** 4527,4533 ****
--- 4527,4538 ----
/* Do not use STRIP_NOPS here. We do not want an enumerator
whose value is 0 to count as a null pointer constant. */
if (TREE_CODE (init) == NON_LVALUE_EXPR)
+ {
inside_init = TREE_OPERAND (init, 0);
+
+ if (inside_init == error_mark_node)
+ return error_mark_node;
+ }
/* Initialization of an array of chars from a string constant
optionally enclosed in braces. */