[Bug c++/109495] New: Stack is used (unexpectedly) for copying on-heap objects (while clang doesn't)

2023-04-13 Thread gcc-bug-reports at xhtml dot guru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109495

Bug ID: 109495
   Summary: Stack is used (unexpectedly) for copying on-heap
objects (while clang doesn't)
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
  Assignee: unassigned at gcc dot gnu.org
  Reporter: gcc-bug-reports at xhtml dot guru
  Target Milestone: ---

Could be a bug or could be a feature -- can't tell. Please help understand why
GCC involves stack in certain conditions when copying on-heap objects (no
problem in clang).

Problem:

In actual live project I have a large struct/class with a lot of data in it ("a
lot" is defined as larger than Wframe-larger-than), I've also got many
locations where that struct is copied (directly or indirectly), and got
Wframe-larger-than enabled. In some cases I'm hitting the error on lines that
_indirectly_ copy-construct the object from an object that's stored on heap
into an object that is also stored on heap (i.e. heap-to-heap operation, if you
will).

After finding minimal case that reproduces the issue
(https://godbolt.org/z/xcnP9E39a), disassembling the code and looking into
potential reasons why GCC might want to use the stack (and thus trigger
Wframe-larger-than), I see that (subjectively for no apparent reason) GCC
involves stack as an intermediate buffer, which I am looking to avoid. clang
doesn't use intermediate buffer in this same scenario. Some surprising
observations (which make the problem go away) might be indicative of a bug in
GCC:

1) If private member "y" of class Parent is made public, Wframe-larger-than
goes away (https://godbolt.org/z/G7x5EWKEf);
2) If type of member "s" of struct Child is changed from std::string to int,
the problem goes away (https://godbolt.org/z/zK6Wjj8nK);
3) If class Parent is adjusted so that there is no padding at the end, for
example by changing type of "z" member of class Parent to short
(https://godbolt.org/z/jsbsc6jcb) or by deleting member "z" altogether
(https://godbolt.org/z/3jqaoKse9), the problem goes away;
4) If inheritance is taken out of the equation, for example by aggregating
class Parent below class Child (instead of inheriting;
https://godbolt.org/z/451K1s7bc), the problem goes away.

Expected behavior: GCC not reporting Wframe-larger-than.

Actual behavior: GCC reports Wframe-larger-than.


// Code (attached as test.cpp):

#include 

class Parent
{
private:
unsigned char y[ 1024 * 64 ];   // Beef up class' size past
Wframe-larger-than

public:
short x;// sizeof == 2 -> increases
alignment requirement to 2
char z; // sizeof == 1 -> triggers padding
(1) at the end of struct
};

struct Child : public Parent
{
std::string s;
};

int main( int, char** )
{
auto* ptr = new Child();
auto* ptr2 = new Child( *ptr ); // g++ reports frame-larger-than
violation; clang doesn't.
delete ptr2;
delete ptr;

return 0;
}

// Environment (gcc version):

$ g++ --version
g++ (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 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.
// but it could be any GCC version.

// Command line (gcc; https://godbolt.org/z/xcnP9E39a):

$ g++ -Werror -Wframe-larger-than=4096 -o test test.cpp
/code/Src/E2EE/dstepanovs.cpp: In copy constructor ‘Child::Child(const
Child&)’:
/code/Src/E2EE/dstepanovs.cpp:14:8: error: the frame size of 65568 bytes is
larger than 4096 bytes [-Werror=frame-larger-than=]
   14 | struct Child : public Parent
  |^
cc1plus: all warnings being treated as errors

// Compiling same code with same flags with clang yields no error (clang
command line; https://godbolt.org/z/PMq5Yr3Tn):
$ clang++ -Werror -Wframe-larger-than=4096 -o test test.cpp

[Bug c++/109495] Stack is used (unexpectedly) for copying on-heap objects (no problem in clang)

2023-04-13 Thread gcc-bug-reports at xhtml dot guru via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109495

--- Comment #1 from gcc-bug-reports at xhtml dot guru ---
Created attachment 54849
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54849&action=edit
test.cpp: test code that triggers Wframe-larger-than in GCC