Hi,
I think I ran into a rather subtle bug inside llvm/ADT/ArrayRef.h which only shows up when compiling the code with GCC-4.8 with switched-off optimizations. (Both clang and GCC-4.7 don’t trigger the bug.)
I already filed a bug against GCC-4.8 which was rejected by the GCC-folks as being invalid, because the code (basically ArrayRef.h) “is doing something bad - it’s retaining a pointer to a temporary object across a function call.” They also provided a detailed explanation for their opinion, which I think is correct. See this link for the full story: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61015
The following program demonstrates the bug using LLVM’s own ArrayRef:
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
#include
#include <llvm/ADT/ArrayRef.h>
class Obj {};
class SpecialObj : public Obj {};
int main()
{
SpecialObj* pSpecial = new SpecialObj();
llvm::ArrayRef<Obj*> arrayRef( pSpecial ); //Breaks on GCC-4.8.
/* Obj* pObj = pSpecial;
llvm::ArrayRef<Obj*> arrayRef( pObj ); //Possible Workaround */
int someStackArray[500];
memset( someStackArray, 0xdd, sizeof(someStackArray) );
if( arrayRef[0] != pSpecial )
printf( “This shouldn’t happen: %p\n”, arrayRef[0] );
else
printf( “Expected behaviour.\n” );
return 0;
}
Compiling (and then executing) this program with
g+±4.8 -Wall -O0 -std=c++11 -I./LLVM_SVN/installed/include main.cpp
prints: “This shouldn’t happen: 0xdddddddddddddddd”
Compiling with
clang++ -Wall -O0 -std=c++11 -I./LLVM_SVN/installed/include main.cpp
prints: “Expected behaviour.”
I think (as a quick fix) we should remove the const qualifier from ArrayRef’s CTor argument, so that the above code won’t compile anymore and thus avoiding a silent failure.
To be precise:
Change llvm/ADT/ArrayRef.h:57 from
ArrayRef(const T &OneElt)
: Data(&OneElt), Length(1) {}
to
ArrayRef(T &OneElt)
: Data(&OneElt), Length(1) {}
Best regards,
Andreas