https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77542

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
                 CC|                            |msebor at gcc dot gnu.org
      Known to work|                            |7.3.0, 8.2.0, 9.0
         Resolution|---                         |FIXED
      Known to fail|                            |5.3.0, 6.4.0

--- Comment #4 from Martin Sebor <msebor at gcc dot gnu.org> ---
After fixing the test in attachment 39608 I get the output below which I think
is what the reporter expected.  Resolving as fixed.

$ cat t.C && xg++ -S -Wall t.C
#include <memory>

class Foo {
public:
  void close() { }
private:
  int foo;
};

struct FooDeleter
{
  void operator()(Foo *foo) { foo->close(); }
};

class Test {
public:
  typedef std::unique_ptr<Foo, FooDeleter> BindScope;

  template <typename... Args>
  BindScope bind(Args&&... args) __attribute__((warn_unused_result));

  BindScope checkWarningInt(int arg) __attribute__((warn_unused_result));
  BindScope checkWarningFoo(int arg) __attribute__((warn_unused_result));

  operator Foo*() { return m_ptr.get(); }
private:
  std::unique_ptr<Foo> m_ptr;
};

template <typename... Args>
Test::BindScope Test::bind(Args&&... args) {
  BindScope bindScope(*this);
  return std::move(bindScope);
}

Test::BindScope Test::checkWarningFoo(int arg) {
  BindScope bindScope(*this);
  return std::move(bindScope);
}

Test::BindScope Test::checkWarningInt(int arg) {
  return 0;
}

int main(int argc, char *argv[]) {
  Test t;
  t.bind(1, "foo"); // no warning <--- that's my bug
  t.checkWarningFoo(1); // emits warning 
  t.checkWarningInt(1); // emits warning 
}

t.C: In member function ‘Test::BindScope Test::checkWarningFoo(int)’:
t.C:38:19: warning: moving a local object in a return statement prevents copy
elision [-Wpessimizing-move]
38 |   return std::move(bindScope);
   |          ~~~~~~~~~^~~~~~~~~~~
t.C:38:19: note: remove ‘std::move’ call
t.C: In function ‘int main(int, char**)’:
t.C:47:19: warning: ignoring return value of ‘Test::BindScope Test::bind(Args&&
...) [with Args = {int, const char (&)[4]}; Test::BindScope =
std::unique_ptr<Foo, FooDeleter>]’, declared with attribute warn_unused_result
[-Wunused-result]
47 |   t.bind(1, "foo"); // no warning <--- that's my bug
   |                   ^
t.C:31:17: note: declared here
31 | Test::BindScope Test::bind(Args&&... args) {
   |                 ^~~~
t.C:48:23: warning: ignoring return value of ‘Test::BindScope
Test::checkWarningFoo(int)’, declared with attribute warn_unused_result
[-Wunused-result]
48 |   t.checkWarningFoo(1); // emits warning
   |                       ^
t.C:36:17: note: declared here
36 | Test::BindScope Test::checkWarningFoo(int arg) {
   |                 ^~~~
t.C:49:23: warning: ignoring return value of ‘Test::BindScope
Test::checkWarningInt(int)’, declared with attribute warn_unused_result
[-Wunused-result]
49 |   t.checkWarningInt(1); // emits warning
   |                       ^
t.C:41:17: note: declared here
41 | Test::BindScope Test::checkWarningInt(int arg) {
   |                 ^~~~
t.C: In instantiation of ‘Test::BindScope Test::bind(Args&& ...) [with Args =
{int, const char (&)[4]}; Test::BindScope = std::unique_ptr<Foo, FooDeleter>]’:
t.C:47:18:   required from here
t.C:33:29: warning: moving a local object in a return statement prevents copy
elision [-Wpessimizing-move]
33 |   return std::move(bindScope);
   |                             ^
t.C:33:29: note: remove ‘std::move’ call

Reply via email to