Bug 61528

Summary: std::min std::max and RValue
Product: gcc Reporter: Lisp2D <lisp2d>
Component: c++Assignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED DUPLICATE    
Severity: normal CC: daniel.kruegler
Priority: P3    
Version: 4.8.1   
Target Milestone: ---   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed:

Description Lisp2D 2014-06-16 17:59:20 UTC
Declaring reference of result of functions MIN or MAX we get a DEAD memory when one of arguments is an RValue.

// gcc -std=c++11 -Os bug.cpp
// gcc -std=c++11 -O2 bug.cpp
#include<iostream>

void  f(size_t  const & x){
  std::cout <<  "f:x="  <<  x <<  std::endl;}

int main(void){
  size_t  x{1};
  size_t  y{2};
  size_t  z{4};
  size_t  const & i=std::min(z,x  + y);
  f(i);
  size_t  const & a=std::max(x,y  + z);
  f(a);}
Comment 1 Marc Glisse 2014-06-16 18:07:31 UTC
Yes, that's required by the standard, nothing we can do about it.
Comment 2 Lisp2D 2014-06-16 18:33:12 UTC
Issue a warning would not hurt.
Comment 3 Marc Glisse 2014-06-16 19:31:45 UTC
The warning is discussed in PR 60517.
Comment 4 Lisp2D 2014-06-16 19:54:36 UTC
 Likely error in the standard. The right set of functions must return a copy of the data and return a the temporary link with real data.
 Working version of it:

size_t  const & min2(size_t const & x,size_t  const & y){
  return  std::min(x,y);}

size_t  min2(size_t const &&  x,size_t  const & y){
  return  {std::min(x,y)};}

size_t  min2(size_t const &  x,size_t  const && y){
  return  {std::min(x,y)};}  


May be do like this?
Comment 5 Marc Glisse 2014-06-16 21:10:22 UTC
Feel free to post a message on https://groups.google.com/a/isocpp.org/forum/#!forum/std-proposals to suggest this. https://isocpp.org/std gives information on making official proposals. In gcc we only implement what the standard tells us.
Comment 6 Daniel Krügler 2014-06-24 18:27:05 UTC
(In reply to Marc Glisse from comment #5)
> Feel free to post a message on
> https://groups.google.com/a/isocpp.org/forum/#!forum/std-proposals to
> suggest this. https://isocpp.org/std gives information on making official
> proposals. In gcc we only implement what the standard tells us.

It is off-topic here, but Howard's similar proposal had been rejected:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2199.html

Well yes, that is now 7 years ago...
Comment 7 Paolo Carlini 2014-06-26 17:22:09 UTC
Linking to the diagnostic issue.

*** This bug has been marked as a duplicate of bug 60517 ***
Comment 8 Marc Glisse 2014-11-22 15:40:17 UTC
If I mark f as static or inline (so the optimizer changes f to take its argument by value), I get with g++-5:

w2.c: In function 'int main()':
w2.c:11:7: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
   f(i);
       ^
w2.c:13:7: warning: '<anonymous>' is used uninitialized in this function [-Wuninitialized]
   f(a);
       ^

(not the best error message, but a good first step)

It is quite fragile though, if instead f is inlined (rename main to help convince the optimizer), we end up with:
  _49 = std::basic_ostream<char>::_M_insert<long unsigned int> (&cout, _9(D));
and don't warn about it (I didn't check, but I assume _9 is marked TREE_NO_WARNING).