This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Exception Specifications & code quality


Last month there was a thread about checking exception specifications
and warning on any leaked exceptions
(http://www.cygnus.com/ml/egcs/1998-Aug/0252.html) I've noticed
something about the exception unwind code, which is related

Consider the following piece of code,
	void fn_char() throw(char);
	void fn_char1() throw(char)
	  {fn_char();}

fn_char1 produces exception unwinding code which checks if it's going to
throw an object outside the set of its exception specification. (I've
attached the sparc assembler produced at -O2). This is, of course, not
possible.

The code I'm talking about is between LL3 and LL16. I must say, I'm a
little surprised about the exception unwind blocks LLEHB14, LLEHB7 and
LLEHB10 around this, surely the routines __cp_eh_info, __tfc,
__check_eh_spec cannot throw?

This isn't an execution speed problem, because this is the exception
path, but it is a code size issue.

As with checking exception specifications, you need to scan over the
function body creating the union of all uncaught thrown types (from
throw statements and function calls). Then if this is a subset of the
function's throw specification no runtime check is required. Solving
this problem gives the oportunity for the warning, if you really want
it. Like the 'this var may be used uninitialized' warning, you'd only
get it when optimizing (and you asked for it!).

Just thought I'd share this with you.

nathan

-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
      You can up the bandwidth, but you can't up the speed of light      
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk
	.file	"e1.ii"
gcc2_compiled.:
	.global __throw
.section	".text"
	.align 4
	.global fn_char1__Fv
	.type	 fn_char1__Fv,#function
	.proc	020
fn_char1__Fv:
.LLFB1:
	!#PROLOGUE# 0
	save %sp,-120,%sp
.LLCFI0:
	!#PROLOGUE# 1
.LLEHB3:
	call fn_char__Fv,0
	nop
.LLEHE3:
	b,a .LL16
.LL2:
	call __throw,0
	nop
.LLEHB14:
.LLEHB7:
.LL3:
	call __cp_eh_info,0
	nop
	mov %o0,%l0
	ld [%l0+28],%o1
	add %o1,1,%o1
	st %o1,[%l0+28]
.LLEHB10:
	mov 1,%o2
	call __tfc,0
	st %o2,[%l0+20]
	st %o0,[%fp-20]
	mov 1,%o0
	call __check_eh_spec,0
	add %fp,-20,%o1
.LLEHE10:
.LL9:
	call __throw,0
	nop
.LLEHE7:
.LL10:
	call __cp_pop_exception,0
	mov %l0,%o0
	b,a .LL9
.LL7:
	b,a .LL2
.LLEHE14:
.LL14:
	call terminate__Fv,0
	nop
.LL16:
	ret
	restore
.LLFE1:
.LLfe1:
	.size	 fn_char1__Fv,.LLfe1-fn_char1__Fv
.section	".gcc_except_table",#alloc,#write
	.align 4
__EXCEPTION_TABLE__:
	.uaword	.LLEHB3
	.uaword	.LLEHE3
	.uaword	.LL3

	.uaword	.LLEHB14
	.uaword	.LLEHE14
	.uaword	.LL14

	.uaword	.LLEHB7
	.uaword	.LLEHE7
	.uaword	.LL7

	.uaword	.LLEHB10
	.uaword	.LLEHE10
	.uaword	.LL10

	.uaword	-1
	.uaword	-1


.section	".eh_frame",#alloc,#write
__FRAME_BEGIN__:
	.uaword	.LLECIE1-.LLSCIE1
.LLSCIE1:
	.uaword	0x0
	.byte	0x1
	.asciz	"eh"

	.uaword	__EXCEPTION_TABLE__
	.byte	0x1
	.byte	0x7c
	.byte	0x65
	.byte	0xc
	.byte	0xe
	.byte	0x0
	.byte	0x9
	.byte	0x65
	.byte	0xf
	.align 4
.LLECIE1:
	.uaword	.LLEFDE1-.LLSFDE1
.LLSFDE1:
	.uaword	.LLSFDE1-__FRAME_BEGIN__
	.uaword	.LLFB1
	.uaword	.LLFE1-.LLFB1
	.byte	0x4
	.uaword	.LLCFI0-.LLFB1
	.byte	0xd
	.byte	0x1e
	.byte	0x2d
	.byte	0x9
	.byte	0x65
	.byte	0x1f
	.align 4
.LLEFDE1:
	.ident	"GCC: (GNU) egcs-2.91.55 19980824 (gcc2 ss-980609 experimental)"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]