libcxxabi PATCH for PR17221 - can't catch virtual base class when throwing NULL

Justin Bogner mail at justinbogner.com
Wed Feb 5 13:15:53 PST 2014


Marshall Clow <mclow.lists at gmail.com> writes:
> Again, we have to treat NULL specially- who knew? ;-)
> More tests, too.
>
> http://llvm.org/bugs/show_bug.cgi?id=17221
>
> Thanks to Howard for the suggested fix.

I'll defer to Howard on the actual change - I just have a couple of
stylistic nits:

> Index: src/private_typeinfo.cpp
> ===================================================================
> --- src/private_typeinfo.cpp	(revision 200864)
> +++ src/private_typeinfo.cpp	(working copy)
> @@ -301,17 +301,20 @@
>                                                      void* adjustedPtr,
>                                                      int path_below) const
>  {
> -    ptrdiff_t offset_to_base = __offset_flags >> __offset_shift;
> -    if (__offset_flags & __virtual_mask)
> +    ptrdiff_t offset_to_base = 0;
> +    if (adjustedPtr != nullptr)
>      {
> -        const char* vtable = *static_cast<const char*const*>(adjustedPtr);
> -        offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
> +        offset_to_base = __offset_flags >> __offset_shift;
> +        if (__offset_flags & __virtual_mask)
> +        {
> +            const char* vtable = *static_cast<const char*const*>(adjustedPtr);
> +            offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);

80 column?

> +        }
>      }
> -    __base_type->has_unambiguous_public_base(info,
> -                                             static_cast<char*>(adjustedPtr) + offset_to_base,
> -                                             (__offset_flags & __public_mask) ?
> -                                                 path_below :
> -                                                 not_public_path);
> +    __base_type->has_unambiguous_public_base(
> +            info,
> +            static_cast<char*>(adjustedPtr) + offset_to_base,
> +            (__offset_flags & __public_mask) ?path_below :not_public_path);

The conditional operator should have spaces on both sides of ? and :,
like so:

    (__offset_flags & __public_mask) ? path_below : not_public_path);

>  }
>  
>  void
> @@ -358,7 +361,8 @@
>                                 void*& adjustedPtr) const
>  {
>      // Do the dereference adjustment
> -    adjustedPtr = *static_cast<void**>(adjustedPtr);
> +    if ( adjustedPtr != NULL )

No spaces inside the if's parens

> +        adjustedPtr = *static_cast<void**>(adjustedPtr);
>      // bullets 1 and 4
>      if (__pbase_type_info::can_catch(thrown_type, adjustedPtr))
>          return true;
> Index: test/catch_ptr_02.cpp
> ===================================================================
> --- test/catch_ptr_02.cpp	(revision 200864)
> +++ test/catch_ptr_02.cpp	(working copy)
> @@ -130,17 +130,33 @@
>  }
>  
>  
> -struct vA {};
> -struct vC : virtual public vA {};
> +struct vBase {};
> +struct vDerived : virtual public vBase {};
>  
>  void test8 ()
>  {
>      try
>      {
> -        throw (vC*)0;
> +        throw new vDerived;
>          assert(false);
>      }
> -    catch (vA *p) {
> +    catch (vBase *p) {
> +        assert(p != 0);
> +    }
> +    catch (...)
> +    {
> +        assert (false);
> +    }
> +}
> +
> +void test9 ()
> +{
> +    try
> +    {
> +        throw nullptr;
> +        assert(false);
> +    }
> +    catch (vBase *p) {
>          assert(p == 0);
>      }
>      catch (...)
> @@ -149,6 +165,22 @@
>      }
>  }
>  
> +void test10 ()
> +{
> +    try
> +    {
> +        throw (vDerived*)0;
> +        assert(false);
> +    }
> +    catch (vBase *p) {
> +        assert(p == 0);
> +    }
> +    catch (...)
> +    {
> +        assert (false);
> +    }
> +}
> +
>  int main()
>  {
>      test1();
> @@ -158,4 +190,7 @@
>      test5();
>      test6();
>      test7();
> +    test8();
> +    test9();
> +    test10();
>  }
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list