Commit 97ccc60e by Jakub Jelinek Committed by Jakub Jelinek

typeck.c (decl_in_std_namespace_p): Return true also for decls in inline…

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
parent e0d91792
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.
2019-10-30 Bernd Edlinger <bernd.edlinger@hotmail.de> 2019-10-30 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c++/92024 PR c++/92024
......
...@@ -9395,8 +9395,19 @@ maybe_warn_about_returning_address_of_local (tree retval) ...@@ -9395,8 +9395,19 @@ maybe_warn_about_returning_address_of_local (tree retval)
bool bool
decl_in_std_namespace_p (tree decl) decl_in_std_namespace_p (tree decl)
{ {
return (decl != NULL_TREE while (decl)
&& DECL_NAMESPACE_STD_P (decl_namespace_context (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. */ /* Returns true if FN, a CALL_EXPR, is a call to std::forward. */
......
2019-10-30 Jakub Jelinek <jakub@redhat.com>
* g++.dg/cpp0x/Wpessimizing-move6.C: New test.
2019-10-30 Bernd Edlinger <bernd.edlinger@hotmail.de> 2019-10-30 Bernd Edlinger <bernd.edlinger@hotmail.de>
PR c++/92024 PR c++/92024
......
// 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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment