From 45f7564db29a3bafa5dfd8c41396843493d1378a Mon Sep 17 00:00:00 2001 From: K-ballo Date: Mon, 9 Jun 2014 19:50:22 -0300 Subject: [PATCH] Disable binding ref to temporaries when rvalue references are supported --- include/boost/core/ref.hpp | 36 ++++++++++++++++++++++++++++++++++++ test/Jamfile.v2 | 3 +++ test/ref_rv_fail1.cpp | 21 +++++++++++++++++++++ test/ref_rv_fail2.cpp | 15 +++++++++++++++ test/ref_rv_fail3.cpp | 25 +++++++++++++++++++++++++ 5 files changed, 100 insertions(+) create mode 100644 test/ref_rv_fail1.cpp create mode 100644 test/ref_rv_fail2.cpp create mode 100644 test/ref_rv_fail3.cpp diff --git a/include/boost/core/ref.hpp b/include/boost/core/ref.hpp index 8a1acc5..c8e7c6a 100644 --- a/include/boost/core/ref.hpp +++ b/include/boost/core/ref.hpp @@ -66,6 +66,14 @@ public: */ BOOST_FORCEINLINE explicit reference_wrapper(T& t): t_(boost::addressof(t)) {} +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + /** + @remark Construction from a temporary object is disabled. + */ + BOOST_DELETED_FUNCTION(reference_wrapper(T&& t)) +public: +# endif + /** @return The stored reference. @remark Does not throw. @@ -144,6 +152,34 @@ template BOOST_FORCEINLINE reference_wrapper BOOST_REF_CONST c # undef BOOST_REF_CONST +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +/** + @cond +*/ +# if defined(BOOST_NO_CXX11_DELETED_FUNCTIONS) +# define BOOST_REF_DELETE +# else +# define BOOST_REF_DELETE = delete +# endif +/** + @endcond +*/ + +/** + @remark Construction from a temporary object is disabled. +*/ +template void ref(T const&& t) BOOST_REF_DELETE; + +/** + @remark Construction from a temporary object is disabled. +*/ +template void cref(T const&& t) BOOST_REF_DELETE; + +# undef BOOST_REF_DELETE + +# endif + // is_reference_wrapper /** diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index e44688e..f98ca08 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -19,6 +19,9 @@ compile-fail checked_delete_fail2.cpp ; compile ref_ct_test.cpp ; run ref_test.cpp ; +compile-fail ref_rv_fail1.cpp ; +compile-fail ref_rv_fail2.cpp ; +compile-fail ref_rv_fail3.cpp ; run eif_constructors.cpp ; run eif_dummy_arg_disambiguation.cpp ; diff --git a/test/ref_rv_fail1.cpp b/test/ref_rv_fail1.cpp new file mode 100644 index 0000000..6e6f706 --- /dev/null +++ b/test/ref_rv_fail1.cpp @@ -0,0 +1,21 @@ +// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy +// Copyright 2014 Agustin Berge +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +int main() +{ + boost::reference_wrapper r(1); // this should produce an ERROR + + return 0; +} + +# else +# error To fail, this test requires rvalue references +# endif diff --git a/test/ref_rv_fail2.cpp b/test/ref_rv_fail2.cpp new file mode 100644 index 0000000..1ca8222 --- /dev/null +++ b/test/ref_rv_fail2.cpp @@ -0,0 +1,15 @@ +// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy +// Copyright 2014 Agustin Berge +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +int main() +{ + boost::reference_wrapper r = boost::ref(2); // this should produce an ERROR + + return 0; +} diff --git a/test/ref_rv_fail3.cpp b/test/ref_rv_fail3.cpp new file mode 100644 index 0000000..d93cb4e --- /dev/null +++ b/test/ref_rv_fail3.cpp @@ -0,0 +1,25 @@ +// Copyright 2002-2004 David Abrahams and Aleksey Gurtovoy +// Copyright 2014 Agustin Berge +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +#include + +# if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + +struct X {}; + +X const crv() { return X(); } + +int main() +{ + boost::reference_wrapper r = boost::ref(crv()); // this should produce an ERROR + + return 0; +} + +# else +# error To fail, this test requires rvalue references +# endif