Bug 168828 - The -fno-enforce-eh-specs option does not behave properly when the function explicitly cannot throw exceptions
The -fno-enforce-eh-specs option does not behave properly when the function e...
Product: Red Hat Enterprise Linux 4
Classification: Red Hat
Component: gcc3 (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Jakub Jelinek
Depends On:
  Show dependency treegraph
Reported: 2005-09-20 11:15 EDT by Josef Bacik
Modified: 2007-11-30 17:07 EST (History)
1 user (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2006-03-15 10:05:16 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Patch that fixes the problem (874 bytes, patch)
2005-09-20 11:17 EDT, Josef Bacik
no flags Details | Diff

  None (edit)
Description Josef Bacik 2005-09-20 11:15:43 EDT
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.10) Gecko/20050719 Red Hat/1.0.6-1.4.1 Firefox/1.0.6

Description of problem:
The g++ option -fno-enforce-eh-specs with RHEL 4's GCC does not work properly with the following test case

#include <iostream>
#include <exception>

using namespace std;

class Exception1 {};

void func1() throw(){ throw Exception1();}

int main()
      cout << "*" << endl;
   catch (...)
      cout << "Exception caught" << endl;

If you compile this with

g++ -Wall -fno-enforce-eh-specs 

and then run it, it will exit with SIGABRT, instead of allowing the exception to be thrown.

Now, what I found is that the only place that the flag_enforce_eh_specs option is invocked is in gcc/cp/decl.c, first around 10620 (depending which build you are looking at) in static void store_parm_decls (tree current_function_parms) with the following code

/* Do the starting of the exception specifications, if we have any. */
if (flag_exceptions && !processing_template_decl
    && flag_enforce_eh_specs
    && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
   current_eh_spec_block = begin_eh_spec_block ();

and then again at 10880 in tree finish_function (int flags)

/* Finish dealing with exception specifiers. */
if (flag_exceptions && !processing_template_decl
    && flag_enforce_eh_specs
    && TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl)))
   finish_eh_spec_block (TYPE_RAISES_EXCEPTIONS
                        (TREE_TYPE (current_function_decl)),

So from this, if this option is set and I'm reading it properly, then the throw() part of a function declaration is never processed, basically stripping the function declaration of its throw() restrictions. This works if you do something like

void foo() throw(int)
   throw myClass;

and compile it with -fno-enforce-eh-specs. However, if you use the case provided , with just throw(), the program aborts. The reason for this is because later down in tree finish_function (int flags), there is the following section

/* If this function can't throw any exceptions, remember that. */
if (!processing_template_decl
    && !cp_function_chain->can_throw
    && !flag_non_call_exceptions)
   TREE_NOTHROW (fndecl) = 1;

and cp_function_chain->can_throw gets set in bool maybe_clone_body (tree fn) in gcc/cp/optimize.c, so the TREE_NOTHROW flag gets set since this function has been declared in such a way so that it is not supposed to throw exceptions.

I've written a patch for this issue and tested it, and it works, I will attach it to this bugzilla.

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1.Make a function definition with throw() in it 
2.compile it with the -fno-enforce-eh-specs option
3.run the program

Actual Results:  The program exits with sigabrt and dumps a core

Expected Results:  It should run fine

Additional info:
Comment 1 Josef Bacik 2005-09-20 11:17:18 EDT
Created attachment 119030 [details]
Patch that fixes the problem

This patch basically checks to see if flag_enforce_eh_specs is set, and if its
not it doesn't allow g++ to note the fact that the function explicitly doesn't
allow exception throwing.
Comment 2 Josef Bacik 2005-09-20 15:23:44 EDT
Hmm, seems I used the wrong test case to test this patch, so it doesn't work.  I
think its because TREE_NOTHROW is set to 1 by default, and is never set back to
0.  I'm rebuilding GCC with some debug information, and as soon as I
verify/prove this wrong I'll work out another patch that should fix this.

Note You need to log in before you can comment on or make changes to this bug.