Bug 587128
| Summary: | Apparent gcc 4.4.3 miscompilation | ||
|---|---|---|---|
| Product: | [Fedora] Fedora | Reporter: | Sam Varshavchik <mrsam> |
| Component: | gcc | Assignee: | Jakub Jelinek <jakub> |
| Status: | CLOSED NOTABUG | QA Contact: | Fedora Extras Quality Assurance <extras-qa> |
| Severity: | medium | Docs Contact: | |
| Priority: | low | ||
| Version: | 12 | CC: | jakub |
| Target Milestone: | --- | ||
| Target Release: | --- | ||
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | Bug Fix | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2010-04-29 09:02:34 UTC | Type: | --- |
| Regression: | --- | Mount Type: | --- |
| Documentation: | --- | CRM: | |
| Verified Versions: | Category: | --- | |
| oVirt Team: | --- | RHEL 7.3 requirements from Atomic Host: | |
| Cloudforms Team: | --- | Target Upstream Version: | |
| Embargoed: | |||
row1 ^= row2 ^= row1 ^= row2; has undefined behavior in both C and C++, and even -Wsequence-point (part of -Wall) warns about it. |
Description of problem: Looks like gcc might be miscompiling code that uses the XOR hack of swapping two integer values. Version-Release number of selected component (if applicable): gcc-4.4.3-4.fc12.i686 How reproducible: #include <iostream> struct A { size_t x1, y1, x2, y2; void foo(size_t &row1, size_t &row2, size_t &pos1, size_t &pos2); }; void A::foo(size_t &row1, size_t &row2, size_t &pos1, size_t &pos2) { row1=y1; row2=y2; pos1=x1; pos2=x2; if (row2 < row1 || (row2 == row1 && pos2 < pos1)) { // Swap the coordinate pairs row1 ^= row2 ^= row1 ^= row2; pos1 ^= pos2 ^= pos1 ^= pos2; } } int main() { A aa; aa.y1=5; aa.x1=1; aa.y2=0; aa.x2=2; size_t row1, row2, col1, col2; aa.foo(row1, row2, col1, col2); std::cout << "row1=" << row1 << ", col1=" << col1 << ", row2=" << row2 << ", col2=" << col2 << std::endl; return (0); } Steps to Reproduce: 1. Compile the above code: g++ -o /tmp/t /tmp/t.C 2. 3. Actual results: $ /tmp/t row1=0, col1=0, row2=5, col2=1 Expected results: $ /tmp/t row1=0, col1=2, row2=5, col2=1 Additional info: The sequence "a ^= b ^= a ^= b" is a hack which essentially swaps the values of a and b. Example: Starting values: a=1, b=2 After a ^= b: a=3, b=2 After b ^= a ^= b: a=3, b=1 After a ^= b ^= a ^= b: a=2, b=1 The above example is a snippet of code that takes a pair of two-dimensional (x, y) coordinates, and returns the "lowest" (x, y) pair and the highest pair. Looks like a struct/class, and a function call passing return values by reference are a necessary ingredient to trigger the miscompilation.