fix ASAN reports about mismatched emplace new/delete

* spot/misc/bitvect.cc, spot/misc/bitvect.hh, spot/tl/formula.cc,
spot/tl/formula.hh: Here.
* NEWS: Mention the bug.
This commit is contained in:
Alexandre Duret-Lutz 2017-11-17 17:22:02 +01:00
parent 933c4cde0c
commit d89579321f
5 changed files with 32 additions and 17 deletions

2
NEWS
View file

@ -209,6 +209,8 @@ New in spot 2.4.2.dev (not yet released)
- couvreur99_new() leaked memory when processing TωA that allocate - couvreur99_new() leaked memory when processing TωA that allocate
states. states.
- Some mismatched placement-new/delete reported by ASAN were fixed.
New in spot 2.4.2 (2017-11-07) New in spot 2.4.2 (2017-11-07)
Tools: Tools:

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014 Laboratoire de Recherche et Développement // Copyright (C) 2013, 2014, 2017 Laboratoire de Recherche et Développement
// de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -108,8 +108,8 @@ namespace spot
// Allocate some memory for the bitvect. The instance // Allocate some memory for the bitvect. The instance
// already contains one int of local_storage_, but // already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table. // we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect) void* mem = ::operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t)); + (n - 1) * sizeof(bitvect::block_t));
bitvect* res = new(mem) bitvect(size_, n, true); bitvect* res = new(mem) bitvect(size_, n, true);
memcpy(res->storage_, storage_, res->block_count_ * sizeof(block_t)); memcpy(res->storage_, storage_, res->block_count_ * sizeof(block_t));
return res; return res;
@ -143,8 +143,8 @@ namespace spot
// Allocate some memory for the bitvect. The instance // Allocate some memory for the bitvect. The instance
// already contains one int of local_storage_, but // already contains one int of local_storage_, but
// we allocate n-1 more so that we store the table. // we allocate n-1 more so that we store the table.
void* mem = operator new(sizeof(bitvect) void* mem = ::operator new(sizeof(bitvect)
+ (n - 1) * sizeof(bitvect::block_t)); + (n - 1) * sizeof(bitvect::block_t));
return new(mem) bitvect(bitcount, n); return new(mem) bitvect(bitcount, n);
} }
@ -156,7 +156,7 @@ namespace spot
size_t bvsize = sizeof(bitvect) + (n - 1) * sizeof(bitvect::block_t); size_t bvsize = sizeof(bitvect) + (n - 1) * sizeof(bitvect::block_t);
// Allocate the bitvect_array with enough space at the end // Allocate the bitvect_array with enough space at the end
// to store all bitvect instances. // to store all bitvect instances.
void* mem = operator new(sizeof(bitvect_array) + bvsize * vectcount); void* mem = ::operator new(sizeof(bitvect_array) + bvsize * vectcount);
bitvect_array* bva = new(mem) bitvect_array(vectcount, bvsize); bitvect_array* bva = new(mem) bitvect_array(vectcount, bvsize);
// Initialize all the bitvect instances. // Initialize all the bitvect instances.
for (size_t i = 0; i < vectcount; ++i) for (size_t i = 0; i < vectcount; ++i)

View file

@ -1,6 +1,6 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2013, 2014, 2015, 2016 Laboratoire de Recherche et // Copyright (C) 2013-2017 Laboratoire de Recherche et Développement
// Développement de l'Epita (LRDE). // de l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
// //
@ -76,6 +76,12 @@ namespace spot
bitvect* clone() const; bitvect* clone() const;
void operator delete(void *ptr)
{
// This object was allocated using a placement new.
::operator delete(ptr);
}
void make_empty() void make_empty()
{ {
size_ = 0; size_ = 0;
@ -398,6 +404,12 @@ namespace spot
at(i).~bitvect(); at(i).~bitvect();
} }
void operator delete(void *ptr)
{
// This object was allocated using a placement new.
::operator delete(ptr);
}
/// The number of bitvect in the array. /// The number of bitvect in the array.
size_t size() const size_t size() const
{ {

View file

@ -124,7 +124,7 @@ namespace spot
} }
} }
const fnode* fnode::unique(const fnode* f) const fnode* fnode::unique(fnode* f)
{ {
auto ires = m.uniq.emplace(f); auto ires = m.uniq.emplace(f);
if (!ires.second) if (!ires.second)
@ -132,7 +132,8 @@ namespace spot
//(*ires.first)->dump(std::cerr << "UNI: ") << '\n'; //(*ires.first)->dump(std::cerr << "UNI: ") << '\n';
for (auto c: *f) for (auto c: *f)
c->destroy(); c->destroy();
delete f; f->~fnode();
::operator delete(f);
return (*ires.first)->clone(); return (*ires.first)->clone();
} }
//f->dump(std::cerr << "INS: ") << '\n'; //f->dump(std::cerr << "INS: ") << '\n';
@ -158,7 +159,8 @@ namespace spot
for (auto c: *this) for (auto c: *this)
c->destroy(); c->destroy();
} }
delete this; this->~fnode();
::operator delete(const_cast<fnode*>(this));
} }
void void
@ -615,9 +617,8 @@ namespace spot
v.insert(v.begin(), tt()); v.insert(v.begin(), tt());
} }
auto mem = ::operator new(sizeof(fnode)
auto mem = operator new(sizeof(fnode) + (v.size() - 1)*sizeof(*children));
+ (v.size() - 1)*sizeof(*children));
return unique(new(mem) fnode(o, v.begin(), v.end())); return unique(new(mem) fnode(o, v.begin(), v.end()));
} }
@ -1029,7 +1030,7 @@ namespace spot
SPOT_UNREACHABLE(); SPOT_UNREACHABLE();
} }
auto mem = operator new(sizeof(fnode) + sizeof(*children)); auto mem = ::operator new(sizeof(fnode) + sizeof(*children));
return unique(new(mem) fnode(o, {first, second})); return unique(new(mem) fnode(o, {first, second}));
} }

View file

@ -1,5 +1,5 @@
// -*- coding: utf-8 -*- // -*- coding: utf-8 -*-
// Copyright (C) 2015, 2016 Laboratoire de Recherche et Développement de // Copyright (C) 2015, 2016, 2017 Laboratoire de Recherche et Développement de
// l'Epita (LRDE). // l'Epita (LRDE).
// //
// This file is part of Spot, a model checking library. // This file is part of Spot, a model checking library.
@ -484,7 +484,7 @@ namespace spot
[[noreturn]] static void report_min_invalid_arg(); [[noreturn]] static void report_min_invalid_arg();
[[noreturn]] static void report_max_invalid_arg(); [[noreturn]] static void report_max_invalid_arg();
static const fnode* unique(const fnode*); static const fnode* unique(fnode*);
// Destruction may only happen via destroy(). // Destruction may only happen via destroy().
~fnode() = default; ~fnode() = default;