[clang-tools-extra] r344757 - [clang-tidy] Non-private member variables in classes (MISRA, CppCoreGuidelines, HICPP)

Roman Lebedev via cfe-commits cfe-commits at lists.llvm.org
Thu Oct 18 13:16:45 PDT 2018


Author: lebedevri
Date: Thu Oct 18 13:16:44 2018
New Revision: 344757

URL: http://llvm.org/viewvc/llvm-project?rev=344757&view=rev
Log:
[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

Added:
    clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
    clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
    clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
    clang-tools-extra/trunk/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
Modified:
    clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
    clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
    clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
    clang-tools-extra/trunk/docs/ReleaseNotes.rst
    clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst

Modified: clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp?rev=344757&r1=344756&r2=344757&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/cppcoreguidelines/CppCoreGuidelinesTidyModule.cpp Thu Oct 18 13:16:44 2018
@@ -10,6 +10,7 @@
 #include "../ClangTidy.h"
 #include "../ClangTidyModule.h"
 #include "../ClangTidyModuleRegistry.h"
+#include "../misc/NonPrivateMemberVariablesInClassesCheck.h"
 #include "../misc/UnconventionalAssignOperatorCheck.h"
 #include "../readability/MagicNumbersCheck.h"
 #include "AvoidGotoCheck.h"
@@ -47,6 +48,8 @@ public:
     CheckFactories.registerCheck<NarrowingConversionsCheck>(
         "cppcoreguidelines-narrowing-conversions");
     CheckFactories.registerCheck<NoMallocCheck>("cppcoreguidelines-no-malloc");
+    CheckFactories.registerCheck<misc::NonPrivateMemberVariablesInClassesCheck>(
+        "cppcoreguidelines-non-private-member-variables-in-classes");
     CheckFactories.registerCheck<OwningMemoryCheck>(
         "cppcoreguidelines-owning-memory");
     CheckFactories.registerCheck<ProBoundsArrayToPointerDecayCheck>(
@@ -75,6 +78,16 @@ public:
     CheckFactories.registerCheck<misc::UnconventionalAssignOperatorCheck>(
         "cppcoreguidelines-c-copy-assignment-signature");
   }
+
+  ClangTidyOptions getModuleOptions() override {
+    ClangTidyOptions Options;
+    ClangTidyOptions::OptionMap &Opts = Options.CheckOptions;
+
+    Opts["cppcoreguidelines-non-private-member-variables-in-classes."
+         "IgnoreClassesWithAllMemberVariablesBeingPublic"] = "1";
+
+    return Options;
+  }
 };
 
 // Register the LLVMTidyModule using this statically initialized variable.

Modified: clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt?rev=344757&r1=344756&r2=344757&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/CMakeLists.txt Thu Oct 18 13:16:44 2018
@@ -6,6 +6,7 @@ add_clang_library(clangTidyMiscModule
   MisplacedConstCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NonCopyableObjects.cpp
+  NonPrivateMemberVariablesInClassesCheck.cpp
   RedundantExpressionCheck.cpp
   StaticAssertCheck.cpp
   ThrowByValueCatchByReferenceCheck.cpp

Modified: clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp?rev=344757&r1=344756&r2=344757&view=diff
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp (original)
+++ clang-tools-extra/trunk/clang-tidy/misc/MiscTidyModule.cpp Thu Oct 18 13:16:44 2018
@@ -14,6 +14,7 @@
 #include "MisplacedConstCheck.h"
 #include "NewDeleteOverloadsCheck.h"
 #include "NonCopyableObjects.h"
+#include "NonPrivateMemberVariablesInClassesCheck.h"
 #include "RedundantExpressionCheck.h"
 #include "StaticAssertCheck.h"
 #include "ThrowByValueCatchByReferenceCheck.h"
@@ -37,6 +38,8 @@ public:
         "misc-new-delete-overloads");
     CheckFactories.registerCheck<NonCopyableObjectsCheck>(
         "misc-non-copyable-objects");
