This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/37378] [4.4 Regression] Revision 139827 causes Divide_X
- From: "jakub at gcc dot gnu dot org" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 24 Oct 2008 13:53:35 -0000
- Subject: [Bug target/37378] [4.4 Regression] Revision 139827 causes Divide_X
- References: <bug-37378-682@http.gcc.gnu.org/bugzilla/>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Comment #14 from jakub at gcc dot gnu dot org 2008-10-24 13:53 -------
I think it is _Jv_divI which now has wrong unwind info (well, not only that).
Here is a self-contained source for _Jv_divI:
#pragma GCC java_exceptions
extern "Java"
{
typedef __java_int jint;
typedef __java_long jlong;
typedef __java_boolean jboolean;
typedef jint jsize;
namespace java
{
namespace lang
{
class Class;
class Object;
class String;
class Throwable;
}
}
}
typedef struct java::lang::Object* jobject;
typedef class java::lang::Class* jclass;
typedef class java::lang::Throwable* jthrowable;
typedef class java::lang::String* jstring;
extern "C" jobject _Jv_AllocObject (jclass) __attribute__((__malloc__));
extern "C" void _Jv_Throw (jthrowable) __attribute__ ((__noreturn__));
extern "Java"
{
struct _JvObjectPrefix
{
virtual void nacd_1 (void) {};
};
}
struct java::lang::Object : public _JvObjectPrefix
{
virtual void finalize (void);
jclass getClass (void);
virtual jint hashCode (void);
void notify (void);
void notifyAll (void);
void wait (jlong timeout, jint nanos);
virtual jboolean equals (jobject obj);
Object (void);
virtual jstring toString (void);
void wait (void);
void wait (jlong timeout);
static java::lang::Class class$;
virtual jobject clone (void);
};
struct java::lang::Throwable : public ::java::lang::Object
{
Throwable();
Throwable(::java::lang::String *);
static const jlong serialVersionUID = -3042686055658047285LL;
::java::lang::String * __attribute__((aligned(__alignof__(
::java::lang::Object)))) detailMessage;
static ::java::lang::Class class$;
};
extern "C" jstring bar(const char*, jsize) __attribute__((__malloc__));
jint
_Jv_divI (jint dividend, jint divisor)
{
if (__builtin_expect (divisor == 0, false))
{
java::lang::Throwable *arithexception = new java::lang::Throwable (bar
("/ by zero", 9));
throw arithexception;
}
if (dividend == (jint) 0x80000000L && divisor == -1)
return dividend;
return dividend / divisor;
}
compile this with -O2 and note that rp is only saved into a register in the
non-throwing case:
_Z8_Jv_divIii:
[.LFB1:]
.prologue 12, 34
.mmi
.save ar.pfs, r35
alloc r35 = ar.pfs, 2, 3, 2, 0
.fframe 16
adds r12 = -16, r12
cmp4.ne p6, p7 = 0, r33
.mmb
mov r36 = r1
mov r37 = r32
(p7) br.cond.spnt .L7
;;
.mib
nop 0
.save rp, r34
mov r34 = b0
...
.L4:
.mii
nop 0
mov ar.pfs = r35
;;
mov b0 = r34
.mmb
nop 0
.label_state 1
.restore sp
adds r12 = 16, r12
br.ret.sptk.many b0
.L7:
.body
.copy_state 1
...
br.call.sptk.many b0 = bar#
...
br.call.sptk.many b0 = _Jv_Throw#
;;
break.f 0
;;
.endp _Z8_Jv_divIii#
The code after .L7 doesn't ever branch to the normal code, and b0 is only saved
into r34 around the normal codepath. So, after the first call after .L7 label
the caller's rp isn't preserved anywhere. If none of the calls could ever
throw, then that would just mean it would be impossible to print backtraces,
but as some calls can throw (and the last, noreturn, call will always throw),
not saving b0 into some local register is a bug.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37378