From 44d57a1d8bf1a4517c66f347bfa3065fb495affa Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Thu, 18 Feb 2016 23:18:01 +0100
Subject: [PATCH] Fix: prevented the binding illegal temporary to
optional
Older MSVC versions add illegal temporary when you want to assign from const integral value.
---
doc/11_development.qbk | 2 +-
doc/15_optional_references.qbk | 5 +-
doc/28_ref_optional_semantics.qbk | 2 +-
doc/90_dependencies.qbk | 8 +-
doc/91_relnotes.qbk | 1 +
.../optional_reference_binding.html | 26 +++--
...ailed_semantics___optional_references.html | 2 +-
doc/html/boost_optional/relnotes.html | 4 +
.../design_overview/the_interface.html | 6 +-
.../tutorial/in_place_factories.html | 6 +-
.../tutorial/optional_references.html | 106 +++++++++---------
doc/html/index.html | 4 +-
doc/html/optional/tutorial.html | 2 -
.../detail/optional_reference_spec.hpp | 28 ++++-
test/Jamfile.v2 | 1 +
test/optional_ref_assign_test_defs.hpp | 20 +---
...onal_test_ref_convert_assign_const_int.cpp | 6 +-
...ref_convert_assign_const_int_prevented.cpp | 32 ++++++
...al_test_ref_convert_assign_mutable_int.cpp | 3 +-
...tional_test_ref_convert_assign_non_int.cpp | 6 +-
20 files changed, 161 insertions(+), 109 deletions(-)
create mode 100644 test/optional_test_ref_convert_assign_const_int_prevented.cpp
diff --git a/doc/11_development.qbk b/doc/11_development.qbk
index 9e3ef44..de5d00d 100644
--- a/doc/11_development.qbk
+++ b/doc/11_development.qbk
@@ -228,7 +228,7 @@ For value access operations `optional<>` uses operators `*` and `->` to
lexically warn about the possibly uninitialized state appealing to the
familiar pointer semantics w.r.t. to null pointers.
-[warning
+[caution
However, it is particularly important to note that `optional<>` objects
are not pointers. [_`optional<>` is not, and does not model, a pointer].
]
diff --git a/doc/15_optional_references.qbk b/doc/15_optional_references.qbk
index 2f8b3c6..acb1226 100644
--- a/doc/15_optional_references.qbk
+++ b/doc/15_optional_references.qbk
@@ -1,6 +1,8 @@
[section Optional references]
+[section Overview]
+
This library allows the template parameter `T` to be of reference type:
`T&`, and to some extent, `T const&`.
@@ -21,7 +23,7 @@ will nonetheless refer to the same object.
* Value-access will actually provide access to the referenced object
rather than the reference itself.
-[warning On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
+[caution On compilers that do not conform to Standard C++ rules of reference binding, some operations on optional references are disabled in order to prevent subtle bugs. For more details see [link boost_optional.dependencies_and_portability.optional_reference_binding Dependencies and Portability section].]
[heading Rvalue references]
@@ -118,3 +120,4 @@ In such a scenario, you can assign the value itself directly, as in:
*opt=value;
[endsect]
+[endsect]
diff --git a/doc/28_ref_optional_semantics.qbk b/doc/28_ref_optional_semantics.qbk
index ca62937..31dc178 100644
--- a/doc/28_ref_optional_semantics.qbk
+++ b/doc/28_ref_optional_semantics.qbk
@@ -857,7 +857,7 @@ __SPACE__
* [*Postconditions:] `bool(*this) == bool(rhs)`.
-* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.tutorial.rebinding_semantics_for_assignment_of_optional_references here] for details.
+* [*Notes:] This behaviour is called ['rebinding semantics]. See [link boost_optional.tutorial.optional_references.rebinding_semantics_for_assignment_of_optional_references here] for details.
* [*Example:]
``
diff --git a/doc/90_dependencies.qbk b/doc/90_dependencies.qbk
index cf678dc..80e1803 100644
--- a/doc/90_dependencies.qbk
+++ b/doc/90_dependencies.qbk
@@ -30,17 +30,17 @@ The implementation uses the following other Boost modules:
[section Optional Reference Binding]
-On compilers that do not conform to Standard C++ rules of reference binding, operations on optional references might give adverse results: rather than binding a reference to a designated object they may create an unexpected temporary and bind to it. Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. On these compilers prefer using direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`:
+A number of compilers incorrectly treat const lvalues of integral type as rvalues, and create an illegal temporary when binding to an lvalue reference to const in some expressions. This could result in creating an optional lvalue reference that is in fact bound to an unexpected temporary rather than to the intended object. In order to prevent hard to find run-time bugs, this library performs compile-time checks to prevent expressions that would otherwise bind an optional reference to an unexpected temporary. As a consequence, on certain compilers certain pieces of functionality in optional references are missing. In order to maintain a portability of your code across diferent compilers, it is recommended that you only stick to the minimum portable interface of optional references: prefer direct-initialization and copy assignment of optional references to copy-initialization and assignment from `T&`:
const int i = 0;
optional or1;
- optional or2 = i; // not portable
- or1 = i; // not portable
+ optional or2 = i; // caution: not portable
+ or1 = i; // caution: not portable
optional or3(i); // portable
or1 = optional(i); // portable
-In order to check if your compiler correctly implements reference binding use this test program.
+Compilers known to have these deficiencies include GCC versions 4.2, 4.3, 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0. In order to check if your compiler correctly implements reference binding use this test program.
#include
diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index 1dced5f..4af88a5 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -16,6 +16,7 @@
* Now `boost::optional` is specialized for reference parameters. This addresses a couple of issues:
* the `sizeof` of optional reference is that of a pointer,
* some bugs connected to copying optional references are gone,
+ * all run-time bugs caused by incorrect reference binding on some compilers are now turned into compile-time errors,
* you can swap optional references: it is like swapping pointers: shalow, underlying objects are not affected,
* optional references to abstract types work.
* Documented nested typedefs ([@https://svn.boost.org/trac/boost/ticket/5193 Trac #5193]).
diff --git a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html
index eef5322..fbe4ba8 100644
--- a/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html
+++ b/doc/html/boost_optional/dependencies_and_portability/optional_reference_binding.html
@@ -28,24 +28,30 @@
Reference Binding
- On compilers that do not conform to Standard C++ rules of reference binding,
- operations on optional references might give adverse results: rather than
- binding a reference to a designated object they may create an unexpected
- temporary and bind to it. Compilers known to have these deficiencies include
- GCC versions 4.2, 4.3, 4.4, 4.5; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0,
- 11.0, 12.0. On these compilers prefer using direct-initialization and copy
- assignment of optional references to copy-initialization and assignment from
- T&:
+ A number of compilers incorrectly treat const lvalues of integral type as
+ rvalues, and create an illegal temporary when binding to an lvalue reference
+ to const in some expressions. This could result in creating an optional lvalue
+ reference that is in fact bound to an unexpected temporary rather than to
+ the intended object. In order to prevent hard to find run-time bugs, this
+ library performs compile-time checks to prevent expressions that would otherwise
+ bind an optional reference to an unexpected temporary. As a consequence,
+ on certain compilers certain pieces of functionality in optional references
+ are missing. In order to maintain a portability of your code across diferent
+ compilers, it is recommended that you only stick to the minimum portable
+ interface of optional references: prefer direct-initialization and copy assignment
+ of optional references to copy-initialization and assignment from T&:
constinti=0;optional<constint&>or1;
-optional<constint&>or2=i;// not portable
-or1=i;// not portable
+optional<constint&>or2=i;// caution: not portable
+or1=i;// caution: not portableoptional<constint&>or3(i);// portableor1=optional<constint&>(i);// portable
+ Compilers known to have these deficiencies include GCC versions 4.2, 4.3,
+ 4.4, 4.5, 5.1, 5.2; QCC 4.4.2; MSVC versions 8.0, 9.0, 10.0, 11.0, 12.0.
In order to check if your compiler correctly implements reference binding
use this test program.
some bugs connected to copying optional references are gone,
+
+ all run-time bugs caused by incorrect reference binding on some compilers
+ are now turned into compile-time errors,
+
you can swap optional references: it is like swapping pointers: shalow,
underlying objects are not affected,
diff --git a/doc/html/boost_optional/tutorial/design_overview/the_interface.html b/doc/html/boost_optional/tutorial/design_overview/the_interface.html
index 86c886f..77e17a5 100644
--- a/doc/html/boost_optional/tutorial/design_overview/the_interface.html
+++ b/doc/html/boost_optional/tutorial/design_overview/the_interface.html
@@ -142,10 +142,10 @@
about the possibly uninitialized state appealing to the familiar pointer
semantics w.r.t. to null pointers.
-
+
-
-
Warning
+
+
Caution
However, it is particularly important to note that optional<> objects are not pointers. optional<> is not, and does not model, a
diff --git a/doc/html/boost_optional/tutorial/in_place_factories.html b/doc/html/boost_optional/tutorial/in_place_factories.html
index ed63397..3b72041 100644
--- a/doc/html/boost_optional/tutorial/in_place_factories.html
+++ b/doc/html/boost_optional/tutorial/in_place_factories.html
@@ -6,7 +6,7 @@
-
+
@@ -20,7 +20,7 @@