This is the mail archive of the gcc-bugs@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]
Other format: [Raw text]

[Bug c++/24996] [4.0/4.1/4.2 Regression] ICE on throw code



------- Comment #11 from rakdver at gcc dot gnu dot org  2006-01-22 21:49 -------
This ICE works this way: to build_throw, we get expression exp that looks like

TARGET_EXPR <D.2066, b ? aggr_init_expr (... t1 ...) : aggr_init_expr (... t2
...)>

Where t1 and t2 are TARGET_EXPRs with cleanups (*).  build_throw generates code

TARGET_EXPR <D.2069, __cxa_allocate_exception (1)>;
try
  {
    *(struct logic_error *) D.2069 = exp;
  }
catch
  {
    __cxa_free_exception (D.2069);
  };
__cxa_throw (D.2069, (void *) &_ZTI11logic_error, 0B);

This is a problem, since exp (that contains cleanups) is withing the try
statement,
and gimplify_cleanup_expr expects that there never is a compound statement
between
cleanup and cleanup_point_expr (except for COND_EXPRs).

For comparison, with

void foo(bool b) {
      throw logic_error(1);
      }

exp is

TARGET_EXPR <D.2066, aggr_init_expr (... t1 ...)>

In this case, however, stabilize_init will allow to pre-evaluate t1, and the
produced
code is (where exp' is exp with t1 replaced by tmp):

TARGET_EXPR <tmp, t1>
TARGET_EXPR <D.2069, __cxa_allocate_exception (1)>;
try
  {
    *(struct logic_error *) D.2069 = exp';
  }
catch
  {
    __cxa_free_exception (D.2069);
  };
__cxa_throw (D.2069, (void *) &_ZTI11logic_error, 0B);

Here gimplify_cleanup_expr has no problem, since t1 is outside of the try
statement.

Now the question is whether we can persuade throw_expr to also evaluate
(the relevant parts of) exp outside of the try statement.  Answering this
question
is far beyond my understanding of c++ frontend; stabilize_init claims that

      /* If the initializer is a COND_EXPR, we can't preevaluate
         anything.  */
      if (TREE_CODE (t) == COND_EXPR)
        return false;

which might suggest that it is not possible, but the statement is too vague for
me to
be sure.

If it is somehow possible, it would be much preferable.  The other possibility
is to teach
gimplify_cleanup_expr to deal with try statements, which basically means to
rewrite it
completely from scratch.

--------------

(*) The exact expression is

TARGET_EXPR <D.2066
  init: bD.2024
           ? TARGET_EXPR <D.2062
               init: aggr_init_expr (__comp_ctor ;
                       0B, (struct string &) &TARGET_EXPR <D.2061
                                                init: aggr_init_expr
(__comp_ctor ;
                                                        0B, 0, (struct
allocator &) (struct allocator *) &TARGET_EXPR <D.2045
                                                                               
                            init: {}
                                                                               
                            clean: __comp_dtor  (&D.2045);
                                                                               
                            >
                                                        D.2061)
                                                >
                       D.2062)
               >
           : TARGET_EXPR <D.2065
               init: aggr_init_expr (__comp_ctor ;
                       0B, (struct string &) &TARGET_EXPR <D.2064
                                                init: aggr_init_expr
(__comp_ctor ;
                                                        0B, 1, (struct
allocator &) (struct allocator *) &TARGET_EXPR <D.2063
                                                                               
                            init: {}
                                                                               
                            clean: __comp_dtor  (&D.2063);
                                                                               
                            >
                                                        D.2064)
                                                >
                       D.2065)
               >;
  >;


-- 

rakdver at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mark at codesourcery dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24996


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