------- Comment #8 from amacleod at redhat dot com 2008-01-16 20:53 ------- Created an attachment (id=14951) --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=14951&action=view) proposed patch for sccvn
I did some analysis, and then verified with dberlin that I was on the right track. The root of the problem is a disconnect between SCCVN and PRE. The function bar() is a function call which is a constant. SCCVN therefore puts it in the tables as a value which can be regenerated by calling bar(). PRE in turn looks at the call and notes that it can throw an exception, and says that it is therefore *not* an expression which can be regenerated. Things then fail in find_or_generate_expression() because the expression is in the table, but PRE is unable to regenerate it. In order to fix the problem, we need to make SCCVN and PRE agree whether a constant function which can throw is an expression which can be regenerated. My initial take on that it is not, because the throw could result in some side effects. The decl for bar() is extern const unsigned short int **bar (void) __attribute__ ((const)); The other question is 'is that really a throwable function?' tree_could_throw_p() currently returns TRUE for bar(). This problem could also be fixed by bar() not being a throwable expression. I'm assuming this is well defined, and currently correct. The final option would be to allow PRE to regenerate expressions which can throw. Thoughts? I've attached a patch to modify SCCVN to say expressions which throw can not be regenerated. Its currently going through testing. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34648