Bug 15745 - exception specification incorrectly changes the type of the exception thrown
Summary: exception specification incorrectly changes the type of the exception thrown
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 3.4.0
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: wrong-code
Depends on:
Blocks:
 
Reported: 2004-05-31 07:58 UTC by William Fulton
Modified: 2008-11-18 18:50 UTC (History)
2 users (show)

See Also:
Host: i586-mandrake-linux-gnu
Target:
Build:
Known to work: 4.3.0
Known to fail: 2.95.3 3.3.1 3.0.4 3.4.0 4.0.0
Last reconfirmed: 2005-05-01 03:48:37


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description William Fulton 2004-05-31 07:58:57 UTC
$ cat gccexceptionbug.cxx

#include <iostream>
using namespace std;

typedef int IntArray[10];

void test_array() throw (IntArray) {
//void test_array() {
    static IntArray arr;
    for (int i=0; i<10; i++) {
        arr[i] = i;
    }
    throw arr;
}

int main ()
{
    cout << "Start" << endl;

    try {
        test_array();
    } catch (IntArray) {
        cout << "Caught!" << endl;
    }

    cout << "Finish" << endl;

    return 0;
}


$ g++-3.4.0 -v -save-temps gccexceptionbug.cxx -o gccexceptionbug
Reading specs from /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/specs
Configured with: ../configure --prefix=/usr --libdir=/usr/lib
--with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info
--enable-shared --enable-threads=posix --disable-checking --enable-long-long
--enable-__cxa_atexit --enable-clocale=gnu --disable-libunwind-exceptions
--enable-languages=c,c++,java --program-suffix=-3.4.0
--host=i586-mandrake-linux-gnu --with-system-zlib
Thread model: posix
gcc version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk)
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/cc1plus -E -quiet -v -D_GNU_SOURCE
gccexceptionbug.cxx -mtune=pentium -o gccexceptionbug.ii
ignoring nonexistent directory
"/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../i586-mandrake-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0/i586-mandrake-linux-gnu
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../../include/c++/3.4.0/backward
 /usr/local/include
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/include
 /usr/include
End of search list.
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/cc1plus -fpreprocessed
gccexceptionbug.ii -quiet -dumpbase gccexceptionbug.cxx -mtune=pentium -auxbase
gccexceptionbug -version -o gccexceptionbug.s
GNU C++ version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk) (i586-mandrake-linux-gnu)
        compiled by GNU C version 3.4.0 (Mandrake Linux 10.0 3.4.0-1mdk).
GGC heuristics: --param ggc-min-expand=47 --param ggc-min-heapsize=32000
 as -V -Qy -o gccexceptionbug.o gccexceptionbug.s
GNU assembler version 2.14.90.0.5 (i586-mandrake-linux-gnu) using BFD version
2.14.90.0.5 20030722
 /usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/collect2 --eh-frame-hdr -m elf_i386
-dynamic-linker /lib/ld-linux.so.2 -o gccexceptionbug
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crt1.o
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crti.o
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/crtbegin.o
-L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0
-L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0
-L/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../.. gccexceptionbug.o -lstdc++
-lm -lgcc_s -lgcc -lc -lgcc_s -lgcc
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/crtend.o
/usr/lib/gcc/i586-mandrake-linux-gnu/3.4.0/../../../crtn.o
$
$ ./gccexceptionbug
Start
terminate called after throwing an instance of 'int*'
Aborted
$


Note that if  the exception specification in the definition of test_array() is
removed, the exception is caught. (Replace with the commented out line). The
same behaviour was observed in gcc version 3.3.1 (cygming special).
Comment 1 Drea Pinski 2004-05-31 13:15:23 UTC
If I recall correctly from my reading of the standard arrays get decayed to pointers for things like this 
(and a couple of others too).
Comment 2 Wolfgang Bangerth 2004-06-01 15:27:57 UTC
Confirmed. Here's a small testcase: 
------------------- 
typedef int IntArray[10]; 
IntArray i; 
 
void test_array() 
#ifdef TEST 
  throw (IntArray) 
#endif 
{ throw i; } 
 
 
int main () { 
    try { 
        test_array(); 
    } catch (IntArray) {} 
} 
------------------ 
 
We get 
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc ; ./a.out  
g/x> /home/bangerth/bin/gcc-3.4-pre/bin/c++ x.cc -DTEST ; ./a.out  
terminate called after throwing an instance of 'int*' 
Aborted 
 
The point is that if we throw an exception that violates the exception 
specification, then it is converted into an unspec exception and we 
abort. However, since we can catch the exception that we throw in the  
main function if there is no exception specification on the function 
body, it seems as if the exception thrown is really of type IntArray 
and shouldn't violate the exception specification. I agree that this 
is confusing and looks like a bug in gcc associated with decaying 
arrays to pointers, though I'd like to solicit a second opinion on 
this. 
 
We get the same results for all gcc versions from 2.95 to mainline. 
 
W. 
Comment 3 Drea Pinski 2004-06-26 20:22:14 UTC
Confirmed.
Comment 4 Jason Merrill 2007-09-06 03:33:57 UTC
Subject: Bug 15745

Author: jason
Date: Thu Sep  6 03:33:46 2007
New Revision: 128174

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128174
Log:
        PR c++/15745
        * except.c (prepare_eh_type): Use type_decays_to.

Added:
    trunk/gcc/testsuite/g++.dg/eh/spec9.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/except.c
    trunk/gcc/testsuite/g++.dg/ext/vla4.C

Comment 5 Jason Merrill 2007-10-01 20:53:25 UTC
Subject: Bug 15745

Author: jason
Date: Mon Oct  1 20:53:09 2007
New Revision: 128917

URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=128917
Log:
        PR c++/15745
        * except.c (prepare_eh_type): Use type_decays_to.

Modified:
    branches/gcc-4_2-branch/gcc/testsuite/g++.dg/ext/vla4.C

Comment 6 Jason Merrill 2008-11-18 18:50:53 UTC
Fixed.