Skip to content

Commit

Permalink
Merging r234254:
Browse files Browse the repository at this point in the history
------------------------------------------------------------------------
r234254 | ericwf | 2015-04-06 16:03:01 -0700 (Mon, 06 Apr 2015) | 25 lines

[libcxxabi] Disallow Base to Derived conversions for catching pointers to members.

Summary:
I accidentally implemented the 4.11 [conv.mem] conversions for libc++abi in a recent patch. @majnemer pointed out that 5.13 [except.handle] only allows the pointer conversions in 4.10 and not those is 4.11. This patch no longer allows the following example code:

```c++
struct A {};
struct B : public A {};

int main() {
  try {
    throw (int A::*)0;
  } catch (int B::*) {
    // exception caught here.
  }
}
```

Reviewers: mclow.lists, jroelofs, majnemer

Reviewed By: majnemer

Subscribers: majnemer, cfe-commits

Differential Revision: http://reviews.llvm.org/D8845
------------------------------------------------------------------------

llvm-svn: 236866
  • Loading branch information
tstellarAMD committed May 8, 2015
1 parent 84c765b commit de42153
Show file tree
Hide file tree
Showing 4 changed files with 118 additions and 17 deletions.
8 changes: 3 additions & 5 deletions libcxxabi/src/private_typeinfo.cpp
Expand Up @@ -473,11 +473,9 @@ bool __pointer_to_member_type_info::can_catch(
if (is_equal(__context, thrown_pointer_type->__context, false))
return true;

__dynamic_cast_info info = {__context, 0, thrown_pointer_type->__context, -1, 0};
info.number_of_dst_type = 1;
__context->has_unambiguous_public_base(&info, adjustedPtr, public_path);
if (info.path_dst_ptr_to_static_ptr == public_path)
return true;
// [except.handle] does not allow the pointer-to-member conversions mentioned
// in [mem.conv] to take place. For this reason we don't check Derived->Base
// for Derived->Base conversions.

return false;
}
Expand Down
15 changes: 5 additions & 10 deletions libcxxabi/test/catch_member_data_pointer_01.cpp
Expand Up @@ -72,7 +72,7 @@ void test2()
}
}

// Check that Base -> Derived conversions are allowed.
// Check that Base -> Derived conversions are NOT allowed.
void test3()
{
try
Expand All @@ -90,14 +90,14 @@ void test3()
}
catch (der1)
{
assert(false);
}
catch (md1)
{
assert(false);
}
}

// Check that Base -> Derived conversions are allowed with different cv
// Check that Base -> Derived conversions NOT are allowed with different cv
// qualifiers.
void test4()
{
Expand All @@ -107,19 +107,14 @@ void test4()
assert(false);
}
catch (der2)
{
}
catch (...)
{
assert(false);
}

try
catch (der1)
{
throw &A::j;
assert(false);
}
catch (der1)
catch (md2)
{
}
catch (...)
Expand Down
110 changes: 110 additions & 0 deletions libcxxabi/test/catch_member_function_pointer_01.cpp
Expand Up @@ -18,6 +18,20 @@ struct A
typedef void (A::*mf1)();
typedef void (A::*mf2)() const;

struct B : public A
{
};

typedef void (B::*dmf1)();
typedef void (B::*dmf2)() const;

template <class Tp>
bool can_convert(Tp) { return true; }

template <class>
bool can_convert(...) { return false; }


void test1()
{
try
Expand Down Expand Up @@ -50,8 +64,104 @@ void test2()
}
}



void test_derived()
{
try
{
throw (mf1)0;
assert(false);
}
catch (dmf2)
{
assert(false);
}
catch (dmf1)
{
assert(false);
}
catch (mf1)
{
}

try
{
throw (mf2)0;
assert(false);
}
catch (dmf1)
{
assert(false);
}
catch (dmf2)
{
assert(false);
}
catch (mf2)
{
}

assert(!can_convert<mf1>((dmf1)0));
assert(!can_convert<mf2>((dmf1)0));
try
{
throw (dmf1)0;
assert(false);
}
catch (mf2)
{
assert(false);
}
catch (mf1)
{
assert(false);
}
catch (...)
{
}

assert(!can_convert<mf1>((dmf2)0));
assert(!can_convert<mf2>((dmf2)0));
try
{
throw (dmf2)0;
assert(false);
}
catch (mf2)
{
assert(false);
}
catch (mf1)
{
assert(false);
}
catch (...)
{
}
}

void test_void()
{
assert(!can_convert<void*>(&A::foo));
try
{
throw &A::foo;
assert(false);
}
catch (void*)
{
assert(false);
}
catch(...)
{
}
}

int main()
{
test1();
test2();
test_derived();
test_void();
}
2 changes: 0 additions & 2 deletions libcxxabi/test/catch_multi_level_pointer.pass.cpp
Expand Up @@ -140,6 +140,4 @@ int main()
generate_tests<int A::*, int A::*, 3>()();
generate_tests<int A::*, void, 2>()();
generate_tests<void, int A::*, 2>()();
generate_tests<int Base::*, int Derived::*, 2>()();
generate_tests<int Derived::*, int Base::*, 2>()();
}

0 comments on commit de42153

Please sign in to comment.