This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Exception propagation problem on IA-64/Linux
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc at gcc dot gnu dot org
- Date: Thu, 27 Oct 2005 22:21:08 +0200
- Subject: Exception propagation problem on IA-64/Linux
Hi,
We have run into an exception propagation problem on IA-64/Linux. An
admittedly contrived C++ testcase is attached.
botcazou@taff:~/EA27-007> g++ -v
Using built-in specs.
Target: ia64-sgi-linux-gnu
Configured with: /home01/botcazou/cvs/gcc/configure ia64-sgi-linux-gnu
--prefix=/nile.build/botcazou/fsf/install_ia64 --disable-nls
--disable-libmudflap --disable-checking --enable-languages=c,c++
Thread model: posix
gcc version 4.1.0 20051024 (experimental)
botcazou@taff:~/EA27-007> g++ -o t t.C u.C
botcazou@taff:~/EA27-007> ./t
botcazou@taff:~/EA27-007> g++ -o t u.C t.C
botcazou@taff:~/EA27-007> ./t
struct S exception caught!
The problem pertains to the type_info objects emitted for the exceptions:
while the exceptions in t.C and u.C are unrelated, these objects are the
same. On IA-32 they are local to the translation unit, but on IA-64 they are
DECL_ONE_ONLY because of dw2_force_const_mem.
Now we have in dw2_asm_output_encoded_addr_rtx:
/* Indirection is used to get dynamic relocations out of a
read-only section. */
if (encoding & DW_EH_PE_indirect)
{
/* It is very tempting to use force_const_mem so that we share data
with the normal constant pool. However, we've already emitted
the constant pool for this function. Moreover, we'd like to
share these constants across the entire unit of translation,
or better, across the entire application (or DSO). */
addr = dw2_force_const_mem (addr);
encoding &= ~DW_EH_PE_indirect;
goto restart;
}
It seems to me that it's not the job of dw2_force_const_mem to do the sharing
"across the entire application (or DSO)", but that of the linker. Its head
comment still reads:
/* Put X, a SYMBOL_REF, in memory. Return a SYMBOL_REF to the allocated
memory. Differs from force_const_mem in that a single pool is used for
the entire unit of translation, and the memory is not guaranteed to be
"near" the function in any interesting sense. */
The "across the entire application (or DSO)" thing was added afterwards:
2001-11-08 Jakub Jelinek <jakub@redhat.com>
* dwarf2asm.c (mark_indirect_pool_entry, mark_indirect_pool): New.
(USE_LINKONCE_INDIRECT): Define.
(dw2_output_indirect_constant_1): Try to output indirect constants
into linkonce sections if possible.
(dw2_force_const_mem): Likewise. Register indirect_pool with GGC.
(dw2_output_indirect_constants): Likewise.
Thoughts?
--
Eric Botcazou
#include <cstdio>
extern void bar(void);
static void foo(void)
{
struct S { int i; };
try {
bar ();
}
catch (struct S) {
printf ("struct S exception caught!\n");
}
catch (...) {}
}
int main(void)
{
foo ();
return 0;
}
bool pred = false;
static void foo(void)
{
struct S { double d; } s1;
if (pred) {
try { foo(); }
catch (struct S) { foo(); }
}
throw s1;
}
void bar(void)
{
foo ();
}