[prev in list] [next in list] [prev in thread] [next in thread]
List: gcc-bugs
Subject: [Bug c++/70018] New: Possible issue around IPO and C++ inline functions
From: "sanjoy at playingwithpointers dot com" <gcc-bugzilla () gcc ! gnu ! org>
Date: 2016-02-29 19:20:01
Message-ID: bug-70018-4 () http ! gcc ! gnu ! org/bugzilla/
[Download RAW message or body]
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70018
Bug ID: 70018
Summary: Possible issue around IPO and C++ inline functions
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: sanjoy at playingwithpointers dot com
Target Milestone: ---
I don't grok gcc internals so I cannot write a terribly well-informed
bug report, but GCC 5.3.0 seems to miscompile
https://github.com/sanjoy/comdat-ipo
This was discussed on llvm-dev:
http://lists.llvm.org/pipermail/llvm-dev/2016-February/095833.html and
the thread contains a description of the underlying cause for
LLVM/Clang.
The TL;DR is that for C++ inline functions (and other functions with
similar linkage rules), you can override a more-refined function
implementation with a less-refined one at link time, and that can
retroactively invalidate earlier transforms, where "refined" in this
case means "undefined in fewer situations".
E.g. if we have (this is very similar to the reproducer above minus
some mechanical details):
inline void foo(int* ptr) {
100 / ptr[0];
}
void bar(int* ptr) {
*ptr = 40;
foo(ptr):
*ptr = 50;
}
=>
inline void foo(int* ptr) {
// 100 / ptr[0]; removed, dead code
}
void bar(int* ptr) {
*ptr = 40;
foo(ptr):
*ptr = 50;
}
=>
inline void foo(int* ptr) {
// 100 / ptr[0]; removed, dead code
}
void bar(int* ptr) {
// *ptr = 40; dead store, since foo does not read memory
foo(ptr):
*ptr = 50;
}
we've miscompiled if *ptr == 0 on entry to bar, and foo is replaced
with the original definition at link time.=
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic