This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [C++ PATCH] Fix up decl_in_std_namespace_p handling of --enable-symvers=gnu-versioned-namespace
- From: Jakub Jelinek <jakub at redhat dot com>
- To: Jason Merrill <jason at redhat dot com>, Marek Polacek <polacek at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Wed, 30 Oct 2019 10:58:57 +0100
- Subject: Re: [C++ PATCH] Fix up decl_in_std_namespace_p handling of --enable-symvers=gnu-versioned-namespace
- References: <20191024223958.GQ2116@tucnak> <20191025144418.GE21634@redhat.com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Fri, Oct 25, 2019 at 10:44:18AM -0400, Marek Polacek wrote:
> That is... sneaky. I guess I/we need to test with
> --enable-symvers=gnu-versioned-namespace every now and then.
Indeed.
> Probably deserves a comment.
Ok, here it is with a comment, bootstrapped/regtested again last night:
2019-10-30 Jakub Jelinek <jakub@redhat.com>
* 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.
--- gcc/cp/typeck.c.jj 2019-10-23 20:38:00.022871653 +0200
+++ gcc/cp/typeck.c 2019-10-24 11:36:14.982981481 +0200
@@ -9395,8 +9395,19 @@ maybe_warn_about_returning_address_of_lo
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. */
--- gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move6.C.jj 2019-10-24 11:26:17.535148996 +0200
+++ gcc/testsuite/g++.dg/cpp0x/Wpessimizing-move6.C 2019-10-24 11:27:17.359232014 +0200
@@ -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<typename _Tp>
+ struct remove_reference
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ struct remove_reference<_Tp&&>
+ { typedef _Tp type; };
+
+ template<typename _Tp>
+ constexpr typename std::remove_reference<_Tp>::type&&
+ move(_Tp&& __t) noexcept
+ { return static_cast<typename std::remove_reference<_Tp>::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);
+}
Jakub