I am from IBM Rational Purify, which is a memory error and leak detection tool.
When using our tool on Solaris 10 x86 with code build using gcc/g++4.0.4 and
gcc/g++4.1.1, we have seen some spurious uninitialized memory reads.

==============

Here is the sample C code:

#include <vector>
#include <algorithm>

int main()
{
    std::vector<double> x;
    x.push_back(1.0);
    std::sort(x.begin(), x.end());
}


==============

The UMRs from our software states the following:


UMR: Uninitialized memory read:
  * This is occurring while in thread 1:
        double* std::uninitialized_copy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double*, std::vec...
[stl_uninitialized.h:113]
        double*
std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, double >(__gnu_cxx::__normal_iterator<doubl...
[stl_uninitialized.h:254]
        std::vector<double, std::allocator<double>
>::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, double const&) [vector.tcc:279]
        std::vector<double, std::allocator<double> >::push_back(double const&)
[stl_vector.h:610]
        main           [BasicTest.C:7]
        _start         [crt1.o]
  * Reading 1 byte from 0x804761b on the stack of thread 1.
  * Address 0x804761b is       29 bytes below frame pointer in function double*
std::uninitialized_copy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double*, std::vec....

****  Purify instrumented ./a.out (pid 27426)  ****
UMR: Uninitialized memory read:
  * This is occurring while in thread 1:
        double* std::uninitialized_copy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double*, std::vec...
[stl_uninitialized.h:113]
        double*
std::__uninitialized_copy_a<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, double >(__gnu_cxx::__normal_iterator<doubl...
[stl_uninitialized.h:254]
        std::vector<double, std::allocator<double>
>::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, double const&) [vector.tcc:286]
        std::vector<double, std::allocator<double> >::push_back(double const&)
[stl_vector.h:610]
        main           [BasicTest.C:7]
        _start         [crt1.o]
  * Reading 1 byte from 0x804761b on the stack of thread 1.
  * Address 0x804761b is       29 bytes below frame pointer in function double*
std::uninitialized_copy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > > >(__gnu_cxx::__normal_iterator<double*, std::vec....

****  Purify instrumented ./a.out (pid 27426)  ****
UMR: Uninitialized memory read:
  * This is occurring while in thread 1:
         std::_Destroy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> >
>>(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, __gnu_cxx::__normal_iterator<double*,
std::vector<double, std::a... [stl_construct.h:155]
         std::_Destroy<__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >, double
>(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, __gnu_cxx::__normal_iterator<double*,
std::vector<doubl... [stl_construct.h:182]
        std::vector<double, std::allocator<double>
>::_M_insert_aux(__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >, double const&) [vector.tcc:298]
        std::vector<double, std::allocator<double> >::push_back(double const&)
[stl_vector.h:610]
        main           [BasicTest.C:7]
        _start         [crt1.o]
  * Reading 1 byte from 0x8047647 on the stack of thread 1.
  * Address 0x8047647 is       17 bytes below frame pointer in function 
std::_Destroy<__gnu_cxx::__normal_iterator<double*, std::vector<double,
std::allocator<double> > >>(__gnu_cxx::__normal_iterator<double*,
std::vector<double, std::allocator<double> > >,
__gnu_cxx::__normal_iterator<double*, std::vector<double, std::a....

****  Purify instrumented ./a.out (pid 27426)  ****
UMR: Uninitialized memory read:
  * This is occurring while in thread 1:
         std::_Destroy<double*>(double*, double*) [stl_construct.h:155]
         std::_Destroy<double*, double >(double*, double*,
std::allocator<double>) [stl_construct.h:182]
        std::vector<double, std::allocator<double> >::~vector()
[stl_vector.h:272]
        main           [BasicTest.C:8]
        _start         [crt1.o]
  * Reading 1 byte from 0x80476d7 on the stack of thread 1.
  * Address 0x80476d7 is       17 bytes below frame pointer in function 
std::_Destroy<double*>(double*, double*).

==============

In order to resolve these uninitialized memory reads (UMR), we had to make the
following change:

In gcc/4.0.4/include/c++/4.0.4/bits/cpp_type_traits.h,

change this:

struct __true_type { };
struct __false_type { };

to this:

struct __true_type {
  char dummy;
  __true_type(void) : dummy(0) {};
};
struct __false_type {
  char dummy;
  __false_type(void) : dummy(0) {};
};

The problem is that a struct with no data members is actually 1 byte in size,
consisting only of a pad byte, which the compiler does not initilalize.

When this struct is passed as a parameter, a UMR is detected.

The change above replaces the pad byte with an explicit dummy byte, that gets
initialized by the default constructor.

We are requesting that this change be made within the compiler so that our
customers using the product do not get reports from these UMRs coming from gcc.


-- 
           Summary: gcc source contains a struct with no data members
                    (actually 1 byte in size) and compiler does not
                    initialize it, resulting in IBM Rational Purify
                    reporting an Uninitialized Memory Read.
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: baolU at us dot ibm dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38107

Reply via email to