This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[C++] init.c/build_new wrongly implements new-expression



vector new-expression implemmentation is buggy: it is translating 

	T* p = new T[N];

as 
	T* p = (T*) operator new(N * sizeof(T));
                                 ^^^^^^^^^^^^^
	// proceed to initialization.

instead of something equivalent to
	
	T* p = (T*) (numeric_limits<size_t>::max()/sizeof(T) > N ?
		     throw bad_alloc() 
		     : operator new(N * sizeof(T)));


So that the following ends up with a segmentation fault instead of
throwing a bad_alloc:

	double* p = new double[numeric_limits<size_t>::max()];
	p[0] = 0;


The bug is present in the EGCs-1.x series.
A testcase is attached.

-- Gaby

#include <cstddef>
#include <climits>
#include <iostream>

int main()
{
    const size_t magic = 28;	// on a 32-bit machine with 64-bit double

    const size_t n = 1u << magic;
    double* p = 0;
    try {
        p = new double[n];
    }
    catch (...) {
        std::cerr << "new double[" << n << "] failed!" << std::endl;
    }
    delete[] p;

    for (size_t i=magic+1; i<CHAR_BIT*sizeof(size_t); ++i) {
        const size_t m = 1u << i;
        try {
            p = new double[m];
        }
        catch (...) {
            continue;
        }

        std::cout << "new double[" << m << "] apparently succeeded\n"
                  << "Checking pointer validity..." << std::endl;
        for (size_t i=0; i<m; ++i) p[i] = 0;

        std::cout << "done" << std::endl;
        delete[] p;
        return 0;
    }
    std::cout << " Good news: the bug seems to have been fixed." <<
std::endl;
    return 0;

}



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]