[llvm-commits] [llvm-gcc-4.2] r49171 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-types.cpp

Duncan Sands baldrick at free.fr
Fri Apr 4 01:50:34 PDT 2008


Hi Dale,

> -  if (!tree_could_throw_p(exp))
> +  if (!tree_could_throw_p(exp) || !flag_exceptions)

this bit is not needed because

bool
tree_could_throw_p (tree t)
{
  if (!flag_exceptions)
    return false;

>    // Compute whether the result needs to be zext or sext'd.
>    ParameterAttributes RAttributes = HandleArgumentExtension(ReturnType);
> +  // Make sure all functions are marked nounwind if we aren't using exceptions.
> +  if (!flag_exceptions)
> +    RAttributes |= ParamAttr::NoUnwind;
> +
>    if (RAttributes != ParamAttr::None)
>      Attrs.push_back(ParamAttrsWithIndex::get(0, RAttributes));
>  
> @@ -1112,7 +1116,9 @@
>      RAttributes |= ParamAttr::NoReturn;
>  
>    // Check for 'nounwind' function attribute.
> -  if (flags & ECF_NOTHROW)
> +  // When flag_exceptions is not set (it is set by default in C++/ObjC++), 
> +  // don't unwind anything.
> +  if ((flags & ECF_NOTHROW) || !flag_exceptions)

I think this is wrong, because it means that declarations of external functions
will always be marked nounwind.  Consider compiling the following without -fexceptions:

extern void g(bool Allowed_To_Throw);
void f(void) {
  g(false);
}

and compiling the following with -fexceptions:

void g(bool Allowed_To_Throw) {
...
  if (Allowed_To_Throw)
    throw something;
  else
    abort();
...
}

then linking the two modules together.  Here g is a function that doesn't throw exceptions
unless Allowed_To_Throw is true.  With your patch g will be declared nounwind in the first
module but not in the second.  When you link them g may be marked nounwind in the linked
module which would be wrong (I don't know if this happens or not currently, but it doesn't
matter - we shouldn't rely on this kind of linker detail for correctness).

What I think should happen is:

(1) *calls* to g from the first module should be marked nounwind.  In fact all calls in
the first module should be marked nounwind.  This is already the case thanks to tree_could_throw_p.
(2) external declarations should not be marked nounwind.
(3) functions like f with a body compiled without -fexceptions should be marked nounwind.

So I think you should undo these changes, and instead add some code to StartFunctionBody
to add the nounwind attribute if !flag_exceptions.

Best wishes,

Duncan.

PS: I was wrong to think that llvm-gcc was already marking functions nounwind when compiled
with !flag_exceptions - it was prune_eh that was adding the marking.  Nice catch!



More information about the llvm-commits mailing list