[libcxxabi] r234254 - [libcxxabi] Disallow Base to Derived conversions for catching pointers to members.
Eric Fiselier
eric at efcs.ca
Mon Apr 6 16:03:02 PDT 2015
Author: ericwf
Date: Mon Apr 6 18:03:01 2015
New Revision: 234254
URL: http://llvm.org/viewvc/llvm-project?rev=234254&view=rev
Log:
[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
Modified:
libcxxabi/trunk/src/private_typeinfo.cpp
libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp
libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp
libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp
Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=234254&r1=234253&r2=234254&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Mon Apr 6 18:03:01 2015
@@ -479,11 +479,9 @@ bool __pointer_to_member_type_info::can_
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;
}
Modified: libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp?rev=234254&r1=234253&r2=234254&view=diff
==============================================================================
--- libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp (original)
+++ libcxxabi/trunk/test/catch_member_data_pointer_01.pass.cpp Mon Apr 6 18:03:01 2015
@@ -72,7 +72,7 @@ void test2()
}
}
-// Check that Base -> Derived conversions are allowed.
+// Check that Base -> Derived conversions are NOT allowed.
void test3()
{
try
@@ -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()
{
@@ -108,18 +108,13 @@ void test4()
}
catch (der2)
{
- }
- catch (...)
- {
assert(false);
}
-
- try
+ catch (der1)
{
- throw &A::j;
assert(false);
}
- catch (der1)
+ catch (md2)
{
}
catch (...)
Modified: libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp?rev=234254&r1=234253&r2=234254&view=diff
==============================================================================
--- libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp (original)
+++ libcxxabi/trunk/test/catch_member_function_pointer_01.pass.cpp Mon Apr 6 18:03:01 2015
@@ -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
@@ -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();
}
Modified: libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp?rev=234254&r1=234253&r2=234254&view=diff
==============================================================================
--- libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp (original)
+++ libcxxabi/trunk/test/catch_multi_level_pointer.pass.cpp Mon Apr 6 18:03:01 2015
@@ -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>()();
}
More information about the cfe-commits
mailing list