+    CheckFactories.registerCheck<NonPrivateMemberVariablesInClassesCheck>(
+        "misc-non-private-member-variables-in-classes");
     CheckFactories.registerCheck<RedundantExpressionCheck>(
         "misc-redundant-expression");
     CheckFactories.registerCheck<StaticAssertCheck>("misc-static-assert");

Added: clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp?rev=344757&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.cpp Thu Oct 18 13:16:44 2018
@@ -0,0 +1,93 @@
+//===--- NonPrivateMemberVariablesInClassesCheck.cpp - clang-tidy ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "NonPrivateMemberVariablesInClassesCheck.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+namespace {
+
+AST_MATCHER(CXXRecordDecl, hasMethods) {
+  return std::distance(Node.method_begin(), Node.method_end()) != 0;
+}
+
+AST_MATCHER(CXXRecordDecl, hasNonStaticMethod) {
+  return hasMethod(unless(isStaticStorageClass()))
+      .matches(Node, Finder, Builder);
+}
+
+AST_MATCHER(CXXRecordDecl, hasNonPublicMemberVariable) {
+  return cxxRecordDecl(has(fieldDecl(unless(isPublic()))))
+      .matches(Node, Finder, Builder);
+}
+
+AST_POLYMORPHIC_MATCHER_P(boolean, AST_POLYMORPHIC_SUPPORTED_TYPES(Stmt, Decl),
+                          bool, Boolean) {
+  return Boolean;
+}
+
+} // namespace
+
+NonPrivateMemberVariablesInClassesCheck::
+    NonPrivateMemberVariablesInClassesCheck(StringRef Name,
+                                            ClangTidyContext *Context)
+    : ClangTidyCheck(Name, Context),
+      IgnoreClassesWithAllMemberVariablesBeingPublic(
+          Options.get("IgnoreClassesWithAllMemberVariablesBeingPublic", false)),
+      IgnorePublicMemberVariables(
+          Options.get("IgnorePublicMemberVariables", false)) {}
+
+void NonPrivateMemberVariablesInClassesCheck::registerMatchers(
+    MatchFinder *Finder) {
+  if (!getLangOpts().CPlusPlus)
+    return;
+
+  // We can ignore structs/classes with all member variables being public.
+  auto ShouldIgnoreRecord =
+      allOf(boolean(IgnoreClassesWithAllMemberVariablesBeingPublic),
+            unless(hasNonPublicMemberVariable()));
+
+  // We only want the records that not only contain the mutable data (non-static
+  // member variables), but also have some logic (non-static member functions).
+  // We may optionally ignore records where all the member variables are public.
+  auto RecordIsInteresting =
+      allOf(anyOf(isStruct(), isClass()), hasMethods(), hasNonStaticMethod(),
+            unless(ShouldIgnoreRecord));
+
+  // There are three visibility types: public, protected, private.
+  // If we are ok with public fields, then we only want to complain about
+  // protected fields, else we want to complain about all non-private fields.
+  // We can ignore public member variables in structs/classes, in unions.
+  auto InterestingField = fieldDecl(
+      IgnorePublicMemberVariables ? isProtected() : unless(isPrivate()));
+
+  Finder->addMatcher(cxxRecordDecl(RecordIsInteresting,
+                                   forEach(InterestingField.bind("field")))
+                         .bind("record"),
+                     this);
+}
+
+void NonPrivateMemberVariablesInClassesCheck::check(
+    const MatchFinder::MatchResult &Result) {
+  const auto *Field = Result.Nodes.getNodeAs<FieldDecl>("field");
+  assert(Field && "We should have the field we are going to complain about");
+
+  diag(Field->getLocation(), "member variable %0 has %1 visibility")
+      << Field << Field->getAccess();
+}
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang

Added: clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h?rev=344757&view=auto
==============================================================================
--- clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h (added)
+++ clang-tools-extra/trunk/clang-tidy/misc/NonPrivateMemberVariablesInClassesCheck.h Thu Oct 18 13:16:44 2018
@@ -0,0 +1,46 @@
+//===--- NonPrivateMemberVariablesInClassesCheck.h - clang-tidy -*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H
+
+#include "../ClangTidy.h"
+
+namespace clang {
+namespace tidy {
+namespace misc {
+
+/// This checker 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.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/misc-non-private-member-variables-in-classes.html
+class NonPrivateMemberVariablesInClassesCheck : public ClangTidyCheck {
+public:
+  NonPrivateMemberVariablesInClassesCheck(StringRef Name,
+                                          ClangTidyContext *Context);
+  void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+  void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+  const bool IgnoreClassesWithAllMemberVariablesBeingPublic;
+  const bool IgnorePublicMemberVariables;
+};
+
+} // namespace misc
+} // namespace tidy
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_NONPRIVATEMEMBERVARIABLESINCLASSESCHECK_H

Modified: clang-tools-extra/trunk/docs/ReleaseNotes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/ReleaseNotes.rst?rev=344757&r1=344756&r2=344757&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/ReleaseNotes.rst (original)
+++ clang-tools-extra/trunk/docs/ReleaseNotes.rst Thu Oct 18 13:16:44 2018
@@ -103,6 +103,13 @@ Improvements to clang-tidy
   Flags uses of ``absl::StrCat()`` to append to a ``std::string``. Suggests
   ``absl::StrAppend()`` should be used instead.
 
+- New :doc:`misc-non-private-member-variables-in-classes
+  <clang-tidy/checks/misc-non-private-member-variables-in-classes>` check.
+
+  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``.
+
 - New :doc:`modernize-concat-nested-namespaces
   <clang-tidy/checks/modernize-concat-nested-namespaces>` check.
 
@@ -134,6 +141,12 @@ Improvements to clang-tidy
   <clang-tidy/checks/readability-uppercase-literal-suffix>`
   added.
 
+- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes
+  <clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes>`
+  to :doc:`misc-non-private-member-variables-in-classes
+  <clang-tidy/checks/misc-non-private-member-variables-in-classes>`
+  added.
+
 - New alias :doc:`hicpp-uppercase-literal-suffix
   <clang-tidy/checks/hicpp-uppercase-literal-suffix>` to
   :doc:`readability-uppercase-literal-suffix

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst?rev=344757&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes.rst Thu Oct 18 13:16:44 2018
@@ -0,0 +1,11 @@
+.. title:: clang-tidy - cppcoreguidelines-non-private-member-variables-in-classes
+.. meta::
+   :http-equiv=refresh: 5;URL=misc-non-private-member-variables-in-classes.html
+
+cppcoreguidelines-non-private-member-variables-in-classes
+=========================================================
+
+The cppcoreguidelines-non-private-member-variables-in-classes check is an alias,
+please see
+`misc-non-private-member-variables-in-classes <misc-non-private-member-variables-in-classes.html>`_
+for more information.

Modified: clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst?rev=344757&r1=344756&r2=344757&view=diff
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst (original)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/list.rst Thu Oct 18 13:16:44 2018
@@ -91,6 +91,7 @@ Clang-Tidy Checks
    cppcoreguidelines-interfaces-global-init
    cppcoreguidelines-narrowing-conversions
    cppcoreguidelines-no-malloc
+   cppcoreguidelines-non-private-member-variables-in-classes (redirects to misc-non-private-member-variables-in-classes) <cppcoreguidelines-non-private-member-variables-in-classes>
    cppcoreguidelines-owning-memory
    cppcoreguidelines-pro-bounds-array-to-pointer-decay
    cppcoreguidelines-pro-bounds-constant-array-index
@@ -165,6 +166,7 @@ Clang-Tidy Checks
    misc-misplaced-const
    misc-new-delete-overloads
    misc-non-copyable-objects
+   misc-non-private-member-variables-in-classes
    misc-redundant-expression
    misc-static-assert
    misc-throw-by-value-catch-by-reference

Added: clang-tools-extra/trunk/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst?rev=344757&view=auto
==============================================================================
--- clang-tools-extra/trunk/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst (added)
+++ clang-tools-extra/trunk/docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst Thu Oct 18 13:16:44 2018
@@ -0,0 +1,26 @@
+.. title:: clang-tidy - misc-non-private-member-variables-in-classes
+
+misc-non-private-member-variables-in-classes
+============================================
+
+`cppcoreguidelines-non-private-member-variables-in-classes` redirects here
+as an alias for this check.
+
+Finds classes that contain non-static data members in addition to non-static
+member functions and diagnose all data members declared with a non-``public``
+access specifier. The data members should be declared as ``private`` and
+accessed through member functions instead of exposed to derived classes or
+class consumers.
+
+Options
+-------
+
+.. option:: IgnoreClassesWithAllMemberVariablesBeingPublic
+
+   Allows to completely ignore classes if **all** the member variables in that
+   class a declared with a ``public`` access specifier.
+
+.. option:: IgnorePublicMemberVariables
+
+   Allows to ignore (not diagnose) **all** the member variables declared with
+   a ``public`` access specifier.

Added: clang-tools-extra/trunk/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp
URL: http://llvm.org/viewvc/llvm-project/clang-tools-extra/trunk/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp?rev=344757&view=auto
==============================================================================
--- clang-tools-extra/trunk/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp (added)
+++ clang-tools-extra/trunk/test/clang-tidy/misc-non-private-member-variables-in-classes.cpp Thu Oct 18 13:16:44 2018
@@ -0,0 +1,380 @@
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,NONPRIVATE,PROTECTED %s misc-non-private-member-variables-in-classes %t
+// 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}]}' --
+// 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}]}' --
+// RUN: %check_clang_tidy -check-suffixes=PUBLIC,PROTECTED %s cppcoreguidelines-non-private-member-variables-in-classes %t -- --
+// 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}]}' --
+// 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}]}' --
+
+//----------------------------------------------------------------------------//
+
+// Only data, do not warn
+
+struct S0 {
+  int S0_v0;
+
+public:
+  int S0_v1;
+
+protected:
+  int S0_v2;
+
+private:
+  int S0_v3;
+};
+
+class S1 {
+  int S1_v0;
+
+public:
+  int S1_v1;
+
+protected:
+  int S1_v2;
+
+private:
+  int S1_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// All functions are static, do not warn.
+
+struct S2 {
+  static void S2_m0();
+  int S2_v0;
+
+public:
+  static void S2_m1();
+  int S2_v1;
+
+protected:
+  static void S2_m3();
+  int S2_v2;
+
+private:
+  static void S2_m4();
+  int S2_v3;
+};
+
+class S3 {
+  static void S3_m0();
+  int S3_v0;
+
+public:
+  static void S3_m1();
+  int S3_v1;
+
+protected:
+  static void S3_m3();
+  int S3_v2;
+
+private:
+  static void S3_m4();
+  int S3_v3;
+};
+
+//============================================================================//
+
+// union != struct/class. do not diagnose.
+
+union U0 {
+  void U0_m0();
+  int U0_v0;
+
+public:
+  void U0_m1();
+  int U0_v1;
+
+protected:
+  void U0_m2();
+  int U0_v2;
+
+private:
+  void U0_m3();
+  int U0_v3;
+};
+
+//============================================================================//
+
+// Has non-static method with default visibility.
+
+struct S4 {
+  void S4_m0();
+
+  int S4_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v0' has public visibility
+public:
+  int S4_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S4_v1' has public visibility
+protected:
+  int S4_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S4_v2' has protected visibility
+private:
+  int S4_v3;
+};
+
+class S5 {
+  void S5_m0();
+
+  int S5_v0;
+
+public:
+  int S5_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S5_v1' has public visibility
+protected:
+  int S5_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S5_v2' has protected visibility
+private:
+  int S5_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with public visibility.
+
+struct S6 {
+  int S6_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v0' has public visibility
+public:
+  void S6_m0();
+  int S6_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S6_v1' has public visibility
+protected:
+  int S6_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S6_v2' has protected visibility
+private:
+  int S6_v3;
+};
+
+class S7 {
+  int S7_v0;
+
+public:
+  void S7_m0();
+  int S7_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S7_v1' has public visibility
+protected:
+  int S7_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S7_v2' has protected visibility
+private:
+  int S7_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with protected visibility.
+
+struct S8 {
+  int S8_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v0' has public visibility
+public:
+  int S8_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S8_v1' has public visibility
+protected:
+  void S8_m0();
+  int S8_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S8_v2' has protected visibility
+private:
+  int S8_v3;
+};
+
+class S9 {
+  int S9_v0;
+
+public:
+  int S9_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S9_v1' has public visibility
+protected:
+  void S9_m0();
+  int S9_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S9_v2' has protected visibility
+private:
+  int S9_v3;
+};
+
+//----------------------------------------------------------------------------//
+
+// Has non-static method with private visibility.
+
+struct S10 {
+  int S10_v0;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v0' has public visibility
+public:
+  int S10_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S10_v1' has public visibility
+protected:
+  int S10_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S10_v2' has protected visibility
+private:
+  void S10_m0();
+  int S10_v3;
+};
+
+class S11 {
+  int S11_v0;
+
+public:
+  int S11_v1;
+  // CHECK-MESSAGES-PUBLIC: :[[@LINE-1]]:7: warning: member variable 'S11_v1' has public visibility
+protected:
+  int S11_v2;
+  // CHECK-MESSAGES-PROTECTED: :[[@LINE-1]]:7: warning: member variable 'S11_v2' has protected visibility
+private:
+  void S11_m0();
+  int S11_v3;
+};
+
+//============================================================================//
+
+// Static variables are ignored.
+// Has non-static methods and static variables.
+
+struct S12 {
+  void S12_m0();
+  static int S12_v0;
+
+public:
+  void S12_m1();
+  static int S12_v1;
+
+protected:
+  void S12_m2();
+  static int S12_v2;
+
+private:
+  void S12_m3();
+  static int S12_v3;
+};
+
+class S13 {
+  void S13_m0();
+  static int S13_v0;
+
+public:
+  void S13_m1();
+  static int S13_v1;
+
+protected:
+  void S13_m2();
+  static int S13_v2;
+
+private:
+  void S13_m3();
+  static int S13_v3;
+};
+
+struct S14 {
+  void S14_m0();
+  int S14_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v0' has public visibility
+
+public:
+  void S14_m1();
+  int S14_v1;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S14_v1' has public visibility
+
+protected:
+  void S14_m2();
+
+private:
+  void S14_m3();
+};
+
+class S15 {
+  void S15_m0();
+
+public:
+  void S15_m1();
+  int S15_v1;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S15_v1' has public visibility
+
+protected:
+  void S15_m2();
+
+private:
+  void S15_m3();
+};
+
+//----------------------------------------------------------------------------//
+
+template <typename T>
+struct S97 {
+  void method();
+  T S97_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:5: warning: member variable 'S97_v0' has public visibility
+};
+
+template struct S97<char *>;
+
+template <>
+struct S97<double> {
+  void method();
+  double S97d_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:10: warning: member variable 'S97d_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+#define FIELD(x) int x;
+
+// Do diagnose fields originating from macros.
+struct S98 {
+  void method();
+  FIELD(S98_v0);
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:9: warning: member variable 'S98_v0' has public visibility
+};
+
+//----------------------------------------------------------------------------//
+
+// Don't look in descendant classes.
+class S99 {
+  void method();
+
+  struct S99_0 {
+    int S99_S0_v0;
+  };
+
+public:
+  struct S99_1 {
+    int S99_S0_v0;
+  };
+
+protected:
+  struct S99_2 {
+    int S99_S0_v0;
+  };
+
+private:
+  struct S99_3 {
+    int S99_S0_v0;
+  };
+};
+
+//----------------------------------------------------------------------------//
+
+// Only diagnose once, don't let the inheritance fool you.
+struct S100 {
+  int S100_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S100_v0' has public visibility
+  void m0();
+};
+struct S101_default_inheritance : S100 {
+  int S101_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S101_v0' has public visibility
+  void m1();
+};
+struct S102_public_inheritance : public S100 {
+  int S102_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S102_v0' has public visibility
+  void m1();
+};
+struct S103_protected_inheritance : protected S100 {
+  int S103_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S103_v0' has public visibility
+  void m1();
+};
+struct S104_private_inheritance : private S100 {
+  int S104_v0;
+  // CHECK-MESSAGES-NONPRIVATE: :[[@LINE-1]]:7: warning: member variable 'S104_v0' has public visibility
+  void m1();
+};




More information about the cfe-commits mailing list