Skip to content

Commit 6cfa38f

Browse files
committedOct 18, 2018
[clang-tidy] Non-private member variables in classes (MISRA, CppCoreGuidelines, HICPP)
Summary: Finds classes that not only contain the data (non-static member variables), but also have logic (non-static member functions), and diagnoses all member variables that have any other scope other than `private`. They should be made `private`, and manipulated exclusively via the member functions. Optionally, classes with all member variables being `public` could be ignored, and optionally all `public` member variables could be ignored. Options ------- * IgnoreClassesWithAllMemberVariablesBeingPublic Allows to completely ignore classes if **all** the member variables in that class have `public` visibility. * IgnorePublicMemberVariables Allows to ignore (not diagnose) **all** the member variables with `public` visibility scope. References: * MISRA 11-0-1 Member data in non-POD class types shall be private. * https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#c2-use-class-if-the-class-has-an-invariant-use-struct-if-the-data-members-can-vary-independently * https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rc-private * https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rh-protected Reviewers: JonasToth, aaron.ballman, alexfh, hokein, xazax.hun Reviewed By: aaron.ballman Subscribers: Eugene.Zelenko, zinovy.nis, cfe-commits, rnkovacs, nemanjai, mgorny, xazax.hun, kbarton Tags: #clang-tools-extra Differential Revision: https://reviews.llvm.org/D52771 llvm-svn: 344757
1 parent a9b271b commit 6cfa38f

10 files changed

+588
-0
lines changed
 

Diff for: ‎clang-tools-extra/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "../ClangTidy.h"
1111
#include "../ClangTidyModule.h"
1212
#include "../ClangTidyModuleRegistry.h"
13+
#include "../misc/NonPrivateMemberVariablesInClassesCheck.h"
1314
#include "../misc/UnconventionalAssignOperatorCheck.h"
1415
#include "../readability/MagicNumbersCheck.h"
1516
#include "AvoidGotoCheck.h"
@@ -47,6 +48,8 @@ class CppCoreGuidelinesModule : public ClangTidyModule {
4748
CheckFactories.registerCheck<NarrowingConversionsCheck>(
4849
"cppcoreguidelines-narrowing-conversions");
4950
CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc");
51+
CheckFactories.registerCheck<misc::NonPrivateMemberVariablesInClassesCheck>(
52+
"cppcoreguidelines-non-private-member-variables-in-classes");
5053
CheckFactories.registerCheck<OwningMemoryCheck>(
5154
"cppcoreguidelines-owning-memory");
5255
CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>(
@@ -75,6 +78,16 @@ class CppCoreGuidelinesModule : public ClangTidyModule {
7578
CheckFactories.registerCheck<misc::UnconventionalAssignOperatorCheck>(
7679
"cppcoreguidelines-c-copy-assignment-signature");
7780
}
81+
82+
ClangTidyOptions getModuleOptions() override {
83+
ClangTidyOptions Options;
84+
ClangTidyOptions::OptionMap &Opts = Options.CheckOptions;
85+
86+
Opts["cppcoreguidelines-non-private-member-variables-in-classes."
87+
"IgnoreClassesWithAllMemberVariablesBeingPublic"] = "1";
88+
89+
return Options;
90+
}
7891
};
7992

8093
// Register the LLVMTidyModule using this statically initialized variable.

Diff for: ‎clang-tools-extra/clang-tidy/misc/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ add_clang_library(clangTidyMiscModule
66
MisplacedConstCheck.cpp
77
NewDeleteOverloadsCheck.cpp
88
NonCopyableObjects.cpp
9+
NonPrivateMemberVariablesInClassesCheck.cpp
910
RedundantExpressionCheck.cpp
1011
StaticAssertCheck.cpp
1112
ThrowByValueCatchByReferenceCheck.cpp

Diff for: ‎clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "MisplacedConstCheck.h"
1515
#include "NewDeleteOverloadsCheck.h"
1616
#include "NonCopyableObjects.h"
17+
#include "NonPrivateMemberVariablesInClassesCheck.h"
1718
#include "RedundantExpressionCheck.h"
1819
#include "StaticAssertCheck.h"
1920
#include "ThrowByValueCatchByReferenceCheck.h"
@@ -37,6 +38,8 @@ class MiscModule : public ClangTidyModule {
3738
"misc-new-delete-overloads");
3839
CheckFactories.registerCheck<NonCopyableObjectsCheck>(
3940
"misc-non-copyable-objects");
41+
CheckFactories.registerCheck<NonPrivateMemberVariablesInClassesCheck>(
42+
"misc-non-private-member-variables-in-classes");
4043
CheckFactories.registerCheck<RedundantExpressionCheck>(
4144
"misc-redundant-expression");
4245
CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
//===--- NonPrivateMemberVariablesInClassesCheck.cpp - clang-tidy ---------===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#include "NonPrivateMemberVariablesInClassesCheck.h"
11+
#include "clang/AST/ASTContext.h"
12+
#include "clang/ASTMatchers/ASTMatchFinder.h"
13+
14+
using namespace clang::ast_matchers;
15+
16+
namespace clang {
17+
namespace tidy {
18+
namespace misc {
19+
20+
namespace {
21+
22+
AST_MATCHER(CXXRecordDecl, hasMethods) {
23+
return std::distance(Node.method_begin(), Node.method_end()) != 0;
24+
}
25+
26+
AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) {
27+
return hasMethod(unless(isStaticStorageClass()))
28+
.matches(Node, Finder, Builder);
29+
}
30+
31+
AST_MATCHER(CXXRecordDecl, hasNonPublicMemberVariable) {
32+
return cxxRecordDecl(has(fieldDecl(unless(isPublic()))))
33+
.matches(Node, Finder, Builder);
34+
}
35+
36+
AST_POLYMORPHIC_MATCHER_P(boolean, AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl),
37+
bool, Boolean) {
38+
return Boolean;
39+
}
40+
41+
} // namespace
42+
43+
NonPrivateMemberVariablesInClassesCheck::
44+
NonPrivateMemberVariablesInClassesCheck(StringRef Name,
45+
ClangTidyContext *Context)
46+
: ClangTidyCheck(Name, Context),
47+
IgnoreClassesWithAllMemberVariablesBeingPublic(
48+
Options.get("IgnoreClassesWithAllMemberVariablesBeingPublic", false)),
49+
IgnorePublicMemberVariables(
50+
Options.get("IgnorePublicMemberVariables", false)) {}
51+
52+
void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
53+
MatchFinder *Finder) {
54+
if (!getLangOpts().CPlusPlus)
55+
return;
56+
57+
// We can ignore structs/classes with all member variables being public.
58+
auto ShouldIgnoreRecord =
59+
allOf(boolean(IgnoreClassesWithAllMemberVariablesBeingPublic),
60+
unless(hasNonPublicMemberVariable()));
61+
62+
// We only want the records that not only contain the mutable data (non-static
63+
// member variables), but also have some logic (non-static member functions).
64+
// We may optionally ignore records where all the member variables are public.
65+
auto RecordIsInteresting =
66+
allOf(anyOf(isStruct(), isClass()), hasMethods(), hasNonStaticMethod(),
67+
unless(ShouldIgnoreRecord));
68+
69+
// There are three visibility types: public, protected, private.
70+
// If we are ok with public fields, then we only want to complain about
71+
// protected fields, else we want to complain about all non-private fields.
72+
// We can ignore public member variables in structs/classes, in unions.
73+
auto InterestingField = fieldDecl(
74+
IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
75+
76+
Finder->addMatcher(cxxRecordDecl(RecordIsInteresting,
77+
forEach(InterestingField.bind("field")))
78+
.bind("record"),
79+
this);
80+
}
81+
82+
void NonPrivateMemberVariablesInClassesCheck::check(
83+
const MatchFinder::MatchResult &Result) {
84+
const auto *Field = Result.Nodes.getNodeAs<FieldDecl>("field");
85+
assert(Field && "We should have the field we are going to complain about");
86+
87+
diag(Field->getLocation(), "member variable %0 has %1 visibility")
88+
<< Field << Field->getAccess();
89+
}
90+
91+
} // namespace misc
92+
} // namespace tidy
93+
} // namespace clang
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//===--- NonPrivateMemberVariablesInClassesCheck.h - clang-tidy -*- C++ -*-===//
2+
//
3+
// The LLVM Compiler Infrastructure
4+
//
5+
// This file is distributed under the University of Illinois Open Source
6+
// License. See LICENSE.TXT for details.
7+
//
8+
//===----------------------------------------------------------------------===//
9+
10+
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
11+
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
12+
13+
#include "../ClangTidy.h"
14+
15+
namespace clang {
16+
namespace tidy {
17+
namespace misc {
18+
19+
/// This checker finds classes that not only contain the data
20+
/// (non-static member variables), but also have logic (non-static member
21+
/// functions), and diagnoses all member variables that have any other scope
22+
/// other than `private`. They should be made `private`, and manipulated
23+
/// exclusively via the member functions.
24+
///
25+
/// Optionally, classes with all member variables being `public` could be
26+
/// ignored and optionally all `public` member variables could be ignored.
27+
///
28+
/// For the user-facing documentation see:
29+
/// http://clang.llvm.org/extra/clang-tidy/checks/misc-non-private-member-variables-in-classes.html
30+
class NonPrivateMemberVariablesInClassesCheck : public ClangTidyCheck {
31+
public:
32+
NonPrivateMemberVariablesInClassesCheck(StringRef Name,
33+
ClangTidyContext *Context);
34+
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
35+
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
36+
37+
private:
38+
const bool IgnoreClassesWithAllMemberVariablesBeingPublic;
39+
const bool IgnorePublicMemberVariables;
40+
};
41+
42+
} // namespace misc
43+
} // namespace tidy
44+
} // namespace clang
45+
46+
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H

Diff for: ‎clang-tools-extra/docs/ReleaseNotes.rst

+13
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ Improvements to clang-tidy
103103
Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
104104
``absl::StrAppend()`` should be used instead.
105105

106+
- New :doc:`misc-non-private-member-variables-in-classes
107+
<clang-tidy/checks/misc-non-private-member-variables-in-classes>` check.
108+
109+
Finds classes that not only contain the data (non-static member variables),
110+
but also have logic (non-static member functions), and diagnoses all member
111+
variables that have any other scope other than ``private``.
112+
106113
- New :doc:`modernize-concat-nested-namespaces
107114
<clang-tidy/checks/modernize-concat-nested-namespaces>` check.
108115

@@ -134,6 +141,12 @@ Improvements to clang-tidy
134141
<clang-tidy/checks/readability-uppercase-literal-suffix>`
135142
added.
136143

144+
- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes
145+
<clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes>`
146+
to :doc:`misc-non-private-member-variables-in-classes
147+
<clang-tidy/checks/misc-non-private-member-variables-in-classes>`
148+
added.
149+
137150
- New alias :doc:`hicpp-uppercase-literal-suffix
138151
<clang-tidy/checks/hicpp-uppercase-literal-suffix>` to
139152
:doc:`readability-uppercase-literal-suffix
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
.. title:: clang-tidy - cppcoreguidelines-non-private-member-variables-in-classes
2+
.. meta::
3+
:http-equiv=refresh: 5;URL=misc-non-private-member-variables-in-classes.html
4+
5+
cppcoreguidelines-non-private-member-variables-in-classes
6+
=========================================================
7+
8+
The cppcoreguidelines-non-private-member-variables-in-classes check is an alias,
9+
please see
10+
`misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_
11+
for more information.

Diff for: ‎clang-tools-extra/docs/clang-tidy/checks/list.rst

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ Clang-Tidy Checks
9191
cppcoreguidelines-interfaces-global-init
9292
cppcoreguidelines-narrowing-conversions
9393
cppcoreguidelines-no-malloc
94+
cppcoreguidelines-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) <cppcoreguidelines-non-private-member-variables-in-classes>
9495
cppcoreguidelines-owning-memory
9596
cppcoreguidelines-pro-bounds-array-to-pointer-decay
9697
cppcoreguidelines-pro-bounds-constant-array-index
@@ -165,6 +166,7 @@ Clang-Tidy Checks
165166
misc-misplaced-const
166167
misc-new-delete-overloads
167168
misc-non-copyable-objects
169+
misc-non-private-member-variables-in-classes
168170
misc-redundant-expression
169171
misc-static-assert
170172
misc-throw-by-value-catch-by-reference
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.. title:: clang-tidy - misc-non-private-member-variables-in-classes
2+
3+
misc-non-private-member-variables-in-classes
4+
============================================
5+
6+
`cppcoreguidelines-non-private-member-variables-in-classes` redirects here
7+
as an alias for this check.
8+
9+
Finds classes that contain non-static data members in addition to non-static
10+
member functions and diagnose all data members declared with a non-``public``
11+
access specifier. The data members should be declared as ``private`` and
12+
accessed through member functions instead of exposed to derived classes or
13+
class consumers.
14+
15+
Options
16+
-------
17+
18+
.. option:: IgnoreClassesWithAllMemberVariablesBeingPublic
19+
20+
Allows to completely ignore classes if **all** the member variables in that
21+
class a declared with a ``public`` access specifier.
22+
23+
.. option:: IgnorePublicMemberVariables
24+
25+
Allows to ignore (not diagnose) **all** the member variables declared with
26+
a ``public`` access specifier.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,380 @@
1+
// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t
2+
// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
3+
// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 0}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
4+
// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s cppcoreguidelines-non-private-member-variables-in-classes %t -- --
5+
// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 0}]}' --
6+
// RUN: %check_clang_tidy -check-suffixes=PROTECTED %s misc-non-private-member-variables-in-classes %t -- -config='{CheckOptions: [{key: misc-non-private-member-variables-in-classes.IgnorePublicMemberVariables, value: 1}, {key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic, value: 1}]}' --
7+
8+
//----------------------------------------------------------------------------//
9+
10+
// Only data, do not warn
11+
12+
struct S0 {
13+
int S0_v0;
14+
15+
public:
16+
int S0_v1;
17+
18+
protected:
19+
int S0_v2;
20+
21+
private:
22+
int S0_v3;
23+
};
24+
25+
class S1 {
26+
int S1_v0;
27+
28+
public:
29+
int S1_v1;
30+
31+
protected:
32+
int S1_v2;
33+
34+
private:
35+
int S1_v3;
36+
};
37+
38+
//----------------------------------------------------------------------------//
39+
40+
// All functions are static, do not warn.
41+
42+
struct S2 {
43+
static void S2_m0();
44+
int S2_v0;
45+
46+
public:
47+
static void S2_m1();
48+
int S2_v1;
49+
50+
protected:
51+
static void S2_m3();
52+
int S2_v2;
53+
54+
private:
55+
static void S2_m4();
56+
int S2_v3;
57+
};
58+
59+
class S3 {
60+
static void S3_m0();
61+
int S3_v0;
62+
63+
public:
64+
static void S3_m1();
65+
int S3_v1;
66+
67+
protected:
68+
static void S3_m3();
69+
int S3_v2;
70+
71+
private:
72+
static void S3_m4();
73+
int S3_v3;
74+
};
75+
76+
//============================================================================//
77+
78+
// union != struct/class. do not diagnose.
79+
80+
union U0 {
81+
void U0_m0();
82+
int U0_v0;
83+
84+
public:
85+
void U0_m1();
86+
int U0_v1;
87+
88+
protected:
89+
void U0_m2();
90+
int U0_v2;
91+
92+
private:
93+
void U0_m3();
94+
int U0_v3;
95+
};
96+
97+
//============================================================================//
98+
99+
// Has non-static method with default visibility.
100+
101+
struct S4 {
102+
void S4_m0();
103+
104+
int S4_v0;
105+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v0' has public visibility
106+
public:
107+
int S4_v1;
108+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v1' has public visibility
109+
protected:
110+
int S4_v2;
111+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S4_v2' has protected visibility
112+
private:
113+
int S4_v3;
114+
};
115+
116+
class S5 {
117+
void S5_m0();
118+
119+
int S5_v0;
120+
121+
public:
122+
int S5_v1;
123+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S5_v1' has public visibility
124+
protected:
125+
int S5_v2;
126+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S5_v2' has protected visibility
127+
private:
128+
int S5_v3;
129+
};
130+
131+
//----------------------------------------------------------------------------//
132+
133+
// Has non-static method with public visibility.
134+
135+
struct S6 {
136+
int S6_v0;
137+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v0' has public visibility
138+
public:
139+
void S6_m0();
140+
int S6_v1;
141+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v1' has public visibility
142+
protected:
143+
int S6_v2;
144+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S6_v2' has protected visibility
145+
private:
146+
int S6_v3;
147+
};
148+
149+
class S7 {
150+
int S7_v0;
151+
152+
public:
153+
void S7_m0();
154+
int S7_v1;
155+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S7_v1' has public visibility
156+
protected:
157+
int S7_v2;
158+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S7_v2' has protected visibility
159+
private:
160+
int S7_v3;
161+
};
162+
163+
//----------------------------------------------------------------------------//
164+
165+
// Has non-static method with protected visibility.
166+
167+
struct S8 {
168+
int S8_v0;
169+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v0' has public visibility
170+
public:
171+
int S8_v1;
172+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v1' has public visibility
173+
protected:
174+
void S8_m0();
175+
int S8_v2;
176+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S8_v2' has protected visibility
177+
private:
178+
int S8_v3;
179+
};
180+
181+
class S9 {
182+
int S9_v0;
183+
184+
public:
185+
int S9_v1;
186+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S9_v1' has public visibility
187+
protected:
188+
void S9_m0();
189+
int S9_v2;
190+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S9_v2' has protected visibility
191+
private:
192+
int S9_v3;
193+
};
194+
195+
//----------------------------------------------------------------------------//
196+
197+
// Has non-static method with private visibility.
198+
199+
struct S10 {
200+
int S10_v0;
201+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v0' has public visibility
202+
public:
203+
int S10_v1;
204+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v1' has public visibility
205+
protected:
206+
int S10_v2;
207+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S10_v2' has protected visibility
208+
private:
209+
void S10_m0();
210+
int S10_v3;
211+
};
212+
213+
class S11 {
214+
int S11_v0;
215+
216+
public:
217+
int S11_v1;
218+
// CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S11_v1' has public visibility
219+
protected:
220+
int S11_v2;
221+
// CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S11_v2' has protected visibility
222+
private:
223+
void S11_m0();
224+
int S11_v3;
225+
};
226+
227+
//============================================================================//
228+
229+
// Static variables are ignored.
230+
// Has non-static methods and static variables.
231+
232+
struct S12 {
233+
void S12_m0();
234+
static int S12_v0;
235+
236+
public:
237+
void S12_m1();
238+
static int S12_v1;
239+
240+
protected:
241+
void S12_m2();
242+
static int S12_v2;
243+
244+
private:
245+
void S12_m3();
246+
static int S12_v3;
247+
};
248+
249+
class S13 {
250+
void S13_m0();
251+
static int S13_v0;
252+
253+
public:
254+
void S13_m1();
255+
static int S13_v1;
256+
257+
protected:
258+
void S13_m2();
259+
static int S13_v2;
260+
261+
private:
262+
void S13_m3();
263+
static int S13_v3;
264+
};
265+
266+
struct S14 {
267+
void S14_m0();
268+
int S14_v0;
269+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v0' has public visibility
270+
271+
public:
272+
void S14_m1();
273+
int S14_v1;
274+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v1' has public visibility
275+
276+
protected:
277+
void S14_m2();
278+
279+
private:
280+
void S14_m3();
281+
};
282+
283+
class S15 {
284+
void S15_m0();
285+
286+
public:
287+
void S15_m1();
288+
int S15_v1;
289+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S15_v1' has public visibility
290+
291+
protected:
292+
void S15_m2();
293+
294+
private:
295+
void S15_m3();
296+
};
297+
298+
//----------------------------------------------------------------------------//
299+
300+
template <typename T>
301+
struct S97 {
302+
void method();
303+
T S97_v0;
304+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:5: warning: member variable 'S97_v0' has public visibility
305+
};
306+
307+
template struct S97<char *>;
308+
309+
template <>
310+
struct S97<double> {
311+
void method();
312+
double S97d_v0;
313+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:10: warning: member variable 'S97d_v0' has public visibility
314+
};
315+
316+
//----------------------------------------------------------------------------//
317+
318+
#define FIELD(x) int x;
319+
320+
// Do diagnose fields originating from macros.
321+
struct S98 {
322+
void method();
323+
FIELD(S98_v0);
324+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:9: warning: member variable 'S98_v0' has public visibility
325+
};
326+
327+
//----------------------------------------------------------------------------//
328+
329+
// Don't look in descendant classes.
330+
class S99 {
331+
void method();
332+
333+
struct S99_0 {
334+
int S99_S0_v0;
335+
};
336+
337+
public:
338+
struct S99_1 {
339+
int S99_S0_v0;
340+
};
341+
342+
protected:
343+
struct S99_2 {
344+
int S99_S0_v0;
345+
};
346+
347+
private:
348+
struct S99_3 {
349+
int S99_S0_v0;
350+
};
351+
};
352+
353+
//----------------------------------------------------------------------------//
354+
355+
// Only diagnose once, don't let the inheritance fool you.
356+
struct S100 {
357+
int S100_v0;
358+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S100_v0' has public visibility
359+
void m0();
360+
};
361+
struct S101_default_inheritance : S100 {
362+
int S101_v0;
363+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S101_v0' has public visibility
364+
void m1();
365+
};
366+
struct S102_public_inheritance : public S100 {
367+
int S102_v0;
368+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S102_v0' has public visibility
369+
void m1();
370+
};
371+
struct S103_protected_inheritance : protected S100 {
372+
int S103_v0;
373+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S103_v0' has public visibility
374+
void m1();
375+
};
376+
struct S104_private_inheritance : private S100 {
377+
int S104_v0;
378+
// CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S104_v0' has public visibility
379+
void m1();
380+
};

0 commit comments

Comments
 (0)
Please sign in to comment.