diff options
-rw-r--r-- | src/expr/node_builder.h | 25 | ||||
-rw-r--r-- | src/main/driver_unified.cpp | 14 | ||||
-rw-r--r-- | src/main/main.cpp | 1 | ||||
-rw-r--r-- | src/main/main.h | 4 | ||||
-rw-r--r-- | src/main/util.cpp | 10 | ||||
-rw-r--r-- | test/unit/expr/node_manager_white.h | 19 |
6 files changed, 63 insertions, 10 deletions
diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h index f6aa1920d..458bd25fa 100644 --- a/src/expr/node_builder.h +++ b/src/expr/node_builder.h @@ -1,11 +1,11 @@ /********************* */ /*! \file node_builder.h ** \verbatim - ** Original author: mdeters - ** Major contributors: dejan - ** Minor contributors (to current version): taking, cconway - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009-2012 New York University and The University of Iowa + ** Original author: Dejan Jovanović <dejan.jovanovic@gmail.com> + ** Major contributors: Morgan Deters <mdeters@cs.nyu.edu> + ** Minor contributors (to current version): Tim King <taking@cs.nyu.edu>, Christopher L. Conway <christopherleeconway@gmail.com> + ** This file is part of the CVC4 project. + ** Copyright (c) 2009-2013 New York University and The University of Iowa ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** @@ -277,7 +277,9 @@ class NodeBuilder { * double-decremented later (on destruction/clear). */ inline void realloc() { - realloc(d_nvMaxChildren * 2); + size_t newSize = 2 * size_t(d_nvMaxChildren); + size_t hardLimit = (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN) - 1; + realloc(EXPECT_FALSE( newSize > hardLimit ) ? hardLimit : newSize); } /** @@ -662,6 +664,7 @@ public: expr::NodeValue* nv = n.d_nv; nv->inc(); d_nv->d_children[d_nv->d_nchildren++] = nv; + Assert(d_nv->d_nchildren <= d_nvMaxChildren); return *this; } @@ -674,6 +677,7 @@ public: expr::NodeValue* nv = typeNode.d_nv; nv->inc(); d_nv->d_children[d_nv->d_nchildren++] = nv; + Assert(d_nv->d_nchildren <= d_nvMaxChildren); return *this; } @@ -771,6 +775,9 @@ template <unsigned nchild_thresh> void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { Assert( toSize > d_nvMaxChildren, "attempt to realloc() a NodeBuilder to a smaller/equal size!" ); + Assert( toSize < (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN), + "attempt to realloc() a NodeBuilder to size %u (beyond hard limit of %u)", + toSize, (1lu << __CVC4__EXPR__NODE_VALUE__NBITS__NCHILDREN) - 1 ); if(EXPECT_FALSE( nvIsAllocated() )) { // Ensure d_nv is not modified on allocation failure @@ -783,6 +790,7 @@ void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { throw std::bad_alloc(); } d_nvMaxChildren = toSize; + Assert(d_nvMaxChildren == toSize);//overflow check // Here, the copy (between two heap-allocated buffers) has already // been done for us by the std::realloc(). d_nv = newBlock; @@ -795,6 +803,7 @@ void NodeBuilder<nchild_thresh>::realloc(size_t toSize) { throw std::bad_alloc(); } d_nvMaxChildren = toSize; + Assert(d_nvMaxChildren == toSize);//overflow check d_nv = newBlock; d_nv->d_id = d_inlineNv.d_id; @@ -1276,10 +1285,14 @@ void NodeBuilder<nchild_thresh>::internalCopy(const NodeBuilder<N>& nb) { return; } + bool realloced = false; if(nb.d_nvMaxChildren > d_nvMaxChildren) { + realloced = true; realloc(nb.d_nvMaxChildren); } + Assert(nb.d_nvMaxChildren <= d_nvMaxChildren); + Assert(nb.d_nv->nv_end() - nb.d_nv->nv_begin() <= d_nvMaxChildren, "realloced:%s, d_nvMax:%u, size:%u, nc:%u", realloced ? "true" : "false", d_nvMaxChildren, nb.d_nv->nv_end() - nb.d_nv->nv_begin(), nb.d_nv->getNumChildren()); std::copy(nb.d_nv->nv_begin(), nb.d_nv->nv_end(), d_nv->nv_begin()); diff --git a/src/main/driver_unified.cpp b/src/main/driver_unified.cpp index b429ad0c2..c27179ee5 100644 --- a/src/main/driver_unified.cpp +++ b/src/main/driver_unified.cpp @@ -43,6 +43,7 @@ #include "util/output.h" #include "util/dump.h" #include "util/result.h" +#include "util/statistics_registry.h" using namespace std; using namespace CVC4; @@ -63,6 +64,9 @@ namespace CVC4 { /** A pointer to the CommandExecutor (the signal handlers need it) */ CVC4::main::CommandExecutor* pExecutor = NULL; + /** A pointer to the totalTime driver stat (the signal handlers need it) */ + CVC4::TimerStat* pTotalTime = NULL; + }/* CVC4::main namespace */ }/* CVC4 namespace */ @@ -84,8 +88,8 @@ void printUsage(Options& opts, bool full) { int runCvc4(int argc, char* argv[], Options& opts) { // Timer statistic - TimerStat s_totalTime("totalTime"); - s_totalTime.start(); + pTotalTime = new TimerStat("totalTime"); + pTotalTime->start(); // For the signal handlers' benefit pOptions = &opts; @@ -216,7 +220,7 @@ int runCvc4(int argc, char* argv[], Options& opts) { int returnValue = 0; { // Timer statistic - RegisterStatistic statTotalTime(&pExecutor->getStatisticsRegistry(), &s_totalTime); + RegisterStatistic statTotalTime(&pExecutor->getStatisticsRegistry(), pTotalTime); // Filename statistics ReferenceStat< const char* > s_statFilename("filename", filename); @@ -304,7 +308,7 @@ int runCvc4(int argc, char* argv[], Options& opts) { ReferenceStat< Result > s_statSatResult("sat/unsat", result); RegisterStatistic statSatResultReg(&pExecutor->getStatisticsRegistry(), &s_statSatResult); - s_totalTime.stop(); + pTotalTime->stop(); // Set the global executor pointer to NULL first. If we get a // signal while dumping statistics, we don't want to try again. @@ -334,9 +338,11 @@ int runCvc4(int argc, char* argv[], Options& opts) { // On exceptional exit, these are leaked, but that's okay... they // need to be around in that case for main() to print statistics. + delete pTotalTime; delete pExecutor; delete exprMgr; + pTotalTime = NULL; pExecutor = NULL; return returnValue; diff --git a/src/main/main.cpp b/src/main/main.cpp index 3e45b4f14..a83baf45f 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -66,6 +66,7 @@ int main(int argc, char* argv[]) { #endif *opts[options::err] << "CVC4 Error:" << endl << e << endl; if(opts[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(*opts[options::err]); } } diff --git a/src/main/main.h b/src/main/main.h index 5b202c532..56cd866da 100644 --- a/src/main/main.h +++ b/src/main/main.h @@ -23,6 +23,7 @@ #include "util/exception.h" #include "util/statistics.h" #include "util/tls.h" +#include "util/statistics_registry.h" #include "cvc4autoconfig.h" #ifndef __CVC4__MAIN__MAIN_H @@ -42,6 +43,9 @@ extern const char* progName; /** A reference for use by the signal handlers to print statistics */ extern CVC4::main::CommandExecutor* pExecutor; +/** A reference for use by the signal handlers to print statistics */ +extern CVC4::TimerStat* pTotalTime; + /** * If true, will not spin on segfault even when CVC4_DEBUG is on. * Useful for nightly regressions, noninteractive performance runs diff --git a/src/main/util.cpp b/src/main/util.cpp index 9ade23630..a6fcddf3b 100644 --- a/src/main/util.cpp +++ b/src/main/util.cpp @@ -65,6 +65,7 @@ void* cvc4StackBase; void timeout_handler(int sig, siginfo_t* info, void*) { fprintf(stderr, "CVC4 interrupted by timeout.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -74,6 +75,7 @@ void timeout_handler(int sig, siginfo_t* info, void*) { void sigint_handler(int sig, siginfo_t* info, void*) { fprintf(stderr, "CVC4 interrupted by user.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -99,6 +101,7 @@ void segv_handler(int sig, siginfo_t* info, void* c) { if(segvNoSpin) { fprintf(stderr, "No-spin requested, aborting...\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -119,6 +122,7 @@ void segv_handler(int sig, siginfo_t* info, void* c) { cerr << "Looks like a NULL pointer was dereferenced." << endl; } if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -132,6 +136,7 @@ void ill_handler(int sig, siginfo_t* info, void*) { if(segvNoSpin) { fprintf(stderr, "No-spin requested, aborting...\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -145,6 +150,7 @@ void ill_handler(int sig, siginfo_t* info, void*) { #else /* CVC4_DEBUG */ fprintf(stderr, "CVC4 executed an illegal instruction.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } abort(); @@ -171,6 +177,7 @@ void cvc4unexpected() { if(segvNoSpin) { fprintf(stderr, "No-spin requested.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } set_terminate(default_terminator); @@ -184,6 +191,7 @@ void cvc4unexpected() { #else /* CVC4_DEBUG */ fprintf(stderr, "CVC4 threw an \"unexpected\" exception.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } set_terminate(default_terminator); @@ -197,6 +205,7 @@ void cvc4terminate() { "Perhaps an exception was thrown during stack unwinding. " "(Don't do that.)\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } default_terminator(); @@ -205,6 +214,7 @@ void cvc4terminate() { "CVC4 was terminated by the C++ runtime.\n" "Perhaps an exception was thrown during stack unwinding.\n"); if((*pOptions)[options::statistics] && pExecutor != NULL) { + pTotalTime->stop(); pExecutor->flushStatistics(cerr); } default_terminator(); diff --git a/test/unit/expr/node_manager_white.h b/test/unit/expr/node_manager_white.h index 3be95ad87..57fb8f445 100644 --- a/test/unit/expr/node_manager_white.h +++ b/test/unit/expr/node_manager_white.h @@ -54,4 +54,23 @@ public: Node m = d_nm->mkConst(i); TS_ASSERT_EQUALS(n.getId(), m.getId()); } + + void testOversizedNodeBuilder() { + NodeBuilder<> nb; + + TS_ASSERT_THROWS_NOTHING(nb.realloc(15)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(25)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(256)); +#ifdef CVC4_ASSERTIONS + TS_ASSERT_THROWS(nb.realloc(100), AssertionException); +#endif /* CVC4_ASSERTIONS */ + TS_ASSERT_THROWS_NOTHING(nb.realloc(257)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(4000)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(20000)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(60000)); + TS_ASSERT_THROWS_NOTHING(nb.realloc(65535)); +#ifdef CVC4_ASSERTIONS + TS_ASSERT_THROWS(nb.realloc(65536), AssertionException); +#endif /* CVC4_ASSERTIONS */ + } }; |