From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id DC89A3982C7F; Fri, 2 Oct 2020 15:00:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org DC89A3982C7F From: "rascmoo at gmail dot com" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/97273] New: Strange behaviour of unordered_set when vector is included (i686) Date: Fri, 02 Oct 2020 15:00:54 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: new X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 10.2.1 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: rascmoo at gmail dot com X-Bugzilla-Status: UNCONFIRMED X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: bug_id short_desc product version bug_status bug_severity priority component assigned_to reporter target_milestone attachments.created Message-ID: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 02 Oct 2020 15:00:55 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D97273 Bug ID: 97273 Summary: Strange behaviour of unordered_set when vector is included (i686) Product: gcc Version: 10.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: rascmoo at gmail dot com Target Milestone: --- Created attachment 49302 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=3D49302&action=3Dedit A few simple source files demonstrating the problem, plus a .ii file genera= ted on my system Hello, I have recently been diagnosing a fault with the 32-bit build of an application, and this has led me to find some strange behaviour with unordered_set, when compiling for 32-bit x86 (i686). I have included an exa= mple which demonstrates the behaviour. Consider the following small program: #include #include uint64_t getBegin(const std::unordered_set & set) { return *set.begin(); } It returns the first value in a uint64_t unordered_set. This can be compiled into a shared library with the following command: g++ -Wall -Wextra -fpic -shared -Os Working.cpp -o libworking.so This works as intended on all 32 and 64 bit systems which I have tested it = on, and on all optimisation levels. However, consider the next small program: #include #include #include uint64_t getBegin(const std::unordered_set & set) { return *set.begin(); } The only change is the addition of a "#include ". This ought not to have any impact on the program, and it ought to work exactly the same. It c= an also be compiled into a shared library with the following command: g++ -Wall -Wextra -fpic -shared -Os Broken.cpp -o libbroken.so Indeed, when compiled on a 64 bit x86 system there is no difference - both functions work as intended. However, when compiled either natively on a 32-= bit x86 system, or cross compiled to 32-bit using the "-m32" flag, "*set.begin(= )" returns an incorrect value. I tested both of these with the following simple test program: #include #include uint64_t getBegin(const std::unordered_set & set); int main(void) { std::unordered_set set({1, 2, 3, 4, 5, 6, 7}); std::cout << getBegin(set) << "\n"; } Which can be compiled using the following commands (linking to either worki= ng or broken versions respectively): g++ -Wall -Wextra -Os test.cpp -L. -lworking -o test g++ -Wall -Wextra -Os test.cpp -L. -lbroken -o test Both versions work correctly when compiled and running natively on a 64-bit= x86 system, (they print "7"). But, when when either compiled with "-m32" on a 64-bit system, or compiled and running natively on a 32-bit x86 system, the second (broken) variant prints "30064771072". This is certainly not one of = the numbers in the unordered_set. I have reproduced the problem across several different 32-bit and 64-bit systems. These are the versions reported by g++ --version, on the systems w= hich I have tried: Debian 10 (stable): g++ (Debian 8.3.0-6) 8.3.0 Debian 11 (testing): g++ (Debian 10.2.0-9) 10.2.0 Fedora 32 (Workstation Edition): g++ (GCC) 10.2.1 20200723 (Red Hat 10.2.1-1) Some source files and a simple makefile, which can reproduce the problem, a= re attached. I have also included the .ii file which is produced when running the follow= ing command, on the broken variant of the function: g++ -save-temps -m32 -Wall -Wextra -fpic -shared -Os Broken.cpp -o libbroke= n.so Other things which I have noticed: > The problem happens with optimisation levels O1, O2, O3, Os and Ofast, b= ut does not occur with O0. > The problem occurs whenever vector is included BEFORE unordered_set. If vector is included after unordered_set, behaviour is correct. > When broken, the memory address pointed to by the iterator returned by begin(), seems to always be wrong by 4 bytes, (4 bytes before the address w= hich it should be). > When I compared the assembly output of the two functions, the offsets in three movl instructions differ - see below. I assume this is causing the wr= ong address to be returned. Working version: movl 8(%eax), %eax # MEM[(struct _Hash_node_base * *)set_2(D) + 8B], MEM[(struct _Hash_node_base * *)set_2(D) + 8B] movl 12(%eax), %edx # MEM[(const long long unsigned int &)_4 + 8], MEM[(const long long unsigned int &)_4 + 8] movl 8(%eax), %eax # MEM[(const long long unsigned int &)_4 + 8], MEM[(const long long unsigned int &)_4 + 8] Broken version: movl 8(%eax), %eax # MEM[(struct _Hash_node_base * *)set_2(D) + 8B], MEM[(struct _Hash_node_base * *)set_2(D) + 8B] movl 8(%eax), %edx # MEM[(const long long unsigned int &)_4 + 4], MEM[(const long long unsigned int &)_4 + 4] movl 4(%eax), %eax # MEM[(const long long unsigned int &)_4 + 4], MEM[(const long long unsigned int &)_4 + 4] If there is any more information about this problem which you require, then please let me know. Thank you very much, Dan Wilson.=