|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r61552 - trunk/libs/config/test
From: nielsdekker_at_[hidden]
Date: 2010-04-25 05:38:49
Author: niels_dekker
Date: 2010-04-25 05:38:48 EDT (Sun, 25 Apr 2010)
New Revision: 61552
URL: http://svn.boost.org/trac/boost/changeset/61552
Log:
Added value-initialization tests for heap objects, added private_int_holder class, did some cosmetics, added link to https://connect.microsoft.com/VisualStudio/feedback/details/484295
Text files modified:
trunk/libs/config/test/boost_no_com_value_init.ipp | 172 +++++++++++++++++++++++++++++++++------
1 files changed, 144 insertions(+), 28 deletions(-)
Modified: trunk/libs/config/test/boost_no_com_value_init.ipp
==============================================================================
--- trunk/libs/config/test/boost_no_com_value_init.ipp (original)
+++ trunk/libs/config/test/boost_no_com_value_init.ipp 2010-04-25 05:38:48 EDT (Sun, 25 Apr 2010)
@@ -69,6 +69,12 @@
{
};
+
+ // A POD aggregate struct derived from an empty struct.
+ // Similar to struct Foo1 from Microsoft Visual C++ bug report 484295,
+ // "VC++ does not value-initialize members of derived classes without
+ // user-declared constructor", reported in 2009 by Sylvester Hesp:
+ // https://connect.microsoft.com/VisualStudio/feedback/details/484295
struct derived_struct: empty_struct
{
int data;
@@ -166,18 +172,30 @@
}
+ class private_int_holder
+ {
+ private:
+ int m_data;
+
+ friend bool is_value_initialized(const private_int_holder& arg)
+ {
+ return arg.m_data == 0;
+ }
+ };
+
+
// Equivalent to the Stats class from GCC Bug 33916,
// "Default constructor fails to initialize array members", reported in 2007 by
// Michael Elizabeth Chastain: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33916
- class int_array_pair
+ class private_int_array_pair
{
- friend bool is_value_initialized(const int_array_pair& arg);
+ friend bool is_value_initialized(const private_int_array_pair& arg);
private:
int first[12];
int second[12];
};
- bool is_value_initialized(const int_array_pair& arg)
+ bool is_value_initialized(const private_int_array_pair& arg)
{
for ( unsigned i = 0; i < 12; ++i)
{
@@ -327,7 +345,7 @@
}
- typedef char _2d_char_array_type[2][3];
+ typedef char _2d_char_array_type[3][4];
bool is_value_initialized(const _2d_char_array_type& arg)
{
@@ -341,7 +359,7 @@
return true;
}
- typedef char _3d_char_array_type[2][3][4];
+ typedef char _3d_char_array_type[5][6][7];
bool is_value_initialized(const _3d_char_array_type& arg)
{
@@ -358,16 +376,53 @@
// For built-in types and enumerated types.
- template <typename T>
+ template <class T>
bool is_value_initialized(const T& arg)
{
return arg == 0;
}
+ // Wraps a heap object that it has allocated by doing new T().
+ template <class T>
+ class heap_object_wrapper
+ {
+ private:
+ T* const m_ptr;
+
+ // The following functions are intentionally left unimplemented
+ // (as if deleted, "= delete", in C++0x):
+ heap_object_wrapper(const heap_object_wrapper&);
+ void operator=(heap_object_wrapper);
+
+ public:
+ heap_object_wrapper()
+ :
+ m_ptr(new T())
+ {
+ }
+
+ ~heap_object_wrapper()
+ {
+ delete m_ptr;
+ }
+
+ bool is_wrapped_object_value_initialized() const
+ {
+ return (m_ptr != 0) && is_value_initialized(*m_ptr);
+ }
+ };
+
+ template <class T>
+ bool is_value_initialized(const heap_object_wrapper<T>& arg)
+ {
+ return arg.is_wrapped_object_value_initialized();
+ }
+
+
// Returns zero when the specified object is value-initializated, and one otherwise.
// Prints a message to standard output if the value-initialization has failed.
- template <typename T>
+ template <class T>
unsigned failed_to_value_initialized(const T& object, const char *const object_name)
{
if ( is_value_initialized(object) )
@@ -419,8 +474,8 @@
double m_double_array[2];
long double m_long_double;
long double m_long_double_array[2];
- void* m_ptr;
- void* m_ptr_array[2];
+ void* m_void_ptr;
+ void* m_void_ptr_array[2];
function_ptr_type m_function_ptr;
function_ptr_type m_function_ptr_array[2];
function_ptr_struct m_function_ptr_struct;
@@ -443,10 +498,12 @@
derived_struct m_derived_struct_array[2];
derived_int_struct m_derived_int_struct;
derived_int_struct m_derived_int_struct_array[2];
+ private_int_holder m_private_int_holder;
+ private_int_holder m_private_int_holder_array[2];
char_array_struct m_char_array_struct;
char_array_struct m_char_array_struct_array[2];
- int_array_pair m_int_array_pair;
- int_array_pair m_int_array_pair_array[2];
+ private_int_array_pair m_private_int_array_pair;
+ private_int_array_pair m_private_int_array_pair_array[2];
enum_holder_and_int m_enum_holder_and_int;
enum_holder_and_int m_enum_holder_and_int_array[2];
private_and_protected_int m_private_and_protected_int;
@@ -501,8 +558,8 @@
m_double_array(),
m_long_double(),
m_long_double_array(),
- m_ptr(),
- m_ptr_array(),
+ m_void_ptr(),
+ m_void_ptr_array(),
m_function_ptr(),
m_function_ptr_array(),
m_function_ptr_struct(),
@@ -525,10 +582,12 @@
m_derived_struct_array(),
m_derived_int_struct(),
m_derived_int_struct_array(),
+ m_private_int_holder(),
+ m_private_int_holder_array(),
m_char_array_struct(),
m_char_array_struct_array(),
- m_int_array_pair(),
- m_int_array_pair_array(),
+ m_private_int_array_pair(),
+ m_private_int_array_pair_array(),
m_enum_holder_and_int(),
m_enum_holder_and_int_array(),
m_private_and_protected_int(),
@@ -586,9 +645,9 @@
FAILED_TO_VALUE_INITIALIZE(m_long_double) +
FAILED_TO_VALUE_INITIALIZE(m_long_double_array[0]) +
FAILED_TO_VALUE_INITIALIZE(m_long_double_array[1]) +
- FAILED_TO_VALUE_INITIALIZE(m_ptr) +
- FAILED_TO_VALUE_INITIALIZE(m_ptr_array[0]) +
- FAILED_TO_VALUE_INITIALIZE(m_ptr_array[1]) +
+ FAILED_TO_VALUE_INITIALIZE(m_void_ptr) +
+ FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[0]) +
+ FAILED_TO_VALUE_INITIALIZE(m_void_ptr_array[1]) +
FAILED_TO_VALUE_INITIALIZE(m_function_ptr) +
FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[0]) +
FAILED_TO_VALUE_INITIALIZE(m_function_ptr_array[1]) +
@@ -622,12 +681,15 @@
FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct) +
FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[0]) +
FAILED_TO_VALUE_INITIALIZE(m_derived_int_struct_array[1]) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_holder) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[0]) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_holder_array[1]) +
FAILED_TO_VALUE_INITIALIZE(m_char_array_struct) +
FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[0]) +
FAILED_TO_VALUE_INITIALIZE(m_char_array_struct_array[1]) +
- FAILED_TO_VALUE_INITIALIZE(m_int_array_pair) +
- FAILED_TO_VALUE_INITIALIZE(m_int_array_pair_array[0]) +
- FAILED_TO_VALUE_INITIALIZE(m_int_array_pair_array[1]) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[0]) +
+ FAILED_TO_VALUE_INITIALIZE(m_private_int_array_pair_array[1]) +
FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int) +
FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[0]) +
FAILED_TO_VALUE_INITIALIZE(m_enum_holder_and_int_array[1]) +
@@ -659,6 +721,8 @@
{
typedef long double long_double_type;
typedef unsigned char unsigned_char_type;
+ typedef void* void_ptr_type;
+
const unsigned num_failures =
FAILED_TO_VALUE_INITIALIZE(enum_holder()) +
FAILED_TO_VALUE_INITIALIZE(enum_type()) +
@@ -671,6 +735,7 @@
FAILED_TO_VALUE_INITIALIZE(float()) +
FAILED_TO_VALUE_INITIALIZE(double()) +
FAILED_TO_VALUE_INITIALIZE(long_double_type()) +
+ FAILED_TO_VALUE_INITIALIZE(void_ptr_type()) +
FAILED_TO_VALUE_INITIALIZE(bit_field_struct()) +
FAILED_TO_VALUE_INITIALIZE(function_ptr_type()) +
FAILED_TO_VALUE_INITIALIZE(function_ptr_struct()) +
@@ -682,8 +747,9 @@
FAILED_TO_VALUE_INITIALIZE(derived_pod_struct()) +
FAILED_TO_VALUE_INITIALIZE(derived_struct()) +
FAILED_TO_VALUE_INITIALIZE(derived_int_struct()) +
+ FAILED_TO_VALUE_INITIALIZE(private_int_holder()) +
FAILED_TO_VALUE_INITIALIZE(char_array_struct()) +
- FAILED_TO_VALUE_INITIALIZE(int_array_pair()) +
+ FAILED_TO_VALUE_INITIALIZE(private_int_array_pair()) +
// IBM's XL V10.1.0.0 may fail to value-initialize a temporary of a non-POD
// type like enum_holder_and_int, virtual_destructor_holder, or non_pod_class,
// as appeared at the Boost Config/trunk regression page in April 2010.
@@ -704,6 +770,46 @@
return num_failures;
}
+ // Checks value-initialization of small heap objects.
+ // Returns the number of failures.
+ unsigned check_value_initialization_of_heap_objects()
+ {
+ const unsigned num_failures =
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_type>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned char>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<short>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<unsigned>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<float>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<double>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<long double>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<void*>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_type>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<function_ptr_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_type>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<member_function_ptr_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<bit_field_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_pod_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<derived_int_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<char_array_struct>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_holder>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_int_array_pair>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<enum_holder_and_int>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<private_and_protected_int>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<user_defined_destructor_holder>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<virtual_destructor_holder>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<non_pod_class>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<pod_struct_and_int_union>() ) +
+ FAILED_TO_VALUE_INITIALIZE( heap_object_wrapper<int_and_pod_struct_union>() );
+ return num_failures;
+ }
// Equivalent to the dirty_stack() function from GCC Bug 33916,
// "Default constructor fails to initialize array members", reported in 2007 by
@@ -718,12 +824,12 @@
}
+ // Checks value-initialization of a large number of data members of a
+ // temporary object, an object on the stack, an object on the heap;
+ // furthermore it checks value-initialization of a number of smaller
+ // temporary objects and heap objects.
int test()
{
- // Check value-initialization of the data members of a temporary object,
- // an object on the stack, an object on the heap, and a number of small
- // temporary objects.
-
unsigned total_num_failures = 0;
dirty_stack();
@@ -766,15 +872,25 @@
<< num_failures_of_temporaries << std::endl;
}
+ const unsigned num_failures_of_heap_objects = check_value_initialization_of_heap_objects();
+
+ total_num_failures += num_failures_of_heap_objects;
+ if ( total_num_failures > 0 )
+ {
+ std::cout << "- Number of failures of heap objects: "
+ << num_failures_of_heap_objects << std::endl;
+ }
+
if ( total_num_failures > 0 )
{
std::cout << "-- Total number of initialization failures ("
<< num_failures_of_a_temporary << '+'
<< num_failures_on_stack << '+'
<< num_failures_on_heap << '+'
- << num_failures_of_temporaries << "): "
+ << num_failures_of_temporaries << '+'
+ << num_failures_of_heap_objects << "): "
<< total_num_failures
- << "\nDetected by boost_no_complete_value_initialization::test() revision 18."
+ << "\nDetected by boost_no_complete_value_initialization::test() revision 19."
<< std::endl;
}
return static_cast<int>(total_num_failures);
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk