new loplugin:noexceptmove

idea from mike kaganski

look for places where we can mark move operators as noexcept, which
makes some STL operations more efficient

Change-Id: Id732b89d1fcadd5ceb0ea2b9d159fed06136330f
Reviewed-on: https://gerrit.libreoffice.org/78251
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
This commit is contained in:
Noel Grandin
2019-08-30 08:12:07 +02:00
parent 0285492a45
commit 6e4a2540d4
38 changed files with 481 additions and 59 deletions
+319
View File
@@ -0,0 +1,319 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// versions before 9.0 didn't have getExceptionSpecType
#include "plugin.hxx"
// clang before V9 does not have API to report exception spec type
#if CLANG_VERSION >= 90000
#include "check.hxx"
#include <string>
#include <set>
/**
Look for move constructors that can be noexcept.
*/
namespace
{
/// Look for the stuff that can be marked noexcept, but only if we also mark some of the callees noexcept.
/// Off by default so as not too annoy people.
constexpr bool bLookForStuffWeCanFix = false;
class NoExceptMove : public loplugin::FilteringPlugin<NoExceptMove>
{
public:
explicit NoExceptMove(loplugin::InstantiationData const& data)
: FilteringPlugin(data)
{
}
virtual void run() override
{
StringRef fn(handler.getMainFileName());
// ONDXPagePtr::operator= calls ONDXPage::ReleaseRef which cannot be noexcept
if (loplugin::isSamePathname(fn,
SRCDIR "/connectivity/source/drivers/dbase/dindexnode.cxx"))
return;
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
}
bool shouldVisitImplicitCode() const { return true; }
bool TraverseCXXConstructorDecl(CXXConstructorDecl*);
bool TraverseCXXMethodDecl(CXXMethodDecl*);
bool VisitCallExpr(const CallExpr*);
bool VisitCXXConstructExpr(const CXXConstructExpr*);
bool VisitVarDecl(const VarDecl*);
private:
llvm::Optional<bool> IsCallThrows(const CallExpr* callExpr);
std::vector<bool> m_ConstructorThrows;
std::vector<std::vector<const Decl*>> m_Exclusions;
std::vector<bool> m_CannotFix;
};
bool NoExceptMove::TraverseCXXConstructorDecl(CXXConstructorDecl* constructorDecl)
{
const bool isMove = constructorDecl->isMoveConstructor()
&& constructorDecl->getExceptionSpecType() == EST_None
&& !constructorDecl->isDefaulted() && !constructorDecl->isDeleted()
&& !ignoreLocation(constructorDecl)
&& constructorDecl->isThisDeclarationADefinition();
if (isMove)
{
m_ConstructorThrows.push_back(false);
m_Exclusions.emplace_back();
m_CannotFix.push_back(false);
}
bool rv = RecursiveASTVisitor::TraverseCXXConstructorDecl(constructorDecl);
if (isMove)
{
if (!m_ConstructorThrows.back())
{
report(DiagnosticsEngine::Warning, "move constructor can be noexcept",
constructorDecl->getSourceRange().getBegin())
<< constructorDecl->getSourceRange();
auto canonicalDecl = constructorDecl->getCanonicalDecl();
if (canonicalDecl != constructorDecl)
report(DiagnosticsEngine::Note, "declaration here",
canonicalDecl->getSourceRange().getBegin())
<< canonicalDecl->getSourceRange();
}
else if (bLookForStuffWeCanFix && !m_CannotFix.back())
{
report(DiagnosticsEngine::Warning, "move constructor can be noexcept",
constructorDecl->getSourceRange().getBegin())
<< constructorDecl->getSourceRange();
auto canonicalDecl = constructorDecl->getCanonicalDecl();
if (canonicalDecl != constructorDecl)
report(DiagnosticsEngine::Note, "declaration here",
canonicalDecl->getSourceRange().getBegin())
<< canonicalDecl->getSourceRange();
for (const Decl* callDecl : m_Exclusions.back())
report(DiagnosticsEngine::Warning, "but need to fix this to be noexcept",
callDecl->getSourceRange().getBegin())
<< callDecl->getSourceRange();
}
m_ConstructorThrows.pop_back();
m_Exclusions.pop_back();
m_CannotFix.pop_back();
}
return rv;
}
bool NoExceptMove::TraverseCXXMethodDecl(CXXMethodDecl* methodDecl)
{
bool isMove = methodDecl->isMoveAssignmentOperator()
&& methodDecl->getExceptionSpecType() == EST_None && !methodDecl->isDefaulted()
&& !methodDecl->isDeleted() && !ignoreLocation(methodDecl)
&& methodDecl->isThisDeclarationADefinition();
if (isMove)
{
StringRef fn = getFileNameOfSpellingLoc(
compiler.getSourceManager().getSpellingLoc(compat::getBeginLoc(methodDecl)));
// SfxObjectShellLock::operator= calls SotObject::OwnerLock whichs in turn calls stuff which cannot be noexcept
if (loplugin::isSamePathname(fn, SRCDIR "/include/sfx2/objsh.hxx"))
isMove = false;
}
if (isMove)
{
m_ConstructorThrows.push_back(false);
m_Exclusions.emplace_back();
m_CannotFix.push_back(false);
}
bool rv = RecursiveASTVisitor::TraverseCXXMethodDecl(methodDecl);
if (isMove)
{
if (!m_ConstructorThrows.back())
{
report(DiagnosticsEngine::Warning, "move operator= can be noexcept",
methodDecl->getSourceRange().getBegin())
<< methodDecl->getSourceRange();
auto canonicalDecl = methodDecl->getCanonicalDecl();
if (canonicalDecl != methodDecl)
report(DiagnosticsEngine::Note, "declaration here",
canonicalDecl->getSourceRange().getBegin())
<< canonicalDecl->getSourceRange();
}
else if (bLookForStuffWeCanFix && !m_CannotFix.back())
{
report(DiagnosticsEngine::Warning, "move operator= can be noexcept",
methodDecl->getSourceRange().getBegin())
<< methodDecl->getSourceRange();
auto canonicalDecl = methodDecl->getCanonicalDecl();
if (canonicalDecl != methodDecl)
report(DiagnosticsEngine::Note, "declaration here",
canonicalDecl->getSourceRange().getBegin())
<< canonicalDecl->getSourceRange();
for (const Decl* callDecl : m_Exclusions.back())
report(DiagnosticsEngine::Warning, "but need to fix this to be noexcept",
callDecl->getSourceRange().getBegin())
<< callDecl->getSourceRange();
}
m_ConstructorThrows.pop_back();
m_Exclusions.pop_back();
m_CannotFix.pop_back();
}
return rv;
}
bool NoExceptMove::VisitCallExpr(const CallExpr* callExpr)
{
if (ignoreLocation(callExpr))
return true;
if (m_ConstructorThrows.empty())
return true;
llvm::Optional<bool> bCallThrows = IsCallThrows(callExpr);
if (!bCallThrows)
{
callExpr->dump();
if (callExpr->getCalleeDecl())
callExpr->getCalleeDecl()->dump();
report(DiagnosticsEngine::Warning, "whats up doc?", callExpr->getSourceRange().getBegin())
<< callExpr->getSourceRange();
m_ConstructorThrows.back() = true;
return true;
}
if (*bCallThrows)
m_ConstructorThrows.back() = true;
return true;
}
static bool IsCallThrowsSpec(clang::ExceptionSpecificationType est)
{
return !(est == EST_DynamicNone || est == EST_NoThrow || est == EST_BasicNoexcept
|| est == EST_NoexceptTrue);
}
bool NoExceptMove::VisitCXXConstructExpr(const CXXConstructExpr* constructExpr)
{
if (ignoreLocation(constructExpr))
return true;
if (m_ConstructorThrows.empty())
return true;
auto constructorDecl = constructExpr->getConstructor();
auto est = constructorDecl->getExceptionSpecType();
if (constructorDecl->isDefaulted() && est == EST_None)
; // ok, non-throwing
else if (IsCallThrowsSpec(est))
{
m_ConstructorThrows.back() = true;
}
return true;
}
bool NoExceptMove::VisitVarDecl(const VarDecl* varDecl)
{
if (varDecl->getLocation().isValid() && ignoreLocation(varDecl))
return true;
if (m_ConstructorThrows.empty())
return true;
// The clang AST does not show me implicit calls to destructors at the end of a block,
// so assume any local var decls of class type will call their destructor.
if (!varDecl->getType()->isRecordType())
return true;
auto cxxRecordDecl = varDecl->getType()->getAsCXXRecordDecl();
if (!cxxRecordDecl)
return true;
auto destructorDecl = cxxRecordDecl->getDestructor();
if (!destructorDecl)
return true;
auto est = destructorDecl->getExceptionSpecType();
if (destructorDecl->isDefaulted() && est == EST_None)
; // ok, non-throwing
else if (IsCallThrowsSpec(est))
{
m_ConstructorThrows.back() = true;
}
return true;
}
llvm::Optional<bool> NoExceptMove::IsCallThrows(const CallExpr* callExpr)
{
const FunctionDecl* calleeFunctionDecl = callExpr->getDirectCallee();
if (calleeFunctionDecl)
{
auto est = calleeFunctionDecl->getExceptionSpecType();
if (bLookForStuffWeCanFix)
{
if (est == EST_None && !ignoreLocation(calleeFunctionDecl))
m_Exclusions.back().push_back(calleeFunctionDecl);
else
m_CannotFix.back() = true;
}
// Whitelist of functions that could be noexcept, but we can't change them because of backwards-compatibility reasons
// css::uno::XInterface::acquire
// css::uno::XInterface::release
if (calleeFunctionDecl->getIdentifier())
{
auto name = calleeFunctionDecl->getName();
if (auto cxxMethodDecl = dyn_cast<CXXMethodDecl>(calleeFunctionDecl))
if (loplugin::ContextCheck(cxxMethodDecl->getParent()->getDeclContext())
.Namespace("uno")
.Namespace("star")
.Namespace("sun")
.Namespace("com")
.GlobalNamespace()
&& (name == "acquire" || name == "release"))
return false;
if (name == "osl_releasePipe" || name == "osl_destroySocketAddr")
return false;
}
return IsCallThrowsSpec(est);
}
auto calleeExpr = callExpr->getCallee();
if (isa<CXXDependentScopeMemberExpr>(calleeExpr) || isa<UnresolvedLookupExpr>(calleeExpr))
{
m_CannotFix.back() = true;
return true;
}
// check for call via function-pointer
clang::QualType calleeType;
if (auto fieldDecl = dyn_cast_or_null<FieldDecl>(callExpr->getCalleeDecl()))
calleeType = fieldDecl->getType();
else if (auto varDecl = dyn_cast_or_null<VarDecl>(callExpr->getCalleeDecl()))
calleeType = varDecl->getType();
else
{
m_CannotFix.back() = true;
return llvm::Optional<bool>();
}
// whitelist of functions that could be noexcept, but we can't change them because of backwards-compatibility reasons
if (auto typedefType = calleeType->getAs<TypedefType>())
if (typedefType->getDecl()->getName() == "uno_ReleaseMappingFunc")
return false;
if (calleeType->isPointerType())
calleeType = calleeType->getPointeeType();
auto funcProto = calleeType->getAs<FunctionProtoType>();
if (!funcProto)
{
m_CannotFix.back() = true;
return llvm::Optional<bool>();
}
auto est = funcProto->getExceptionSpecType();
if (bLookForStuffWeCanFix)
{
m_CannotFix.back() = true; // TODO, could improve
}
return IsCallThrowsSpec(est);
}
loplugin::Plugin::Registration<NoExceptMove> noexceptmove("noexceptmove");
}
#endif // CLANG_VERSION
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
+102
View File
@@ -0,0 +1,102 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include "config_clang.h"
// clang before V9 does not have API to report exception spec type
#if CLANG_VERSION >= 90000
namespace test1
{
class Mapping
{
char* m_pMapping;
// expected-error@+1 {{move constructor can be noexcept [loplugin:noexceptmove]}}
Mapping(Mapping&& other)
: m_pMapping(other.m_pMapping)
{
other.m_pMapping = nullptr;
}
// expected-error@+1 {{move operator= can be noexcept [loplugin:noexceptmove]}}
Mapping& operator=(Mapping&& other)
{
m_pMapping = other.m_pMapping;
other.m_pMapping = nullptr;
return *this;
}
};
};
// No warning expected, because calling throwing function.
namespace test2
{
void foo() noexcept(false);
class Bar
{
Bar(Bar&&) { foo(); }
};
};
// no warning expected, because calling throwing constructor
namespace test3
{
struct Foo
{
Foo() noexcept(false);
};
class Bar
{
Bar(Bar&&) { Foo aFoo; }
};
class Bar2
{
Foo m_foo;
Bar2(Bar2&&) {}
};
};
// No warning expected, because calling throwing destructor.
namespace test4
{
struct Foo
{
~Foo() noexcept(false);
};
class Bar
{
Bar(Bar&&) { Foo aFoo; }
};
};
// Check for calls to defaulted constructors.
namespace test5
{
struct Foo
{
Foo() = default; // non-throwing
};
class Bar
{
Bar(Bar&&) // expected-error {{move constructor can be noexcept [loplugin:noexceptmove]}}
{
Foo aFoo;
(void)aFoo;
}
};
};
#else
// expected-no-diagnostics
#endif // CLANG_VERSION
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
@@ -82,7 +82,7 @@ namespace connectivity
if (mpQuery)
e_book_query_ref(mpQuery);
}
EBookQueryWrapper(EBookQueryWrapper&& rhs)
EBookQueryWrapper(EBookQueryWrapper&& rhs) noexcept
: mpQuery(rhs.mpQuery)
{
rhs.mpQuery = nullptr;
+2 -2
View File
@@ -60,13 +60,13 @@ class Mapping
public:
inline explicit Mapping( uno_Mapping * pMapping = nullptr );
inline Mapping( const Mapping & rMapping );
Mapping(Mapping && other): _pMapping(other._pMapping)
Mapping(Mapping && other) noexcept : _pMapping(other._pMapping)
{ other._pMapping = nullptr; }
inline ~Mapping();
inline Mapping & operator = ( uno_Mapping * pMapping );
Mapping & operator = ( const Mapping & rMapping )
{ return operator = ( rMapping._pMapping ); }
Mapping & operator =(Mapping && other) {
Mapping & operator =(Mapping && other) noexcept {
if (_pMapping != nullptr) {
(*_pMapping->release)(_pMapping);
}
+2 -2
View File
@@ -307,7 +307,7 @@ public:
@param rRef another reference
*/
inline Reference( Reference< interface_type > && rRef );
inline Reference( Reference< interface_type > && rRef ) noexcept;
#endif
/** Up-casting conversion constructor: Copies interface reference.
@@ -586,7 +586,7 @@ public:
@param rRef an interface reference
@return this reference
*/
inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef );
inline Reference< interface_type > & SAL_CALL operator = ( Reference< interface_type > && rRef ) noexcept;
#endif
/** Queries given interface reference for type interface_type.
+2 -2
View File
@@ -126,7 +126,7 @@ inline Reference< interface_type >::Reference( const Reference< interface_type >
#if defined LIBO_INTERNAL_ONLY
template< class interface_type >
inline Reference< interface_type >::Reference( Reference< interface_type > && rRef )
inline Reference< interface_type >::Reference( Reference< interface_type > && rRef ) noexcept
{
_pInterface = rRef._pInterface;
rRef._pInterface = nullptr;
@@ -353,7 +353,7 @@ inline Reference< interface_type > & Reference< interface_type >::operator = (
#if defined LIBO_INTERNAL_ONLY
template< class interface_type >
inline Reference< interface_type > & Reference< interface_type >::operator = (
Reference< interface_type > && rRef )
Reference< interface_type > && rRef ) noexcept
{
if (_pInterface)
_pInterface->release();
+1 -1
View File
@@ -64,7 +64,7 @@ public:
WeakReferenceHelper( const WeakReferenceHelper & rWeakRef );
#if defined LIBO_INTERNAL_ONLY
WeakReferenceHelper(WeakReferenceHelper && other): m_pImpl(other.m_pImpl)
WeakReferenceHelper(WeakReferenceHelper && other) noexcept : m_pImpl(other.m_pImpl)
{ other.m_pImpl = nullptr; }
#endif
+2 -2
View File
@@ -51,7 +51,7 @@ namespace osl
}
#if defined LIBO_INTERNAL_ONLY
Pipe::Pipe(Pipe && other): m_handle(other.m_handle) {
Pipe::Pipe(Pipe && other) noexcept : m_handle(other.m_handle) {
other.m_handle = nullptr;
}
#endif
@@ -97,7 +97,7 @@ namespace osl
}
#if defined LIBO_INTERNAL_ONLY
Pipe & Pipe::operator =(Pipe && other) {
Pipe & Pipe::operator =(Pipe && other) noexcept {
if (m_handle != nullptr) {
osl_releasePipe(m_handle);
}
+2 -2
View File
@@ -59,7 +59,7 @@ public:
inline Pipe(const Pipe& pipe);
#if defined LIBO_INTERNAL_ONLY
inline Pipe(Pipe && other);
inline Pipe(Pipe && other) noexcept;
#endif
/** Constructs a Pipe reference without acquiring the handle
@@ -108,7 +108,7 @@ public:
inline Pipe& SAL_CALL operator= (const Pipe& pipe);
#if defined LIBO_INTERNAL_ONLY
inline Pipe & operator =(Pipe && other);
inline Pipe & operator =(Pipe && other) noexcept;
#endif
/** Assignment operator. If pipe was already created, the old one will
+2 -2
View File
@@ -35,7 +35,7 @@ namespace osl
}
#if defined LIBO_INTERNAL_ONLY
SocketAddr::SocketAddr(SocketAddr && other): m_handle(other.m_handle) {
SocketAddr::SocketAddr(SocketAddr && other) noexcept : m_handle(other.m_handle) {
other.m_handle = nullptr;
}
#endif
@@ -141,7 +141,7 @@ namespace osl
}
#if defined LIBO_INTERNAL_ONLY
SocketAddr & SocketAddr::operator =(SocketAddr && other) {
SocketAddr & SocketAddr::operator =(SocketAddr && other) noexcept {
if (m_handle != nullptr) {
osl_destroySocketAddr(m_handle);
}
+2 -2
View File
@@ -51,7 +51,7 @@ namespace osl
inline SocketAddr(const SocketAddr& Addr);
#if defined LIBO_INTERNAL_ONLY
inline SocketAddr(SocketAddr && other);
inline SocketAddr(SocketAddr && other) noexcept;
#endif
/** The SocketAddr takes over the responsibility of the handle (which means
@@ -141,7 +141,7 @@ namespace osl
inline SocketAddr & SAL_CALL operator= (const SocketAddr& Addr);
#if defined LIBO_INTERNAL_ONLY
inline SocketAddr & operator =(SocketAddr && other);
inline SocketAddr & operator =(SocketAddr && other) noexcept;
#endif
/** Assigns the socket addr without copyconstructing it.
+1 -1
View File
@@ -90,7 +90,7 @@ public:
/// Copy constructor
inline Registry(const Registry& toCopy);
Registry(Registry && other): m_pApi(other.m_pApi), m_hImpl(other.m_hImpl)
Registry(Registry && other) noexcept : m_pApi(other.m_pApi), m_hImpl(other.m_hImpl)
{ other.m_hImpl = nullptr; }
/// Destructor. The Destructor close the registry if it is open.
+2 -2
View File
@@ -190,7 +190,7 @@ public:
*/
inline ByteSequence( const ByteSequence & rSeq );
#if defined LIBO_INTERNAL_ONLY
inline ByteSequence( ByteSequence && rSeq );
inline ByteSequence( ByteSequence && rSeq ) noexcept;
#endif
/** Copy constructor Creates a copy from the C-Handle.
@@ -236,7 +236,7 @@ public:
*/
inline ByteSequence & SAL_CALL operator = ( const ByteSequence & rSeq );
#if defined LIBO_INTERNAL_ONLY
inline ByteSequence & SAL_CALL operator = ( ByteSequence && rSeq );
inline ByteSequence & SAL_CALL operator = ( ByteSequence && rSeq ) noexcept;
#endif
/** Gets the length of sequence.
+2 -2
View File
@@ -41,7 +41,7 @@ inline ByteSequence::ByteSequence( const ByteSequence & rSeq )
}
#if defined LIBO_INTERNAL_ONLY
inline ByteSequence::ByteSequence( ByteSequence && rSeq )
inline ByteSequence::ByteSequence( ByteSequence && rSeq ) noexcept
: _pSequence(rSeq._pSequence)
{
rSeq._pSequence = nullptr;
@@ -95,7 +95,7 @@ inline ByteSequence & ByteSequence::operator = ( const ByteSequence & rSeq )
}
#if defined LIBO_INTERNAL_ONLY
inline ByteSequence & ByteSequence::operator = ( ByteSequence && rSeq )
inline ByteSequence & ByteSequence::operator = ( ByteSequence && rSeq ) noexcept
{
::rtl_byte_sequence_release(_pSequence);
_pSequence = rSeq._pSequence;
+1 -1
View File
@@ -77,7 +77,7 @@ public:
#ifdef LIBO_INTERNAL_ONLY
/** Move constructor...
*/
Reference (Reference<reference_type> && handle)
Reference (Reference<reference_type> && handle) noexcept
: m_pBody (handle.m_pBody)
{
handle.m_pBody = nullptr;
+2 -2
View File
@@ -129,7 +129,7 @@ public:
@param str an OString.
@since LibreOffice 5.2
*/
OString( OString && str )
OString( OString && str ) noexcept
{
pData = str.pData;
str.pData = nullptr;
@@ -313,7 +313,7 @@ public:
@param str an OString.
@since LibreOffice 5.2
*/
OString & operator=( OString && str )
OString & operator=( OString && str ) noexcept
{
rtl_string_release( pData );
pData = str.pData;
+2 -2
View File
@@ -158,7 +158,7 @@ public:
@param str an OUString.
@since LibreOffice 5.2
*/
OUString( OUString && str )
OUString( OUString && str ) noexcept
{
pData = str.pData;
str.pData = nullptr;
@@ -462,7 +462,7 @@ public:
@param str an OUString.
@since LibreOffice 5.2
*/
OUString & operator=( OUString && str )
OUString & operator=( OUString && str ) noexcept
{
rtl_uString_release( pData );
pData = str.pData;
+2 -2
View File
@@ -778,7 +778,7 @@ protected:
public:
SfxObjectShellLock() { pObj = nullptr; }
inline SfxObjectShellLock( const SfxObjectShellLock & rObj );
inline SfxObjectShellLock( SfxObjectShellLock && rObj );
inline SfxObjectShellLock( SfxObjectShellLock && rObj ) noexcept;
inline SfxObjectShellLock( SfxObjectShell * pObjP );
inline void Clear();
inline ~SfxObjectShellLock();
@@ -797,7 +797,7 @@ inline SfxObjectShellLock::SfxObjectShellLock( const SfxObjectShellLock & rObj )
if( pObj )
pObj->OwnerLock( true );
}
inline SfxObjectShellLock::SfxObjectShellLock( SfxObjectShellLock && rObj )
inline SfxObjectShellLock::SfxObjectShellLock( SfxObjectShellLock && rObj ) noexcept
{
pObj = rObj.pObj;
rObj.pObj = nullptr;
+2 -2
View File
@@ -147,7 +147,7 @@ public:
/** Move construction.
*/
OStoreDirectory (OStoreDirectory && rhs)
OStoreDirectory (OStoreDirectory && rhs) noexcept
: m_hImpl (rhs.m_hImpl)
{
rhs.m_hImpl = nullptr;
@@ -167,7 +167,7 @@ public:
/** Move assignment.
*/
OStoreDirectory & operator= (OStoreDirectory && rhs)
OStoreDirectory & operator= (OStoreDirectory && rhs) noexcept
{
if (m_hImpl)
(void) store_releaseHandle (m_hImpl);
+2 -2
View File
@@ -60,7 +60,7 @@ public:
pImp( rObj.pImp )
{
}
SvGlobalName( SvGlobalName && rObj ) :
SvGlobalName( SvGlobalName && rObj ) noexcept :
pImp( std::move(rObj.pImp) )
{
}
@@ -75,7 +75,7 @@ public:
SvGlobalName( const SvGUID & rId );
SvGlobalName & operator = ( const SvGlobalName & rObj );
SvGlobalName & operator = ( SvGlobalName && rObj );
SvGlobalName & operator = ( SvGlobalName && rObj ) noexcept;
~SvGlobalName();
TOOLS_DLLPUBLIC friend SvStream & operator >> ( SvStream &, SvGlobalName & );
+2 -2
View File
@@ -98,7 +98,7 @@ public:
sal_uInt16 nPoints );
Polygon( const tools::Polygon& rPoly );
Polygon( tools::Polygon&& rPoly);
Polygon( tools::Polygon&& rPoly) noexcept;
~Polygon();
void SetPoint( const Point& rPt, sal_uInt16 nPos );
@@ -155,7 +155,7 @@ public:
Point& operator[]( sal_uInt16 nPos );
tools::Polygon& operator=( const tools::Polygon& rPoly );
tools::Polygon& operator=( tools::Polygon&& rPoly );
tools::Polygon& operator=( tools::Polygon&& rPoly ) noexcept;
bool operator==( const tools::Polygon& rPoly ) const;
bool operator!=( const tools::Polygon& rPoly ) const
{ return !(Polygon::operator==( rPoly )); }
+2 -2
View File
@@ -83,7 +83,7 @@ public:
*/
inline TypeDescription( const TypeDescription & rDescr );
#if defined LIBO_INTERNAL_ONLY
TypeDescription(TypeDescription && other): _pTypeDescr(other._pTypeDescr)
TypeDescription(TypeDescription && other) noexcept : _pTypeDescr(other._pTypeDescr)
{ other._pTypeDescr = nullptr; }
#endif
/** Constructor:
@@ -115,7 +115,7 @@ public:
{ return this->operator =( rTypeDescr.get() ); }
#if defined LIBO_INTERNAL_ONLY
TypeDescription & operator =(TypeDescription && other) {
TypeDescription & operator =(TypeDescription && other) noexcept {
if (_pTypeDescr != nullptr) {
typelib_typedescription_release(_pTypeDescr);
}
+1 -1
View File
@@ -59,7 +59,7 @@ public:
inline UnoInterfaceReference( UnoInterfaceReference const & ref );
#if defined LIBO_INTERNAL_ONLY
UnoInterfaceReference(UnoInterfaceReference && other):
UnoInterfaceReference(UnoInterfaceReference && other) noexcept :
m_pUnoI(other.m_pUnoI)
{ other.m_pUnoI = nullptr; }
#endif
+1 -1
View File
@@ -95,7 +95,7 @@ public:
inline Environment( const Environment & rEnv );
#if defined LIBO_INTERNAL_ONLY
Environment(Environment && other): _pEnv(other._pEnv)
Environment(Environment && other) noexcept : _pEnv(other._pEnv)
{ other._pEnv = nullptr; }
#endif
+2 -2
View File
@@ -111,7 +111,7 @@ public:
inline Mapping( const Mapping & rMapping );
#if defined LIBO_INTERNAL_ONLY
Mapping(Mapping && other): _pMapping(other._pMapping)
Mapping(Mapping && other) noexcept : _pMapping(other._pMapping)
{ other._pMapping = nullptr; }
#endif
@@ -134,7 +134,7 @@ public:
{ return operator = ( rMapping._pMapping ); }
#if defined LIBO_INTERNAL_ONLY
Mapping & operator =(Mapping && other) {
Mapping & operator =(Mapping && other) noexcept {
if (_pMapping != nullptr) {
(*_pMapping->release)(_pMapping);
}
+1 -1
View File
@@ -83,7 +83,7 @@ struct TItemInfo
{
}
TItemInfo(TItemInfo&& other)
TItemInfo(TItemInfo&& other) noexcept
: pItem(std::move(other.pItem))
, eItem(other.eItem)
{
+1 -1
View File
@@ -71,7 +71,7 @@ public:
TempFile( const OUString& rLeadingChars, bool _bStartWithZero=true, const OUString* pExtension=nullptr,
const OUString* pParent=nullptr, bool bCreateParentDirs=false );
TempFile(TempFile && other);
TempFile(TempFile && other) noexcept;
/**
TempFile will be removed from disk in dtor if EnableKillingFile(true) was called before.
+1 -1
View File
@@ -42,7 +42,7 @@ public:
AlphaMask& operator=( const Bitmap& rBitmap );
AlphaMask& operator=( const AlphaMask& rAlphaMask ) { return static_cast<AlphaMask&>( Bitmap::operator=( rAlphaMask ) ); }
AlphaMask& operator=( AlphaMask&& rAlphaMask ) { return static_cast<AlphaMask&>( Bitmap::operator=( std::move(rAlphaMask) ) ); }
AlphaMask& operator=( AlphaMask&& rAlphaMask ) noexcept { return static_cast<AlphaMask&>( Bitmap::operator=( std::move(rAlphaMask) ) ); }
bool operator!() const { return Bitmap::operator!(); }
bool operator==( const AlphaMask& rAlphaMask ) const { return Bitmap::operator==(rAlphaMask); }
bool operator!=( const AlphaMask& rAlphaMask ) const { return Bitmap::operator!=(rAlphaMask); }
+2 -2
View File
@@ -48,7 +48,7 @@ class VCL_DLLPUBLIC Font
public:
explicit Font();
Font( const Font& ); // TODO make me explicit
Font( Font&& );
Font( Font&& ) noexcept;
explicit Font( const OUString& rFamilyName, const Size& );
explicit Font( const OUString& rFamilyName, const OUString& rStyleName, const Size& );
explicit Font( FontFamily eFamily, const Size& );
@@ -150,7 +150,7 @@ public:
void GetFontAttributes( FontAttributes& rAttrs ) const;
Font& operator=( const Font& );
Font& operator=( Font&& );
Font& operator=( Font&& ) noexcept;
bool operator==( const Font& ) const;
bool operator!=( const Font& rFont ) const
{ return !(Font::operator==( rFont )); }
+2 -2
View File
@@ -72,7 +72,7 @@ public:
explicit Region(const tools::PolyPolygon& rPolyPoly);
explicit Region(const basegfx::B2DPolyPolygon&);
Region(const vcl::Region& rRegion);
Region(vcl::Region&& rRegion);
Region(vcl::Region&& rRegion) noexcept;
~Region();
// direct access to contents
@@ -114,7 +114,7 @@ public:
bool IsOver( const tools::Rectangle& rRect ) const;
vcl::Region& operator=( const vcl::Region& rRegion );
vcl::Region& operator=( vcl::Region&& rRegion );
vcl::Region& operator=( vcl::Region&& rRegion ) noexcept;
vcl::Region& operator=( const tools::Rectangle& rRect );
bool operator==( const vcl::Region& rRegion ) const;
@@ -38,6 +38,7 @@ $(eval $(call gb_CompilerTest_add_exception_objects,compilerplugins_clang, \
compilerplugins/clang/test/loopvartoosmall \
compilerplugins/clang/test/nullptr \
compilerplugins/clang/test/mapindex \
compilerplugins/clang/test/noexceptmove \
compilerplugins/clang/test/oncevar \
compilerplugins/clang/test/oslendian-1 \
compilerplugins/clang/test/oslendian-2 \
+2 -2
View File
@@ -76,8 +76,8 @@ class IDocumentMarkAccess
iterator(std::vector<::sw::mark::MarkBase*>::const_iterator const& rIter);
iterator(iterator const& rOther);
iterator& operator=(iterator const& rOther);
iterator(iterator && rOther);
iterator& operator=(iterator && rOther);
iterator(iterator && rOther) noexcept;
iterator& operator=(iterator && rOther) noexcept;
~iterator();
// FIXME unfortunately there's a requirement on input iterator
+2 -2
View File
@@ -80,12 +80,12 @@ auto IDocumentMarkAccess::iterator::operator=(iterator const& rOther) -> iterato
return *this;
}
IDocumentMarkAccess::iterator::iterator(iterator && rOther)
IDocumentMarkAccess::iterator::iterator(iterator && rOther) noexcept
: m_pIter(std::move(rOther.m_pIter))
{
}
auto IDocumentMarkAccess::iterator::operator=(iterator && rOther) -> iterator&
auto IDocumentMarkAccess::iterator::operator=(iterator && rOther) noexcept -> iterator&
{
m_pIter = std::move(rOther.m_pIter);
return *this;
+2 -2
View File
@@ -872,7 +872,7 @@ Polygon::Polygon( const tools::Polygon& rPoly ) : mpImplPolygon(rPoly.mpImplPoly
{
}
Polygon::Polygon( tools::Polygon&& rPoly)
Polygon::Polygon( tools::Polygon&& rPoly) noexcept
: mpImplPolygon(std::move(rPoly.mpImplPolygon))
{
}
@@ -1555,7 +1555,7 @@ tools::Polygon& Polygon::operator=( const tools::Polygon& rPoly )
return *this;
}
tools::Polygon& Polygon::operator=( tools::Polygon&& rPoly )
tools::Polygon& Polygon::operator=( tools::Polygon&& rPoly ) noexcept
{
mpImplPolygon = std::move(rPoly.mpImplPolygon);
return *this;
+1 -1
View File
@@ -105,7 +105,7 @@ SvGlobalName & SvGlobalName::operator = ( const SvGlobalName & rObj )
return *this;
}
SvGlobalName & SvGlobalName::operator = ( SvGlobalName && rObj )
SvGlobalName & SvGlobalName::operator = ( SvGlobalName && rObj ) noexcept
{
pImp = std::move(rObj.pImp);
return *this;
+1 -1
View File
@@ -370,7 +370,7 @@ TempFile::TempFile( const OUString& rLeadingChars, bool _bStartWithZero,
true, true, bCreateParentDirs );
}
TempFile::TempFile(TempFile && other):
TempFile::TempFile(TempFile && other) noexcept :
aName(std::move(other.aName)), pStream(std::move(other.pStream)), bIsDirectory(other.bIsDirectory),
bKillingFileEnabled(other.bKillingFileEnabled)
{
+2 -2
View File
@@ -49,7 +49,7 @@ Font::Font( const vcl::Font& rFont ) : mpImplFont( rFont.mpImplFont )
{
}
Font::Font( vcl::Font&& rFont ) : mpImplFont( std::move(rFont.mpImplFont) )
Font::Font( vcl::Font&& rFont ) noexcept : mpImplFont( std::move(rFont.mpImplFont) )
{
}
@@ -283,7 +283,7 @@ Font& Font::operator=( const vcl::Font& rFont )
return *this;
}
Font& Font::operator=( vcl::Font&& rFont )
Font& Font::operator=( vcl::Font&& rFont ) noexcept
{
mpImplFont = std::move(rFont.mpImplFont);
return *this;
+2 -2
View File
@@ -365,7 +365,7 @@ Region::Region(const basegfx::B2DPolyPolygon& rPolyPoly)
Region::Region(const vcl::Region&) = default;
Region::Region(vcl::Region&& rRegion)
Region::Region(vcl::Region&& rRegion) noexcept
: mpB2DPolyPolygon(std::move(rRegion.mpB2DPolyPolygon)),
mpPolyPolygon(std::move(rRegion.mpPolyPolygon)),
mpRegionBand(std::move(rRegion.mpRegionBand)),
@@ -1425,7 +1425,7 @@ void vcl::Region::SetEmpty()
Region& vcl::Region::operator=( const vcl::Region& ) = default;
Region& vcl::Region::operator=( vcl::Region&& rRegion )
Region& vcl::Region::operator=( vcl::Region&& rRegion ) noexcept
{
mpB2DPolyPolygon = std::move(rRegion.mpB2DPolyPolygon);
mpPolyPolygon = std::move(rRegion.mpPolyPolygon);