2017-05-22 13:25:58 +02:00
/* -*- 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/.
*/
2018-08-16 13:46:39 +02:00
# include <sal/config.h>
# include <config_clang.h>
2017-08-23 08:49:02 +02:00
# include <array>
2018-08-17 14:40:29 +02:00
# include <memory>
2018-01-15 14:56:29 +02:00
# include <vector>
2017-08-23 08:49:02 +02:00
# include <unordered_map>
2017-07-13 20:42:04 +02:00
struct XXX {
~ XXX ( ) { }
} ;
2017-05-22 13:25:58 +02:00
2017-06-26 09:48:30 +02:00
class Foo1 {
2017-07-13 20:42:04 +02:00
XXX * m_pbar ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2017-06-26 09:48:30 +02:00
~ Foo1 ( )
2017-05-22 13:25:58 +02:00
{
2018-01-10 11:29:36 +02:00
delete m_pbar ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2017-05-22 13:25:58 +02:00
m_pbar = nullptr ;
}
} ;
2017-06-26 09:48:30 +02:00
class Foo2 {
char * m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
char * m_pbar2 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo2 ( )
{
2018-01-10 11:29:36 +02:00
delete [ ] m_pbar1 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
delete [ ] m_pbar2 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2017-06-26 09:48:30 +02:00
}
} ;
class Foo3 {
char * m_pbar ;
bool bMine ;
~ Foo3 ( )
{
if ( bMine )
delete [ ] m_pbar ;
}
} ;
2017-08-23 08:49:02 +02:00
class Class4 {
int * m_pbar [ 10 ] ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Class4 ( )
{
for ( int i = 0 ; i < 10 ; + + i )
2019-01-17 16:48:23 +02:00
delete m_pbar [ i ] ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
}
} ;
class Class5 {
int * m_pbar [ 10 ] ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Class5 ( )
{
2018-11-08 13:32:22 +02:00
for ( auto p : m_pbar ) // expected-note {{var is here [loplugin:useuniqueptr]}}
delete p ; // expected-error {{rather manage this with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}} expected-error {{call to delete on a var, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
}
} ;
2018-08-16 13:46:39 +02:00
class Class5a {
int * m_pbar [ 10 ] ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Class5a ( )
{
2018-11-08 13:32:22 +02:00
for ( auto p : m_pbar ) // expected-note {{var is here [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
{
int x = 1 ;
x = x + 2 ;
2018-11-08 13:32:22 +02:00
delete p ; // expected-error {{rather manage this with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}} expected-error {{call to delete on a var, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
}
}
} ;
2017-08-23 08:49:02 +02:00
class Class6 {
std : : array < int * , 10 > m_pbar ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Class6 ( )
{
2018-11-08 13:32:22 +02:00
for ( auto p : m_pbar ) // expected-note {{var is here [loplugin:useuniqueptr]}}
delete p ; // expected-error {{rather manage this with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}} expected-error {{call to delete on a var, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
}
} ;
class Class7 {
std : : array < int * , 10 > m_pbar ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Class7 ( )
{
for ( int i = 0 ; i < 10 ; + + i )
2019-01-17 16:48:23 +02:00
delete m_pbar [ i ] ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
}
} ;
class Class8 {
2018-07-13 10:50:22 +02:00
std : : unordered_map < int , int * > m_pbar ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
~ Class8 ( )
{
2018-10-05 09:49:57 +02:00
for ( auto & i : m_pbar )
2018-09-17 10:56:28 +02:00
delete i . second ; // expected-error {{rather manage this with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2017-08-23 08:49:02 +02:00
}
} ;
2018-01-10 11:29:36 +02:00
class Foo8 {
XXX * m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
XXX * m_pbar2 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo8 ( )
{
delete m_pbar1 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
delete m_pbar2 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
} ;
2018-01-10 16:23:41 +02:00
class Foo9 {
XXX * m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
XXX * m_pbar2 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
XXX * m_pbar3 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2018-01-17 13:14:21 +02:00
XXX * m_pbar4 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2018-01-10 16:23:41 +02:00
~ Foo9 ( )
{
if ( m_pbar1 )
{
delete m_pbar1 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
if ( m_pbar2 ! = nullptr )
{
delete m_pbar2 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
if ( m_pbar3 ! = nullptr )
delete m_pbar3 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-01-17 13:14:21 +02:00
if ( m_pbar4 ! = nullptr )
{
int x = 1 ;
( void ) x ;
delete m_pbar4 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
2018-01-10 16:23:41 +02:00
}
} ;
2018-01-12 08:22:39 +02:00
// no warning expected
class Foo10 {
XXX * m_pbar1 ;
~ Foo10 ( )
{
if ( m_pbar1 ! = getOther ( ) )
{
delete m_pbar1 ;
}
}
XXX * getOther ( ) { return nullptr ; }
} ;
2018-01-15 14:56:29 +02:00
class Foo11 {
std : : vector < XXX * > m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo11 ( )
{
2018-11-08 13:32:22 +02:00
for ( const auto & p : m_pbar1 ) // expected-note {{var is here [loplugin:useuniqueptr]}}
2018-01-15 14:56:29 +02:00
{
2018-11-08 13:32:22 +02:00
delete p ; // expected-error {{rather manage this with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}} expected-error {{call to delete on a var, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-01-15 14:56:29 +02:00
}
}
} ;
2018-01-17 13:14:21 +02:00
class Foo12 {
std : : array < int * , 10 > m_pbar ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo12 ( )
{
int i = 0 ;
while ( i < 10 )
2019-01-17 16:48:23 +02:00
delete m_pbar [ i + + ] ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2018-01-17 13:14:21 +02:00
}
} ;
2018-04-24 14:04:53 +02:00
# define DELETEZ( p ) ( delete p,p = NULL )
class Foo13 {
int * m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
int * m_pbar2 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2018-07-23 12:21:25 +02:00
int * m_pbar3 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
2018-04-24 14:04:53 +02:00
~ Foo13 ( )
{
if ( m_pbar1 )
DELETEZ ( m_pbar1 ) ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
DELETEZ ( m_pbar2 ) ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-07-23 12:21:25 +02:00
if ( m_pbar3 )
{
DELETEZ ( m_pbar3 ) ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
2018-04-24 14:04:53 +02:00
}
} ;
2018-08-16 13:46:39 +02:00
2018-05-02 14:46:26 +02:00
// check for unconditional inner compound statements
class Foo14 {
int * m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo14 ( )
{
{
delete m_pbar1 ; // expected-error {{unconditional call to delete on a member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
}
}
} ;
2018-08-16 13:46:39 +02:00
2018-06-21 15:32:52 +02:00
void Foo15 ( int * p )
{
2020-07-06 03:39:12 +02:00
delete p ; // expected-error {{calling delete on a pointer param, should be either allowlisted or simplified [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
} ;
class Foo16 {
Foo16 ( int * p )
{
2020-07-06 03:39:12 +02:00
delete p ; // expected-error {{calling delete on a pointer param, should be either allowlisted or simplified [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
} ;
void foo ( int * p )
{
2020-07-06 03:39:12 +02:00
delete p ; // expected-error {{calling delete on a pointer param, should be either allowlisted or simplified [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
} ;
} ;
// check for delete on array members
class Foo17 {
int * m_pbar1 [ 6 ] ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo17 ( )
{
2018-09-17 10:56:28 +02:00
delete m_pbar1 [ 0 ] ; // expected-error {{unconditional call to delete on an array member, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
}
} ;
// this only starts to work somewhere after clang 3.8 and before clang7
class Foo18 {
std : : vector < char * > m_pbar1 ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo18 ( )
{
for ( auto aIter = m_pbar1 . begin ( ) ; aIter ! = m_pbar1 . end ( ) ; + + aIter )
2019-01-17 16:48:23 +02:00
delete * aIter ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2018-08-16 13:46:39 +02:00
}
2018-06-21 15:32:52 +02:00
} ;
2018-08-17 14:40:29 +02:00
2018-09-17 10:56:28 +02:00
void foo19 ( )
{
std : : vector < char * > vec ; // expected-note {{var is here [loplugin:useuniqueptr]}}
2018-12-09 10:12:13 +01:00
for ( char * p : vec ) // expected-note {{var is here [loplugin:useuniqueptr]}}
delete p ; // expected-error {{rather manage this var with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}} expected-error {{call to delete on a var, should be using std::unique_ptr [loplugin:useuniqueptr]}}
2018-09-17 10:56:28 +02:00
}
// no warning expected
namespace foo20
{
struct struct20_1 { } ;
struct struct20_2 : public struct20_1 {
char * p ;
} ;
void foo20 ( struct20_1 * pMapping )
{
delete static_cast < struct20_2 * > ( pMapping ) - > p ;
}
} ;
2018-10-05 09:49:57 +02:00
// ------------------------------------------------------------------------------------------------
// tests for deleting when looping via iterators
// ------------------------------------------------------------------------------------------------
void foo21 ( )
{
std : : vector < bool * > vec ; // expected-note {{var is here [loplugin:useuniqueptr]}}
for ( auto it = vec . begin ( ) ; it ! = vec . end ( ) ; + + it )
delete * it ; // expected-error {{rather manage this var with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
}
void foo22 ( )
{
std : : unordered_map < int , float * > map ; // expected-note {{var is here [loplugin:useuniqueptr]}}
for ( auto it = map . begin ( ) ; it ! = map . end ( ) ; + + it )
delete it - > second ; // expected-error {{rather manage this var with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
}
class Foo23
{
std : : unordered_map < int , float * > map ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo23 ( )
{
for ( auto it = map . begin ( ) ; it ! = map . end ( ) ; + + it )
2019-01-17 16:48:23 +02:00
delete it - > second ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2018-10-05 09:49:57 +02:00
}
} ;
class Foo24
{
typedef std : : vector < int * > HTMLAttrs ;
HTMLAttrs m_aSetAttrTab ; // expected-note {{member is here [loplugin:useuniqueptr]}}
~ Foo24 ( )
{
for ( HTMLAttrs : : const_iterator it = m_aSetAttrTab . begin ( ) ; it ! = m_aSetAttrTab . end ( ) ; + + it )
2019-01-17 16:48:23 +02:00
delete * it ; // expected-error {{rather manage this member with std::some_container<std::unique_ptr<T>> [loplugin:useuniqueptr]}}
2018-10-05 09:49:57 +02:00
}
} ;
2018-08-17 14:40:29 +02:00
// ------------------------------------------------------------------------------------------------
// tests for passing owning pointers to constructors
2018-10-05 09:49:57 +02:00
// ------------------------------------------------------------------------------------------------
2018-08-17 14:40:29 +02:00
class Bravo1
{
std : : unique_ptr < int > m_field1 ;
Bravo1 ( int * p )
: m_field1 ( p ) // expected-error {{should be passing via std::unique_ptr param [loplugin:useuniqueptr]}}
{ }
} ;
class Bravo2
{
std : : unique_ptr < int > m_field1 ;
Bravo2 ( std : : unique_ptr < int > p )
: m_field1 ( std : : move ( p ) ) // no warning expected
{ }
} ;
2018-10-05 09:49:57 +02:00
2017-05-22 13:25:58 +02:00
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */