From: Jakub Jelinek Date: Wed, 30 Oct 2019 21:53:37 +0000 (+0100) Subject: typeck.c (decl_in_std_namespace_p): Return true also for decls in inline namespaces... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=97ccc60e0c8590e22488e909464fc591eb8b0534;p=gcc.git typeck.c (decl_in_std_namespace_p): Return true also for decls in inline namespaces inside of std namespace. * typeck.c (decl_in_std_namespace_p): Return true also for decls in inline namespaces inside of std namespace. * g++.dg/cpp0x/Wpessimizing-move6.C: New test. From-SVN: r277648 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 402d321d0e7..46b8fe02907 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2019-10-30 Jakub Jelinek + + * typeck.c (decl_in_std_namespace_p): Return true also for decls + in inline namespaces inside of std namespace. + 2019-10-30 Bernd Edlinger PR c++/92024 diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 477c6a39955..03c39b3e3b9 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -9395,8 +9395,19 @@ maybe_warn_about_returning_address_of_local (tree retval) bool decl_in_std_namespace_p (tree decl) { - return (decl != NULL_TREE - && DECL_NAMESPACE_STD_P (decl_namespace_context (decl))); + while (decl) + { + decl = decl_namespace_context (decl); + if (DECL_NAMESPACE_STD_P (decl)) + return true; + /* Allow inline namespaces inside of std namespace, e.g. with + --enable-symvers=gnu-versioned-namespace std::forward would be + actually std::_8::forward. */ + if (!DECL_NAMESPACE_INLINE_P (decl)) + return false; + decl = CP_DECL_CONTEXT (decl); + } + return false; } /* Returns true if FN, a CALL_EXPR, is a call to std::forward. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 67de104fb1d..d64275b8ea5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2019-10-30 Jakub Jelinek + + * g++.dg/cpp0x/Wpessimizing-move6.C: New test. + 2019-10-30 Bernd Edlinger PR c++/92024 diff --git a/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move6.C b/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move6.C new file mode 100644 index 00000000000..64675566115 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move6.C @@ -0,0 +1,135 @@ +// PR c++/86981 +// { dg-do compile { target c++11 } } +// { dg-options "-Wpessimizing-move" } + +// Define std::move. +namespace std { + inline namespace _8 { } + namespace _8 { + template + struct remove_reference + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&> + { typedef _Tp type; }; + + template + struct remove_reference<_Tp&&> + { typedef _Tp type; }; + + template + constexpr typename std::remove_reference<_Tp>::type&& + move(_Tp&& __t) noexcept + { return static_cast::type&&>(__t); } + } +} + +struct T { + T() { } + T(const T&) { } + T(T&&) { } +}; +struct U { + U() { } + U(const U&) { } + U(U&&) { } + U(T) { } +}; + +T g; + +T +fn1 () +{ + T t; + return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" } +} + +T +fn2 () +{ + // Not a local variable. + return std::move (g); +} + +int +fn3 () +{ + int i = 42; + // Not a class type. + return std::move (i); +} + +T +fn4 (bool b) +{ + T t; + if (b) + throw std::move (t); + return std::move (t); // { dg-warning "moving a local object in a return statement prevents copy elision" } +} + +T +fn5 (T t) +{ + // Function parameter; std::move is redundant but not pessimizing. + return std::move (t); +} + +U +fn6 (T t, U u, bool b) +{ + if (b) + return std::move (t); + else + // Function parameter; std::move is redundant but not pessimizing. + return std::move (u); +} + +U +fn6 (bool b) +{ + T t; + U u; + if (b) + return std::move (t); + else + return std::move (u); // { dg-warning "moving a local object in a return statement prevents copy elision" } +} + +T +fn7 () +{ + static T t; + // Non-local; don't warn. + return std::move (t); +} + +T +fn8 () +{ + return T(); +} + +T +fn9 (int i) +{ + T t; + + switch (i) + { + case 1: + return std::move ((t)); // { dg-warning "moving a local object in a return statement prevents copy elision" } + case 2: + return (std::move (t)); // { dg-warning "moving a local object in a return statement prevents copy elision" } + default: + return (std::move ((t))); // { dg-warning "moving a local object in a return statement prevents copy elision" } + } +} + +int +fn10 () +{ + return std::move (42); +}