Industrial-antidepressant Industrial-antidepressant - 1 month ago 7
C++ Question

Why g++ with -O3 segfault with the following LLVM library code

So I want to use the

llvm::Twine
string chunk class.

I have the following sample:

#include <llvm/ADT/Twine.h>
#include <iostream>

int main()
{
llvm::Twine twine1 = llvm::Twine("aaaa") + "bbbb" + "cccc" + "dddd";
llvm::Twine twine2 = llvm::Twine(twine1) + "dddd" + "eeee";
std::cout << twine1.str() << std::endl;
std::cout << twine2.str() << std::endl;

return 0;
}


It runs with
clang++
with
-O3
and
g++
with
-O0
but segfault with
g++
with
-O3
. I tried this code parts different versions of clang library from 3.4-3.9 and tried with
g++ 4.8.4
,
g++ 4.8.5
and
mingw-5.3.0
.

You need the llvm library and link the code with
-lLLVMSupport -lLLVMCore
and the others from
llvm-config --ldflags

Answer

From Twine documentation:

A Twine is not intended for use directly and should not be stored, its implementation relies on the ability to store pointers to temporary stack objects which may be deallocated at the end of a statement. Twines should only be used accepted as const references in arguments, when an API wishes to accept possibly-concatenated strings.

In the other words, Twine object doesn't own its parts, so they are destroyed at the end of statement.

A correct usage would be:

#include <llvm/ADT/Twine.h>
#include <iostream>

void bar(const llvm::Twine& twine1, const llvm::Twine2& twine2){
    std::cout << twine1.str() << std::endl;
    std::cout << twine2.str() << std::endl;
}

void foo(const llvm::Twine& twine1){
    bar(twine1, twine1 + "dddd" + "eeee");
}

int main()
{
  foo(llvm::Twine("aaaa") + "bbbb" + "cccc" + "dddd");

  return 0;
}  
Comments