[Bug c++/103843] New: Direct call to Desctructor is optimized out

2021-12-27 Thread georgii.shagov--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103843

Bug ID: 103843
   Summary: Direct call to Desctructor is optimized out
   Product: gcc
   Version: 10.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: georgii.sha...@be-tse.de
  Target Milestone: ---

cat ./d.cpp
#include 

class S {
public:
   S() = default;
   ~S() { i=10; }
   void foo() { this->~S(); }
   int getI() const { return i; }
private:
   int i{0};
};

int main()
{
   S s;
   do {
  std::cout << "Before foo: " << s.getI();
  s.foo();
  std::cout << "; After: " << s.getI() << std::endl;
   } while (false);
   return 0;
}

g++ -O0 ./d.cpp 
$./a.out 
Before foo: 0; After: 10

g++ -O3 ./d.cpp 
georgii@ltgscosvm:~/prj/test$./a.out 
Before foo: 0; After: 0

gcc --version
gcc (GCC) 10.2.1 20210130 (Red Hat 10.2.1-11)
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

hostnamectl
   Static hostname: ltgscosvm.be-tse01.de
 Icon name: computer-vm
   Chassis: vm
Machine ID: fb944a0ffb46449f9b639e589d00b598
   Boot ID: 433e59a4db5c419a9081cc6968e4e590
Virtualization: microsoft
  Operating System: CentOS Linux 7 (Core)
   CPE OS Name: cpe:/o:centos:centos:7
Kernel: Linux 3.10.0-1160.45.1.el7.x86_64
  Architecture: x86-64

uname -a
Linux ltgscosvm.be-tse01.de 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13
17:20:51 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

[Bug c++/103843] Direct call to Desctructor is optimized out

2021-12-27 Thread georgii.shagov--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103843

--- Comment #1 from Georgii.Shagov  ---
>From experiments, I would guess that in case of -O3 the call to destructor was
substituted by initializer:

This works fine:

cat ./d.cpp
#include 

class S {
public:
   S() : i{1} {}
   ~S() { i=0; }
   void foo() { this->~S(); }
   int getI() const { return i; }
private:
   int i{0};
};

int main()
{
   S s;
   do {
  std::cout << "Before foo: " << s.getI();
  s.foo();
  std::cout << "; After: " << s.getI() << std::endl;
   } while (false);
   return 0;
}


g++ ./d.cpp 
$./a.out 
Before foo: 1; After: 0
$g++ -O3 ./d.cpp 
$./a.out 
Before foo: 1; After: 0
g++ --version
g++ (GCC) 10.2.1 20210130 (Red Hat 10.2.1-11)

[Bug c++/103843] Direct call to Desctructor is optimized out

2021-12-27 Thread georgii.shagov--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103843

Georgii.Shagov  changed:

   What|Removed |Added

 Resolution|INVALID |FIXED

--- Comment #3 from Georgii.Shagov  ---
(In reply to Andrew Pinski from comment #2)
> This is undefined code. The object is officially not live after you call the
> deconstructor so GCC is able to remove the store from the deconstructor as
> being dead.

I appreciate your reply. But this is confusing. The object was NOT released
(de-allocated). In essence Destructor is just a function. Why the content of
the class had been re-initialized?
IMU: there should be not such obvious difference between optimized and
non-optimized code

thnx in advance.

[Bug c++/103843] Direct call to Desctructor is optimized out

2021-12-27 Thread georgii.shagov--- via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103843

Georgii.Shagov  changed:

   What|Removed |Added

 Resolution|INVALID |FIXED

--- Comment #5 from Georgii.Shagov  ---

> No, the destructor is not just a function in C++, it terminates the object
> being alive (not de-allocated though). You can then reuse the space for
> another object, either the same type or a different type by using the
> inplacement new.
> 
> > Why the content of the class had been re-initialized?
> 
> It was not re-initialized rather the store was removed.
> 
> > IMU: there should be not such obvious difference between optimized and
> > non-optimized code
> 
> why not, it is undefined code.

I really appreciate and value your Reply, Andrew.

I have modified the code a little bit:

#include 

class S {
public:
   S() = default;
   ~S() { i=10; }
   void foo() { this->~S(); }
   int getI() const { return i; }
private:
   int i{100};
};

int main()
{
   S s;
   do {
  std::cout << "Before foo: " << s.getI();
  s.foo();
  std::cout << "; After: " << s.getI() << std::endl;
   } while (false);
   return 0;
}

$g++ -O3 ./d.cpp 
$./a.out 
Before foo: 100; After: 0
$g++ -O0 ./d.cpp 
$./a.out 
Before foo: 100; After: 10

> No, the destructor is not just a function in C++, it terminates the object
> being alive (not de-allocated though). 

I do understand your point, yet I would not feel comfortable in sharing one.

- It is not clear: what function/code has reset S::i value to 0 after a Direct
call to Destructor?
- Why 0? :-?
- In order to avoid misleading I have allocated the object on the stack as you
can see. So, no-memory mgmt is not involved
- Does it mean gcc implants some code, being called after Destructor call,
resetting the content of the class Instance to 0? ::memset??
- Is there any agreement unto this? I would be happy to learn more about this.


Thnx in advance,
Yours truly, George