Bug 32370 - [4.3 Regression] Segfault after rejecting bogus assembler
Summary: [4.3 Regression] Segfault after rejecting bogus assembler
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 4.3.0
: P2 normal
Target Milestone: 4.3.0
Assignee: Jakub Jelinek
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: error-recovery, ice-on-invalid-code
: 33138 (view as bug list)
Depends on:
Blocks:
 
Reported: 2007-06-16 17:40 UTC by Martin Michlmayr
Modified: 2007-10-10 07:35 UTC (History)
3 users (show)

See Also:
Host:
Target: ia64-linux-gnu
Build:
Known to work: 4.2.0
Known to fail: 4.3.0
Last reconfirmed: 2007-08-24 20:23:29


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Michlmayr 2007-06-16 17:40:47 UTC
I have a really interesting testcase that fails with current trunk.  It's
a piece of C code with some x86 assembler which I'm trying to compile on
IA64.  Obviously, this won't work.  In the past, GCC happily rejected the
code.  Now, however, GCC segfaults after printing an error.  In fact, it's
a bit more interesting than this: GCC segfaults with -O and above, but with
no -O option it runs out of memory.

GCC did the right thing (i.e. reject the code and exit) as of 20070604.

Unfortunately I don't have a working gdb on ia64 so I cannot attach a
traceback.

tbm@coconut0:~$ /usr/lib/gcc-snapshot/libexec/gcc/ia64-linux-gnu/4.3.0/cc1 -O1 vbetool-thunk.c
 inb_local printk x_inb
Analyzing compilation unit
Performing interprocedural optimizations
 <visibility> <early_local_cleanups> <inline> <static-var> <pure-const>Assembling functions:
 inb_local
vbetool-thunk.c: In function 'inb_local':
vbetool-thunk.c:10: error: can't find a register in class 'AR_M_REGS' while reloading 'asm'
vbetool-thunk.c:10: error: 'asm' operand has impossible constraints
 x_inb
vbetool-thunk.c: In function 'x_inb':
vbetool-thunk.c:22: internal compiler error: Segmentation fault
Please submit a full bug report,
with preprocessed source if appropriate.
tbm@coconut0:~/src/b/vbetool-0.7$ /usr/lib/gcc-snapshot/libexec/gcc/ia64-linux-gnu/4.3.0/cc1 vbetool-thunk.c
 inb_local
vbetool-thunk.c: In function 'inb_local':
vbetool-thunk.c:10: error: can't find a register in class 'AR_M_REGS' while reloading 'asm'
vbetool-thunk.c:10: error: 'asm' operand has impossible constraints
 printkKilled

Testcase:


#include <stdarg.h>

#define __BUILDIO(bwl,bw,type) \
unsigned type in##bwl##_local(unsigned long port) { \
        unsigned type value; \
        __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
        return value; \
}\

__BUILDIO(b,b,char)

void
printk(const char *fmt, ...)
{
        va_list argptr;
        va_start(argptr, fmt);
        va_end(argptr);
}

void
x_inb(unsigned short port)
{
        unsigned char  val;
        val = inb_local(port);
}
Comment 1 Martin Michlmayr 2007-06-16 17:48:59 UTC
On powerpc I simply get:

vbetool-thunk.c: In function 'inb_local':
vbetool-thunk.c:10: error: impossible constraint in 'asm'

no segfault.
Comment 2 Steve Ellcey 2007-06-21 16:30:20 UTC
Here is a preprocessed test case"

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;
unsigned char inb_local(unsigned long port) { unsigned char value; __asm__ __vol
atile__("in" "b" " %w1, %" "b" "0" : "=a"(value) : "Nd"(port)); return value; }
void
printk(const char *fmt, ...)
{
        va_list argptr;
        __builtin_va_start(argptr,fmt);
        __builtin_va_end(argptr);
}
void
x_inb(unsigned short port)
{
        unsigned char val;
        val = inb_local(port);
}
Comment 3 Steve Ellcey 2007-06-21 17:10:20 UTC
Slightly shorter test case:

unsigned char inb_local(unsigned long port)
{
        unsigned char value;
        __asm__ __volatile__("in" "b" " %w1, %" "b" "0" : "=a"(value) : "Nd"(port));
        return value;

}
void
x_inb(unsigned short port)
{
        unsigned char val;
        val = inb_local(port);
}
Comment 4 Steve Ellcey 2007-06-21 17:13:00 UTC
With optimization, it looks like we die because df_insn_change_bb can handle
insn_info being NULL but it can't handle insn_info->defs (or uses or eq_uses) being NULL and that is what is happening with -O2.  When no optimization is being done then the failure looks different.  I believe this is due to the dataflow merge.
Comment 5 Steve Ellcey 2007-06-21 22:38:27 UTC
The non-optimized infinite loop problem looks like some kind of memory corruption problem.  At the end of bitmap_element_allocate I put a line "gcc_assert (element != head);" which should never trigger because head exists before the call and element is being newly allocated.  But it does trigger with the test case and this winds up putting us into an infinite loop.
Comment 6 Jakub Jelinek 2007-08-28 09:50:19 UTC
Subject: Bug 32370

Author: jakub
Date: Tue Aug 28 09:50:04 2007
New Revision: 127856

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=127856
Log:
	PR middle-end/32370
	* passes.c (init_optimization_passes): Move pass_df_finish
	after pass_postreload sublist.

	* gcc.dg/pr32370.c: New test.

Added:
    trunk/gcc/testsuite/gcc.dg/pr32370.c
Modified:
    trunk/gcc/ChangeLog
    trunk/gcc/passes.c
    trunk/gcc/testsuite/ChangeLog

Comment 7 Jakub Jelinek 2007-08-28 09:55:19 UTC
Fixed.
Comment 8 Martin Michlmayr 2007-10-10 07:35:30 UTC
*** Bug 33138 has been marked as a duplicate of this bug. ***