blob: 78ededbea8e8ec78c738bf361c0921574e535d19 [file] [log] [blame]
Benoit Jacobdcbc9852011-10-16 16:12:19 -04001// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>
5//
6// Eigen is free software; you can redistribute it and/or
7// modify it under the terms of the GNU Lesser General Public
8// License as published by the Free Software Foundation; either
9// version 3 of the License, or (at your option) any later version.
10//
11// Alternatively, you can redistribute it and/or
12// modify it under the terms of the GNU General Public License as
13// published by the Free Software Foundation; either version 2 of
14// the License, or (at your option) any later version.
15//
16// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19// GNU General Public License for more details.
20//
21// You should have received a copy of the GNU Lesser General Public
22// License and a copy of the GNU General Public License along with
23// Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25#include "main.h"
26
27#define VERIFY_THROWS_BADALLOC(a) { \
28 bool threw = false; \
29 try { \
30 a; \
31 } \
32 catch (std::bad_alloc&) { threw = true; } \
33 VERIFY(threw && "should have thrown bad_alloc: " #a); \
34 }
35
36typedef DenseIndex Index;
37
38template<typename MatrixType>
39void triggerMatrixBadAlloc(Index rows, Index cols)
40{
41 VERIFY_THROWS_BADALLOC( MatrixType m(rows, cols) );
42 VERIFY_THROWS_BADALLOC( MatrixType m; m.resize(rows, cols) );
43 VERIFY_THROWS_BADALLOC( MatrixType m; m.conservativeResize(rows, cols) );
44}
45
46template<typename VectorType>
47void triggerVectorBadAlloc(Index size)
48{
49 VERIFY_THROWS_BADALLOC( VectorType v(size) );
50 VERIFY_THROWS_BADALLOC( VectorType v; v.resize(size) );
51 VERIFY_THROWS_BADALLOC( VectorType v; v.conservativeResize(size) );
52}
53
54void test_sizeoverflow()
55{
56 // there are 2 levels of overflow checking. first in PlainObjectBase.h we check for overflow in rows*cols computations.
57 // this is tested in tests of the form times_itself_gives_0 * times_itself_gives_0
58 // Then in Memory.h we check for overflow in size * sizeof(T) computations.
59 // this is tested in tests of the form times_4_gives_0 * sizeof(float)
60
61 size_t times_itself_gives_0 = size_t(1) << (8 * sizeof(Index) / 2);
62 VERIFY(times_itself_gives_0 * times_itself_gives_0 == 0);
63
64 size_t times_4_gives_0 = size_t(1) << (8 * sizeof(Index) - 2);
65 VERIFY(times_4_gives_0 * 4 == 0);
66
67 size_t times_8_gives_0 = size_t(1) << (8 * sizeof(Index) - 3);
68 VERIFY(times_8_gives_0 * 8 == 0);
69
70 triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0, times_itself_gives_0);
71 triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0 / 4, times_itself_gives_0);
72 triggerMatrixBadAlloc<MatrixXf>(times_4_gives_0, 1);
73
74 triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0, times_itself_gives_0);
75 triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0 / 8, times_itself_gives_0);
76 triggerMatrixBadAlloc<MatrixXd>(times_8_gives_0, 1);
77
78 triggerVectorBadAlloc<VectorXf>(times_4_gives_0);
79
80 triggerVectorBadAlloc<VectorXd>(times_8_gives_0);
81}