public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak
@ 2021-05-09 20:17 ldalessandro at gmail dot com
2021-05-09 20:28 ` [Bug c++/100495] " ldalessandro at gmail dot com
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: ldalessandro at gmail dot com @ 2021-05-09 20:17 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
Bug ID: 100495
Summary: constexpr virtual destructor incorrectly reports
memory leak
Product: gcc
Version: 12.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: ldalessandro at gmail dot com
Target Milestone: ---
When using a constexpr virtual destructor gcc fails to match delete with
corresponding new.
```
struct Foo {
constexpr virtual ~Foo() {}
};
constexpr bool foo() {
Foo *ptr = new Foo();
delete ptr;
return true;
}
static_assert(foo()); //error: 'foo()' is not a constant expression because
allocated storage has not been deallocated
```
https://godbolt.org/z/W6haTEvzs
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
@ 2021-05-09 20:28 ` ldalessandro at gmail dot com
2021-05-09 21:28 ` ldalessandro at gmail dot com
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: ldalessandro at gmail dot com @ 2021-05-09 20:28 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #1 from Luke Dalessandro <ldalessandro at gmail dot com> ---
A short-term workaround for this appears to be explicit allocator usage (works
back at least to 10.2).
```
#include <memory>
struct Foo {
constexpr virtual ~Foo() {}
};
constexpr bool foo() {
std::allocator<Foo> alloc = {};
Foo *ptr = alloc.allocate(1);
std::construct_at(ptr);
std::destroy_at(ptr);
alloc.deallocate(ptr, 1);
return true;
}
static_assert(foo());
```
https://godbolt.org/z/ohKE6h3Px
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
2021-05-09 20:28 ` [Bug c++/100495] " ldalessandro at gmail dot com
@ 2021-05-09 21:28 ` ldalessandro at gmail dot com
2021-05-10 13:30 ` jakub at gcc dot gnu.org
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: ldalessandro at gmail dot com @ 2021-05-09 21:28 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #2 from Luke Dalessandro <ldalessandro at gmail dot com> ---
It's also possible to workaround this with array allocation.
```
struct Foo {
constexpr virtual ~Foo() {}
};
constexpr bool foo() {
Foo *ptr = new Foo[1]{};
delete [] ptr;
return true;
}
static_assert(foo());
```
Obviously both of the workarounds require that we be able to cast from a `Foo*`
to our derived pointer, at which point we might as well skip the virtual
destructor and add an abstract `virtual void destroy() = 0` member where we can
just call `delete this` anyway.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
2021-05-09 20:28 ` [Bug c++/100495] " ldalessandro at gmail dot com
2021-05-09 21:28 ` ldalessandro at gmail dot com
@ 2021-05-10 13:30 ` jakub at gcc dot gnu.org
2021-09-01 22:43 ` pinskia at gcc dot gnu.org
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-05-10 13:30 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |jakub at gcc dot gnu.org,
| |jason at gcc dot gnu.org
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
Last reconfirmed| |2021-05-10
--- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
constexpr.c (cxx_eval_call_expression) has:
if (DECL_CLONED_FUNCTION_P (fun))
fun = DECL_CLONED_FUNCTION (fun);
and similarly constexpr.c (maybe_save_constexpr_fundef) has:
if (processing_template_decl
|| !DECL_DECLARED_CONSTEXPR_P (fun)
|| cp_function_chain->invalid_constexpr
|| DECL_CLONED_FUNCTION_P (fun))
return;
which means instead of calling during constexpr evaluation the deleting
destructor (_ZN3FooD0Ev) we call the destructor it is cloned from (_ZN3FooD4Ev)
and that means we don't constexpr evaluate the actual delete operator call.
I guess it would be possible to remember
DECL_DELETING_DESTRUCTOR_P (fun) from before the fun = DECL_CLONED_FUNCTION
(fun); and constexpr evaluate a delete operator call, but I'm afraid I have no
idea how this works for constructors or any other cloned function either, how
do we figure out what arguments to bind to e.g. in_chrg argument etc.?
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (2 preceding siblings ...)
2021-05-10 13:30 ` jakub at gcc dot gnu.org
@ 2021-09-01 22:43 ` pinskia at gcc dot gnu.org
2021-09-06 10:31 ` jakub at gcc dot gnu.org
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: pinskia at gcc dot gnu.org @ 2021-09-01 22:43 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |friedkeenan at protonmail dot com
--- Comment #4 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
*** Bug 102167 has been marked as a duplicate of this bug. ***
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (3 preceding siblings ...)
2021-09-01 22:43 ` pinskia at gcc dot gnu.org
@ 2021-09-06 10:31 ` jakub at gcc dot gnu.org
2021-09-06 11:48 ` jakub at gcc dot gnu.org
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-09-06 10:31 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #5 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Ah, for constructors this is likely a non-issue, because in_chrg etc. only
appears on constructors of classes with virtual bases and such constructors are
not constexpr.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (4 preceding siblings ...)
2021-09-06 10:31 ` jakub at gcc dot gnu.org
@ 2021-09-06 11:48 ` jakub at gcc dot gnu.org
2021-09-07 17:35 ` cvs-commit at gcc dot gnu.org
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-09-06 11:48 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
Jakub Jelinek <jakub at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |ASSIGNED
Assignee|unassigned at gcc dot gnu.org |jakub at gcc dot gnu.org
--- Comment #6 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Created attachment 51415
--> https://gcc.gnu.org/bugzilla/attachment.cgi?id=51415&action=edit
gcc12-pr100495.patch
The easiest fix seems to be to just remember the deleting dtor bodies and
constexpr evaluating them, they are quite special anyway, as they are
created by build_delete_destructor_body and essentially contain just two calls,
so there is no user code in those and thus practically they aren't really
clones of those user functions - they just call some other dtor fndecl (with
the user code in it) and delete.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (5 preceding siblings ...)
2021-09-06 11:48 ` jakub at gcc dot gnu.org
@ 2021-09-07 17:35 ` cvs-commit at gcc dot gnu.org
2021-09-07 17:42 ` cvs-commit at gcc dot gnu.org
2021-09-07 17:44 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-09-07 17:35 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #7 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:81f9718139cb1cc164ada411ada8cca9f32b8be8
commit r12-3387-g81f9718139cb1cc164ada411ada8cca9f32b8be8
Author: Jakub Jelinek <jakub@redhat.com>
Date: Tue Sep 7 19:33:28 2021 +0200
c++: Fix up constexpr evaluation of deleting dtors [PR100495]
We do not save bodies of constexpr clones and instead evaluate the bodies
of the constexpr functions they were cloned from.
I believe that is just fine for constructors because complete vs. base
ctors differ only in classes that have virtual bases and such constructors
aren't constexpr, similarly complete/base destructors.
But as the testcase below shows, for deleting destructors it is not fine,
deleting dtors while marked as clones in fact are just artificial functions
with synthetized body which calls the user destructor and deallocation.
So, either we'd need to evaluate the destructor and afterwards synthetize
and evaluate the deallocation, or we can just save and use the deleting
dtors bodies. The latter seems much easier to me.
2021-09-07 Jakub Jelinek <jakub@redhat.com>
PR c++/100495
* constexpr.c (maybe_save_constexpr_fundef): Save body even for
constexpr deleting dtors.
(cxx_eval_call_expression): Don't use DECL_CLONED_FUNCTION for
deleting dtors.
* g++.dg/cpp2a/constexpr-new21.C: New test.
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (6 preceding siblings ...)
2021-09-07 17:35 ` cvs-commit at gcc dot gnu.org
@ 2021-09-07 17:42 ` cvs-commit at gcc dot gnu.org
2021-09-07 17:44 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: cvs-commit at gcc dot gnu.org @ 2021-09-07 17:42 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #8 from CVS Commits <cvs-commit at gcc dot gnu.org> ---
The releases/gcc-11 branch has been updated by Jakub Jelinek
<jakub@gcc.gnu.org>:
https://gcc.gnu.org/g:9f300873f6bf8456ebdbd40d0211aefe57f95cb5
commit r11-8968-g9f300873f6bf8456ebdbd40d0211aefe57f95cb5
Author: Jakub Jelinek <jakub@redhat.com>
Date: Tue Sep 7 19:33:28 2021 +0200
c++: Fix up constexpr evaluation of deleting dtors [PR100495]
We do not save bodies of constexpr clones and instead evaluate the bodies
of the constexpr functions they were cloned from.
I believe that is just fine for constructors because complete vs. base
ctors differ only in classes that have virtual bases and such constructors
aren't constexpr, similarly complete/base destructors.
But as the testcase below shows, for deleting destructors it is not fine,
deleting dtors while marked as clones in fact are just artificial functions
with synthetized body which calls the user destructor and deallocation.
So, either we'd need to evaluate the destructor and afterwards synthetize
and evaluate the deallocation, or we can just save and use the deleting
dtors bodies. The latter seems much easier to me.
2021-09-07 Jakub Jelinek <jakub@redhat.com>
PR c++/100495
* constexpr.c (maybe_save_constexpr_fundef): Save body even for
constexpr deleting dtors.
(cxx_eval_call_expression): Don't use DECL_CLONED_FUNCTION for
deleting dtors.
* g++.dg/cpp2a/constexpr-new21.C: New test.
(cherry picked from commit 81f9718139cb1cc164ada411ada8cca9f32b8be8)
^ permalink raw reply [flat|nested] 10+ messages in thread
* [Bug c++/100495] constexpr virtual destructor incorrectly reports memory leak
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
` (7 preceding siblings ...)
2021-09-07 17:42 ` cvs-commit at gcc dot gnu.org
@ 2021-09-07 17:44 ` jakub at gcc dot gnu.org
8 siblings, 0 replies; 10+ messages in thread
From: jakub at gcc dot gnu.org @ 2021-09-07 17:44 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100495
--- Comment #9 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
Fixed for 11.3+/12+ so far, probably should be backported for 10.4 too.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2021-09-07 17:44 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-09 20:17 [Bug c++/100495] New: constexpr virtual destructor incorrectly reports memory leak ldalessandro at gmail dot com
2021-05-09 20:28 ` [Bug c++/100495] " ldalessandro at gmail dot com
2021-05-09 21:28 ` ldalessandro at gmail dot com
2021-05-10 13:30 ` jakub at gcc dot gnu.org
2021-09-01 22:43 ` pinskia at gcc dot gnu.org
2021-09-06 10:31 ` jakub at gcc dot gnu.org
2021-09-06 11:48 ` jakub at gcc dot gnu.org
2021-09-07 17:35 ` cvs-commit at gcc dot gnu.org
2021-09-07 17:42 ` cvs-commit at gcc dot gnu.org
2021-09-07 17:44 ` jakub at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).