The question is, does the following snippet use uninitialized memory, as reported by Google's MemorySanitizer? Or is it a false positive?:
main.cpp
:#include <string>
#include <iostream>
using namespace std;
int main() {
string s0 = to_string(1);
cout << "s0: " << s0 << endl;
string s1 = to_string(1) + to_string(2);
cout << "s1: " << s1 << endl;
return 0;
}
Makefile
:main:
clang++ -fsanitize=memory -fsanitize-memory-track-origins -fPIE -pie -fno-omit-frame-pointer -g -O2 main.cpp -o main-msan.out
clang++ -O2 main.cpp -o main.out
Result:
./main-msan.out
s0: 1
==122092==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x55a7354e5cf7 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6123:34
#1 0x55a7354e5cf7 in main <my_directory>/msan/main.cpp:9:30
#2 0x7f201f6edd09 in __libc_start_main csu/../csu/libc-start.c:308:16
#3 0x55a735468349 in _start (<my_directory>/msan/main-msan.out+0x21349)
Uninitialized value was created by an allocation of 'ref.tmp' in the stack frame of function 'main'
#0 0x55a7354e4d90 in main <my_directory>/msan/main.cpp:6
SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/basic_string.h:6123:34 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > std::operator+<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&)
Exiting
A mirror issue is also opened here
A mirror issue to this question received an answer. The gist of the answer is that MemorySanitizer is not a "plug-in"-style checker.
To be specific, say we have a source code file main.cpp
and we want to compile it to binary main.out
, simply adding -fsanitize=memory -fsanitize-memory-track-origins
to my compilation command is not enough. To avoid false positives, all the libraries used by main.out
must also be compiled with -fsanitize=memory -fsanitize-memory-track-origins
as well. In the answer, this is called "instrumentation".
This official wiki post describes how we can achieve it.