Bug 80183 - [7 Regression] Conditional jump or move depends on uninitialised value: std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) (tree.cc:97)
Summary: [7 Regression] Conditional jump or move depends on uninitialised value: std::...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 7.0.1
: P1 normal
Target Milestone: 7.0
Assignee: Markus Trippelsdorf
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-03-25 12:12 UTC by Markus Trippelsdorf
Modified: 2017-03-26 19:27 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2017-03-25 00:00:00


Attachments
testcase. valgrind clang-format bench.ii (78.38 KB, text/plain)
2017-03-25 12:19 UTC, Markus Trippelsdorf
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Trippelsdorf 2017-03-25 12:12:28 UTC
Running clang-format under valgrind shows:

==69398== Conditional jump or move depends on uninitialised value(s)
==69398==    at 0x42D3B08: std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) (tree.cc:97)
==69398==    by 0x101B12FF: std::_Rb_tree_const_iterator<clang::tooling::Replacement>::operator--() (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B17FF: std::reverse_iterator<std::_Rb_tree_const_iterator<clang::tooling::Replacement> >::operator->() const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B0597: clang::tooling::applyAllReplacements[abi:cxx11](llvm::StringRef, clang::tooling::Replacements const&) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101099FB: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*)::{lambda(clang::format::TokenAnalyzer&)#1}::operator()(clang::format::TokenAnalyzer&) const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x10109E67: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000C603: clang::format::format(llvm::StringRef) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000D1D7: main (in /home/trippels/llvm_build/bin/clang-format)
==69398== 
==69398== Conditional jump or move depends on uninitialised value(s)
==69398==    at 0x42D3B08: std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) (tree.cc:97)
==69398==    by 0x101B12FF: std::_Rb_tree_const_iterator<clang::tooling::Replacement>::operator--() (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B17FF: std::reverse_iterator<std::_Rb_tree_const_iterator<clang::tooling::Replacement> >::operator->() const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B05BF: clang::tooling::applyAllReplacements[abi:cxx11](llvm::StringRef, clang::tooling::Replacements const&) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101099FB: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*)::{lambda(clang::format::TokenAnalyzer&)#1}::operator()(clang::format::TokenAnalyzer&) const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x10109E67: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000C603: clang::format::format(llvm::StringRef) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000D1D7: main (in /home/trippels/llvm_build/bin/clang-format)
==69398== 
==69398== Conditional jump or move depends on uninitialised value(s)
==69398==    at 0x42D3B08: std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) (tree.cc:97)
==69398==    by 0x101B12FF: std::_Rb_tree_const_iterator<clang::tooling::Replacement>::operator--() (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B17FF: std::reverse_iterator<std::_Rb_tree_const_iterator<clang::tooling::Replacement> >::operator->() const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B05E7: clang::tooling::applyAllReplacements[abi:cxx11](llvm::StringRef, clang::tooling::Replacements const&) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101099FB: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*)::{lambda(clang::format::TokenAnalyzer&)#1}::operator()(clang::format::TokenAnalyzer&) const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x10109E67: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000C603: clang::format::format(llvm::StringRef) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000D1D7: main (in /home/trippels/llvm_build/bin/clang-format)
==69398== 
==69398== Conditional jump or move depends on uninitialised value(s)
==69398==    at 0x42D3B08: std::local_Rb_tree_decrement(std::_Rb_tree_node_base*) (tree.cc:97)
==69398==    by 0x101B12FF: std::_Rb_tree_const_iterator<clang::tooling::Replacement>::operator--() (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101B06DF: clang::tooling::applyAllReplacements[abi:cxx11](llvm::StringRef, clang::tooling::Replacements const&) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x101099FB: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*)::{lambda(clang::format::TokenAnalyzer&)#1}::operator()(clang::format::TokenAnalyzer&) const (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x10109E67: clang::format::reformat(clang::format::FormatStyle const&, llvm::StringRef, llvm::ArrayRef<clang::tooling::Range>, llvm::StringRef, bool*) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000C603: clang::format::format(llvm::StringRef) (in /home/trippels/llvm_build/bin/clang-format)
==69398==    by 0x1000D1D7: main (in /home/trippels/llvm_build/bin/clang-format)

This happens even when llvm/clang is build with -O0 and also when build with clang.
gcc-6 libstdc++.so.6 works fine. And clang with -stdlib=libc++ also is fine.

So it looks like a libstdc++ regression. Sorry, but I have no testcase yet.
Comment 1 Markus Trippelsdorf 2017-03-25 12:19:18 UTC
Created attachment 41052 [details]
testcase. valgrind clang-format bench.ii
Comment 2 Markus Trippelsdorf 2017-03-25 15:18:11 UTC
Started with r243379.
Comment 3 Markus Trippelsdorf 2017-03-26 09:06:51 UTC
The problem is here libstdc++-v3/include/bits/stl_tree.h:


 179 #if __cplusplus >= 201103L                                                                                                                                                    
 180     _Rb_tree_header(_Rb_tree_header&& __x) noexcept                                                                                                                           
 181     {                                                                                                                                                                         
 182       if (__x._M_header._M_parent != nullptr)                                                                                                                                 
 183         _M_move_data(__x);                                                                                                                                                    
 184       else                                                                                                                                                                    
 185         {                                                                                                                                                                     
 186           _M_header._M_color = _S_red;                                                                                                                                        
 187           _M_reset();                                                                                                                                                         
 188         }                                                                                                                                                                     
 189     }                                                                                                                                                                         
 190 #endif                                                                                                                                                                        
 191                                                                                                                                                                               
 192     void                                                                                                                                                                      
 193     _M_move_data(_Rb_tree_header& __from)                                                                                                                                     
 194     {                                                                                                                                                                         
 195       _M_header._M_parent = __from._M_header._M_parent;                                                                                                                       
 196       _M_header._M_left = __from._M_header._M_left;                                                                                                                           
 197       _M_header._M_right = __from._M_header._M_right;                                                                                                                         
 198       _M_header._M_parent->_M_parent = &_M_header;                                                                                                                            
 199       _M_node_count = __from._M_node_count;                                                                                                                                   
 200                                                                                                                                                                               
 201       __from._M_reset();                                                                                                                                                      
 202     }                                                                                                                                                                         
 203                                                                                                                                                                               
 204     void                                                                                                                                                                      
 205     _M_reset()                                                                                                                                                                
 206     {                                                                                                                                                                         
 207       _M_header._M_parent = 0;                                                                                                                                                
 208       _M_header._M_left = &_M_header;                                                                                                                                         
 209       _M_header._M_right = &_M_header;                                                                                                                                        
 210       _M_node_count = 0;                                                                                                                                                      
 211     }                                                                                                                                                                         
 212   }; 

on line 183 _M_move_data(__x) doesn't set _M_header._M_color to any value.
So either hard set it to _S_red or augment _M_move_data to copy the color.
Comment 4 Jonathan Wakely 2017-03-26 12:26:30 UTC
I think this is my fault, I asked François to remove a store to _M_color that I thought was redundant.
Comment 5 Markus Trippelsdorf 2017-03-26 12:34:07 UTC
Author: trippels
Date: Sun Mar 26 12:33:35 2017
New Revision: 246483

URL: https://gcc.gnu.org/viewcvs?rev=246483&root=gcc&view=rev
Log:
Fix PR80183 : _M_color not moved

	PR libstdc++/80183
	* include/bits/stl_tree.h:
	(_Rb_tree_header::_M_move_data(_Rb_tree_header&)): Also save _M_color.

Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/include/bits/stl_tree.h
Comment 6 Markus Trippelsdorf 2017-03-26 12:35:35 UTC
Fixed.
Comment 7 François Dumont 2017-03-26 19:27:15 UTC
(In reply to Jonathan Wakely from comment #4)
> I think this is my fault, I asked François to remove a store to _M_color
> that I thought was redundant.

I was surprised that _M_color wasn't move along with other members, with your patch it is now.

However to strictly restore previous behavior you could have only set _M_color to red in the move constructor whether _M_move_data or _M_reset was called. But I prefer current code of course.