1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* -*- 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 <sal/types.h>

#define VOID void

class Class1
{
    SAL_CALL Class1() {} // expected-error {{SAL_CALL unnecessary here [loplugin:salcall]}}
    SAL_CALL ~Class1() {} // expected-error {{SAL_CALL unnecessary here [loplugin:salcall]}}
    SAL_CALL operator int() // expected-error {{SAL_CALL unnecessary here [loplugin:salcall]}}
    {
        return 0;
    }

    void SAL_CALL method1(); // expected-error {{SAL_CALL unnecessary here [loplugin:salcall]}}<--- Unused private function: 'Class1::method1'
    VOID method2() {}<--- Unused private function: 'Class1::method2'<--- The function 'method2' is never used.
    // no SAL_CALL for above method2, even though "SAL_CALL" appears between definition of VOID and
    // the declaration's name, "method2"
};
void SAL_CALL Class1::method1()
{ // expected-error@-1 {{SAL_CALL unnecessary here [loplugin:salcall]}}
}

class Class2
{
    void method1(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}<--- Unused private function: 'Class2::method1'
};
void SAL_CALL Class2::method1() {} // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}

// comment this out because it seems to generate a warning in some internal buffer of clang that I can't annotate
#if 0
// no warning, this appears to be legal
class Class3
{
    void SAL_CALL method1(); // expected-error {{SAL_CALL unnecessary here [loplugin:salcall]}}
};
void Class3::method1() {}
#endif

// no warning, normal case for reference
class Class4
{
    void method1();<--- Unused private function: 'Class4::method1'
};
void Class4::method1() {}

class Class5_1
{
    virtual void method1(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}
    virtual ~Class5_1();
};
class Class5_2
{
    virtual void SAL_CALL method1();
    virtual ~Class5_2();
};
class Class5_3 : public Class5_1, public Class5_2
{
    virtual void SAL_CALL
    method1() override; // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}
    virtual ~Class5_3();
};

class Class6_1
{
    virtual void SAL_CALL method1();
    virtual ~Class6_1();
};
class Class6_2
{
    virtual void SAL_CALL method1();
    virtual ~Class6_2();
};
class Class6_3 : public Class6_1, public Class6_2
{
    virtual void SAL_CALL method1() override;
    virtual ~Class6_3();
};

class Class7_1
{
    virtual void method1();
    virtual ~Class7_1();
};
class Class7_2
{
    virtual void method1();
    virtual ~Class7_2();
};
class Class7_3 : public Class7_1, public Class7_2
{
    virtual void method1() override;
    virtual ~Class7_3();
};

class Class8_1
{
    virtual void method2();
    virtual ~Class8_1();
};
class Class8_2
{
    virtual void SAL_CALL method2(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}
    virtual ~Class8_2();
};
class Class8_3 : public Class8_1, public Class8_2
{
    virtual void method2() override; // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}
    virtual ~Class8_3();
};

#define M1(m) VOID m
class Class9
{
    Class9(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}
    M1(method1)(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}<--- Unused private function: 'Class9::method1'
    void method2(); // expected-note {{SAL_CALL inconsistency [loplugin:salcall]}}<--- Unused private function: 'Class9::method2'
};
#define MC(num)                                                                                    \
    Class##num::Class##num() {}
SAL_CALL MC(9) // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}
    ; // to appease clang-format
void SAL_CALL Class9::method1() // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}
{
}
#define M2(T) T SAL_CALL
M2(void) Class9::method2() {} // expected-error {{SAL_CALL inconsistency [loplugin:salcall]}}

#if 0 // see TODO in SalCall::isSalCallFunction
class Class10
{
    void method1();
};
#define M3(T, SAL_CALL) T SAL_CALL::
M3(void, Class10) method1() {} // false "SAL_CALL inconsistency"
#endif

#if 0 //TODO
template<typename> struct S {
    virtual ~S();
    virtual void f();
};
template<typename T> S<T>::~S() {}
template<typename T> void S<T>::f() {}
struct S2: S<int> {
    ~S2();
    void f() {}
};
int main() {
    S2 s2;
    s2->f();
}
#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */