[LLVMdev] Bug in llvm/ADT/ArrayRef.h?

Philip Reames listmail at philipreames.com
Fri Jul 18 09:46:23 PDT 2014


On 07/18/2014 02:29 AM, Andreas Weber wrote:
> 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
I think you may have misread the explanation.  I'm not entirely sure the 
explanation of the spec behaviour is correct, but let's leave that 
discussion to people more knowledgeable then myself.

If I'm reading the link above right, the issue is that you used:
llvm::ArrayRef<Obj*> arrayRef( pSpecial );
Instead of:
llvm::ArrayRef<SpecialObj*> arrayRef( pSpecial );

The former requires the creation of a temporary variable; the latter 
does not.  GCC 4.8 exploits that temporary variable.  Clang should if we 
don't already.  :)


>
> The following program demonstrates the bug using LLVM's own ArrayRef:
> #define __STDC_LIMIT_MACROS
> #define __STDC_CONSTANT_MACROS
>
> #include <cstdio>
> #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
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140718/a95cc422/attachment.html>


More information about the llvm-dev mailing list