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

David Blaikie dblaikie at gmail.com
Fri Jul 18 10:08:40 PDT 2014


On Fri, Jul 18, 2014 at 9:46 AM, Philip Reames
<listmail at philipreames.com> wrote:
>
> 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.  :)

Arnaud seems to be working on that (
http://llvm.org/viewvc/llvm-project?rev=213379&view=rev - though its
been reverted pending investigation of some failures it caused).

>
>
>
> 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
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



More information about the llvm-dev mailing list