diff --git a/src/lib/access-casted.hpp b/src/lib/access-casted.hpp index b4ec5462f..e549a9560 100644 --- a/src/lib/access-casted.hpp +++ b/src/lib/access-casted.hpp @@ -88,8 +88,9 @@ namespace util { template struct can_take_address { - static constexpr bool value = !std::is_pointer::type>::value - && std::is_pointer::type>::value; + static constexpr bool value = !std::is_rvalue_reference::value + && !std::is_pointer::type>::value + && std::is_pointer::type>::value; }; template diff --git a/tests/library/meta/access-casted-test.cpp b/tests/library/meta/access-casted-test.cpp index 22a5a98d2..6e054334b 100644 --- a/tests/library/meta/access-casted-test.cpp +++ b/tests/library/meta/access-casted-test.cpp @@ -126,19 +126,25 @@ namespace test { cout << "can_use_conversion = " << can_use_conversion::value < = " << can_use_dynamic_downcast::value <" << AccessCasted::access(d) <" << AccessCasted::access(rD) <::access(move(dd1)); // does not compile since it would be dangerous; we can't take a l-value ref + // AccessCasted::access(rD); // from a r-value (move) reference and we can't move a l-value ref + // AccessCasted::access(d); // cout << "=== build a value object ==="<" << AccessCasted::access(d) <" << AccessCasted::access(rD) <" << AccessCasted::access(move(dd1)) <" << AccessCasted::access(d) <" << AccessCasted::access(rD) <::access(move(dd1)); // should not take value moved by r-value-ref as pointer, otherwise the moved object would be lost cout << "=== dereference a pointer ==="<" << AccessCasted::access(pD) <" << AccessCasted::access(move(pdd1)) <::access(pNull)); + VERIFY_ERROR(BOTTOM_VALUE, AccessCasted::access(pNull)); // run-time NULL check + // AccessCasted::access(pD); // should not move away a value accessed through a pointer, there might be other users cout << "=== const correctness ==="<" << AccessCasted::access(d) <" << AccessCasted::access(rcD) <" << AccessCasted::access(pcD) <" << AccessCasted::access(pcD) <" << AccessCasted::access(rcD) <" << AccessCasted::access(move(cD1)) <::access(rcD); // normal ref from const ref is not const correct + // AccessCasted::access(rcD); // likewise, regular pointer from const ref prohibited + // AccessCasted::access(pcD); // likewise, regular ref from pointer-to-const + // AccessCasted::access(pcD); // and regular pointer from pointer-to-const + // AccessCasted::access(rcD); // ruled out already because moving a reference is invalid + // AccessCasted::access(pcD); // ruled out already because moving a dereferenced pointer is invalid + // AccessCasted::access(move(cD)); // ruled out already because taking reference from moved value is invalid + // AccessCasted::access(move(cD)); // and same for taking pointer from a moved value. cout << "=== work cases: actual conversions ==="<" << AccessCasted::access(rB) <