Skip to content

Conversation

@Bhuvan1527
Copy link
Contributor

Resolves: #171136

Referred the issue tagged in the issue mentioned.

@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2025

@llvm/pr-subscribers-clang-tools-extra

Author: Bala_Bhuvan_Varma (Bhuvan1527)

Changes

Resolves: #171136

Referred the issue tagged in the issue mentioned.


Full diff: https://github.com/llvm/llvm-project/pull/171565.diff

7 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt (-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/misc/CMakeLists.txt (+1)
  • (modified) clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp (+3)
  • (renamed) clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp (+2-2)
  • (renamed) clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h (+5-5)
  • (added) clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp (+165)
diff --git a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
index c7234098f094a..b7e278814371e 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
@@ -7,7 +7,6 @@ add_clang_library(clangTidyFuchsiaModule STATIC
   DefaultArgumentsCallsCheck.cpp
   DefaultArgumentsDeclarationsCheck.cpp
   FuchsiaTidyModule.cpp
-  MultipleInheritanceCheck.cpp
   OverloadedOperatorCheck.cpp
   StaticallyConstructedObjectsCheck.cpp
   TemporaryObjectsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
index c62c43f0c42a3..6cbae3253f53c 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
@@ -12,7 +12,7 @@
 #include "../google/UnnamedNamespaceInHeaderCheck.h"
 #include "DefaultArgumentsCallsCheck.h"
 #include "DefaultArgumentsDeclarationsCheck.h"
-#include "MultipleInheritanceCheck.h"
+#include "../misc/MultipleInheritanceCheck.h"
 #include "OverloadedOperatorCheck.h"
 #include "StaticallyConstructedObjectsCheck.h"
 #include "TemporaryObjectsCheck.h"
@@ -34,7 +34,7 @@ class FuchsiaModule : public ClangTidyModule {
         "fuchsia-default-arguments-declarations");
     CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(
         "fuchsia-header-anon-namespaces");
-    CheckFactories.registerCheck<MultipleInheritanceCheck>(
+    CheckFactories.registerCheck<misc::MultipleInheritanceCheck>(
         "fuchsia-multiple-inheritance");
     CheckFactories.registerCheck<OverloadedOperatorCheck>(
         "fuchsia-overloaded-operator");
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index e8705aada3f22..c05930cc27ce0 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangTidyMiscModule STATIC
   MiscTidyModule.cpp
   MisleadingBidirectionalCheck.cpp
   MisleadingIdentifierCheck.cpp
+  MultipleInheritanceCheck.cpp
   MisplacedConstCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NoRecursionCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index 03f25775de0bf..9d48f2005edae 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -17,6 +17,7 @@
 #include "IncludeCleanerCheck.h"
 #include "MisleadingBidirectionalCheck.h"
 #include "MisleadingIdentifierCheck.h"
+#include "MultipleInheritanceCheck.h"
 #include "MisplacedConstCheck.h"
 #include "NewDeleteOverloadsCheck.h"
 #include "NoRecursionCheck.h"
@@ -86,6 +87,8 @@ class MiscModule : public ClangTidyModule {
         "misc-use-anonymous-namespace");
     CheckFactories.registerCheck<UseInternalLinkageCheck>(
         "misc-use-internal-linkage");
+    CheckFactories.registerCheck<MultipleInheritanceCheck>(
+        "misc-multiple-inheritance");
   }
 };
 
diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
similarity index 97%
rename from clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
rename to clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
index 4a10cb4085a41..557b4559697b9 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
@@ -13,7 +13,7 @@
 using namespace clang;
 using namespace clang::ast_matchers;
 
-namespace clang::tidy::fuchsia {
+namespace clang::tidy::misc {
 
 namespace {
 AST_MATCHER(CXXRecordDecl, hasBases) {
@@ -74,4 +74,4 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
                           "pure virtual is discouraged");
 }
 
-} // namespace clang::tidy::fuchsia
+} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
similarity index 82%
rename from clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h
rename to clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
index 4dcbd0c7893c5..5fe1cf7c321c4 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
@@ -6,12 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
 
 #include "../ClangTidyCheck.h"
 
-namespace clang::tidy::fuchsia {
+namespace clang::tidy::misc {
 
 /// Multiple implementation inheritance is discouraged.
 ///
@@ -38,6 +38,6 @@ class MultipleInheritanceCheck : public ClangTidyCheck {
   llvm::DenseMap<const CXXRecordDecl *, bool> InterfaceMap;
 };
 
-} // namespace clang::tidy::fuchsia
+} // namespace clang::tidy::misc
 
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
new file mode 100644
index 0000000000000..6004ab3d812ea
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
@@ -0,0 +1,165 @@
+// RUN: %check_clang_tidy %s misc-multiple-inheritance %t
+
+class Base_A {
+public:
+  virtual int foo() { return 0; }
+};
+
+class Base_B {
+public:
+  virtual int bar() { return 0; }
+};
+
+class Base_A_child : public Base_A {
+public:
+  virtual int baz() { return 0; }
+};
+
+class Interface_A {
+public:
+  virtual int foo() = 0;
+};
+
+class Interface_B {
+public:
+  virtual int bar() = 0;
+};
+
+class Interface_C {
+public:
+  virtual int blat() = 0;
+};
+
+class Interface_A_with_member {
+public:
+  virtual int foo() = 0;
+  int val = 0;
+};
+
+class Interface_with_A_Parent : public Base_A {
+public:
+  virtual int baz() = 0;
+};
+
+// Shouldn't warn on forward declarations.
+class Bad_Child1;
+
+// Inherits from multiple concrete classes.
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {};
+class Bad_Child1 : public Base_A, Base_B {};
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+class Bad_Child2 : public Base_A, Interface_A_with_member {
+  virtual int foo() override { return 0; }
+};
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+  virtual int baz() override { return 0; }
+};
+
+// Easy cases of single inheritance
+class Simple_Child1 : public Base_A {};
+class Simple_Child2 : public Interface_A {
+  virtual int foo() override { return 0; }
+};
+
+// Valid uses of multiple inheritance
+class Good_Child1 : public Interface_A, Interface_B {
+  virtual int foo() override { return 0; }
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child2 : public Base_A, Interface_B {
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child3 : public Base_A_child, Interface_C, Interface_B {
+  virtual int bar() override { return 0; }
+  virtual int blat() override { return 0; }
+};
+
+struct B1 { int x; };
+struct B2 { int x;};
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D : B1, B2 {};
+struct D1 : B1, B2 {};
+
+struct Base1 { virtual void foo() = 0; };
+struct V1 : virtual Base1 {};
+struct V2 : virtual Base1 {};
+struct D2 : V1, V2 {};
+
+struct Base2 { virtual void foo(); };
+struct V3 : virtual Base2 {};
+struct V4 : virtual Base2 {};
+struct D3 : V3, V4 {};
+
+struct Base3 {};
+struct V5 : virtual Base3 { virtual void f(); };
+struct V6 : virtual Base3 { virtual void g(); };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D4 : V5, V6 {};
+struct D4 : V5, V6 {};
+
+struct Base4 {};
+struct V7 : virtual Base4 { virtual void f() = 0; };
+struct V8 : virtual Base4 { virtual void g() = 0; };
+struct D5 : V7, V8 {};
+
+struct Base5 { virtual void f() = 0; };
+struct V9 : virtual Base5 { virtual void f(); };
+struct V10 : virtual Base5 { virtual void g() = 0; };
+struct D6 : V9, V10 {};
+
+struct Base6 { virtual void f(); };
+struct Base7 { virtual void g(); };
+struct V15 : virtual Base6 { virtual void f() = 0; };
+struct V16 : virtual Base7 { virtual void g() = 0; };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D9 : V15, V16 {};
+struct D9 : V15, V16 {};
+
+struct Static_Base { static void foo(); };
+struct V11 : virtual Static_Base {};
+struct V12 : virtual Static_Base {};
+struct D7 : V11, V12 {};
+
+struct Static_Base_2 {};
+struct V13 : virtual Static_Base_2 { static void f(); };
+struct V14 : virtual Static_Base_2 { static void g(); };
+struct D8 : V13, V14 {};
+
+template<typename T> struct A : T {};
+template<typename T> struct B : virtual T {};
+
+template<typename> struct C {};
+template<typename T> struct D : C<T> {};
+
+// Check clang_tidy does not crash on this code.
+template <class T>
+struct WithTemplBase : T {
+  WithTemplBase();
+};
+
+void test_no_crash() {
+  auto foo = []() {};
+  WithTemplBase<decltype(foo)>();
+}
+
+struct S1 {};
+struct S2 {};
+
+struct S3 : S1, S2 {};
+
+namespace N {
+
+struct S1 { int i; };
+struct S2 { int i; };
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+struct S3 : S1, S2 {};
+
+} // namespace N

@llvmbot
Copy link
Member

llvmbot commented Dec 10, 2025

@llvm/pr-subscribers-clang-tidy

Author: Bala_Bhuvan_Varma (Bhuvan1527)

Changes

Resolves: #171136

Referred the issue tagged in the issue mentioned.


Full diff: https://github.com/llvm/llvm-project/pull/171565.diff

7 Files Affected:

  • (modified) clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt (-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/misc/CMakeLists.txt (+1)
  • (modified) clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp (+3)
  • (renamed) clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp (+2-2)
  • (renamed) clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h (+5-5)
  • (added) clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp (+165)
diff --git a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
index c7234098f094a..b7e278814371e 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/fuchsia/CMakeLists.txt
@@ -7,7 +7,6 @@ add_clang_library(clangTidyFuchsiaModule STATIC
   DefaultArgumentsCallsCheck.cpp
   DefaultArgumentsDeclarationsCheck.cpp
   FuchsiaTidyModule.cpp
-  MultipleInheritanceCheck.cpp
   OverloadedOperatorCheck.cpp
   StaticallyConstructedObjectsCheck.cpp
   TemporaryObjectsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
index c62c43f0c42a3..6cbae3253f53c 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/FuchsiaTidyModule.cpp
@@ -12,7 +12,7 @@
 #include "../google/UnnamedNamespaceInHeaderCheck.h"
 #include "DefaultArgumentsCallsCheck.h"
 #include "DefaultArgumentsDeclarationsCheck.h"
-#include "MultipleInheritanceCheck.h"
+#include "../misc/MultipleInheritanceCheck.h"
 #include "OverloadedOperatorCheck.h"
 #include "StaticallyConstructedObjectsCheck.h"
 #include "TemporaryObjectsCheck.h"
@@ -34,7 +34,7 @@ class FuchsiaModule : public ClangTidyModule {
         "fuchsia-default-arguments-declarations");
     CheckFactories.registerCheck<google::build::UnnamedNamespaceInHeaderCheck>(
         "fuchsia-header-anon-namespaces");
-    CheckFactories.registerCheck<MultipleInheritanceCheck>(
+    CheckFactories.registerCheck<misc::MultipleInheritanceCheck>(
         "fuchsia-multiple-inheritance");
     CheckFactories.registerCheck<OverloadedOperatorCheck>(
         "fuchsia-overloaded-operator");
diff --git a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
index e8705aada3f22..c05930cc27ce0 100644
--- a/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/misc/CMakeLists.txt
@@ -27,6 +27,7 @@ add_clang_library(clangTidyMiscModule STATIC
   MiscTidyModule.cpp
   MisleadingBidirectionalCheck.cpp
   MisleadingIdentifierCheck.cpp
+  MultipleInheritanceCheck.cpp
   MisplacedConstCheck.cpp
   NewDeleteOverloadsCheck.cpp
   NoRecursionCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
index 03f25775de0bf..9d48f2005edae 100644
--- a/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MiscTidyModule.cpp
@@ -17,6 +17,7 @@
 #include "IncludeCleanerCheck.h"
 #include "MisleadingBidirectionalCheck.h"
 #include "MisleadingIdentifierCheck.h"
+#include "MultipleInheritanceCheck.h"
 #include "MisplacedConstCheck.h"
 #include "NewDeleteOverloadsCheck.h"
 #include "NoRecursionCheck.h"
@@ -86,6 +87,8 @@ class MiscModule : public ClangTidyModule {
         "misc-use-anonymous-namespace");
     CheckFactories.registerCheck<UseInternalLinkageCheck>(
         "misc-use-internal-linkage");
+    CheckFactories.registerCheck<MultipleInheritanceCheck>(
+        "misc-multiple-inheritance");
   }
 };
 
diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
similarity index 97%
rename from clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
rename to clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
index 4a10cb4085a41..557b4559697b9 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.cpp
@@ -13,7 +13,7 @@
 using namespace clang;
 using namespace clang::ast_matchers;
 
-namespace clang::tidy::fuchsia {
+namespace clang::tidy::misc {
 
 namespace {
 AST_MATCHER(CXXRecordDecl, hasBases) {
@@ -74,4 +74,4 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
                           "pure virtual is discouraged");
 }
 
-} // namespace clang::tidy::fuchsia
+} // namespace clang::tidy::misc
diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
similarity index 82%
rename from clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h
rename to clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
index 4dcbd0c7893c5..5fe1cf7c321c4 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.h
+++ b/clang-tools-extra/clang-tidy/misc/MultipleInheritanceCheck.h
@@ -6,12 +6,12 @@
 //
 //===----------------------------------------------------------------------===//
 
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
 
 #include "../ClangTidyCheck.h"
 
-namespace clang::tidy::fuchsia {
+namespace clang::tidy::misc {
 
 /// Multiple implementation inheritance is discouraged.
 ///
@@ -38,6 +38,6 @@ class MultipleInheritanceCheck : public ClangTidyCheck {
   llvm::DenseMap<const CXXRecordDecl *, bool> InterfaceMap;
 };
 
-} // namespace clang::tidy::fuchsia
+} // namespace clang::tidy::misc
 
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_FUCHSIA_MULTIPLEINHERITANCECHECK_H
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MISC_MULTIPLEINHERITANCECHECK_H
diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
new file mode 100644
index 0000000000000..6004ab3d812ea
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc/multiple-inheritance.cpp
@@ -0,0 +1,165 @@
+// RUN: %check_clang_tidy %s misc-multiple-inheritance %t
+
+class Base_A {
+public:
+  virtual int foo() { return 0; }
+};
+
+class Base_B {
+public:
+  virtual int bar() { return 0; }
+};
+
+class Base_A_child : public Base_A {
+public:
+  virtual int baz() { return 0; }
+};
+
+class Interface_A {
+public:
+  virtual int foo() = 0;
+};
+
+class Interface_B {
+public:
+  virtual int bar() = 0;
+};
+
+class Interface_C {
+public:
+  virtual int blat() = 0;
+};
+
+class Interface_A_with_member {
+public:
+  virtual int foo() = 0;
+  int val = 0;
+};
+
+class Interface_with_A_Parent : public Base_A {
+public:
+  virtual int baz() = 0;
+};
+
+// Shouldn't warn on forward declarations.
+class Bad_Child1;
+
+// Inherits from multiple concrete classes.
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child1 : public Base_A, Base_B {};
+class Bad_Child1 : public Base_A, Base_B {};
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+class Bad_Child2 : public Base_A, Interface_A_with_member {
+  virtual int foo() override { return 0; }
+};
+
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+class Bad_Child3 : public Interface_with_A_Parent, Base_B {
+  virtual int baz() override { return 0; }
+};
+
+// Easy cases of single inheritance
+class Simple_Child1 : public Base_A {};
+class Simple_Child2 : public Interface_A {
+  virtual int foo() override { return 0; }
+};
+
+// Valid uses of multiple inheritance
+class Good_Child1 : public Interface_A, Interface_B {
+  virtual int foo() override { return 0; }
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child2 : public Base_A, Interface_B {
+  virtual int bar() override { return 0; }
+};
+
+class Good_Child3 : public Base_A_child, Interface_C, Interface_B {
+  virtual int bar() override { return 0; }
+  virtual int blat() override { return 0; }
+};
+
+struct B1 { int x; };
+struct B2 { int x;};
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D : B1, B2 {};
+struct D1 : B1, B2 {};
+
+struct Base1 { virtual void foo() = 0; };
+struct V1 : virtual Base1 {};
+struct V2 : virtual Base1 {};
+struct D2 : V1, V2 {};
+
+struct Base2 { virtual void foo(); };
+struct V3 : virtual Base2 {};
+struct V4 : virtual Base2 {};
+struct D3 : V3, V4 {};
+
+struct Base3 {};
+struct V5 : virtual Base3 { virtual void f(); };
+struct V6 : virtual Base3 { virtual void g(); };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D4 : V5, V6 {};
+struct D4 : V5, V6 {};
+
+struct Base4 {};
+struct V7 : virtual Base4 { virtual void f() = 0; };
+struct V8 : virtual Base4 { virtual void g() = 0; };
+struct D5 : V7, V8 {};
+
+struct Base5 { virtual void f() = 0; };
+struct V9 : virtual Base5 { virtual void f(); };
+struct V10 : virtual Base5 { virtual void g() = 0; };
+struct D6 : V9, V10 {};
+
+struct Base6 { virtual void f(); };
+struct Base7 { virtual void g(); };
+struct V15 : virtual Base6 { virtual void f() = 0; };
+struct V16 : virtual Base7 { virtual void g() = 0; };
+// CHECK-MESSAGES: [[@LINE+2]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+// CHECK-NEXT: struct D9 : V15, V16 {};
+struct D9 : V15, V16 {};
+
+struct Static_Base { static void foo(); };
+struct V11 : virtual Static_Base {};
+struct V12 : virtual Static_Base {};
+struct D7 : V11, V12 {};
+
+struct Static_Base_2 {};
+struct V13 : virtual Static_Base_2 { static void f(); };
+struct V14 : virtual Static_Base_2 { static void g(); };
+struct D8 : V13, V14 {};
+
+template<typename T> struct A : T {};
+template<typename T> struct B : virtual T {};
+
+template<typename> struct C {};
+template<typename T> struct D : C<T> {};
+
+// Check clang_tidy does not crash on this code.
+template <class T>
+struct WithTemplBase : T {
+  WithTemplBase();
+};
+
+void test_no_crash() {
+  auto foo = []() {};
+  WithTemplBase<decltype(foo)>();
+}
+
+struct S1 {};
+struct S2 {};
+
+struct S3 : S1, S2 {};
+
+namespace N {
+
+struct S1 { int i; };
+struct S2 { int i; };
+
+// CHECK-MESSAGES: [[@LINE+1]]:1: warning: inheriting multiple classes that aren't pure virtual is discouraged [misc-multiple-inheritance]
+struct S3 : S1, S2 {};
+
+} // namespace N

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

✅ With the latest revision this PR passed the C/C++ code formatter.

@github-actions
Copy link

github-actions bot commented Dec 10, 2025

✅ With the latest revision this PR passed the C/C++ code linter.

Copy link
Contributor

@EugeneZelenko EugeneZelenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation was not moved and Release Notes entry is missing.

@Bhuvan1527 Bhuvan1527 force-pushed the move-fucshia-multiInher-misc branch from dddbc62 to 629487c Compare December 10, 2025 07:55
…dule

Resolves: [llvm#171136](llvm#171136)
Referred the issue tagged in the issue mentioned.
@Bhuvan1527 Bhuvan1527 force-pushed the move-fucshia-multiInher-misc branch from 629487c to 88b8b46 Compare December 10, 2025 08:09
@zeyi2 zeyi2 self-requested a review December 10, 2025 10:44
Copy link
Member

@zeyi2 zeyi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code change looks nice. However you still need to update the documentations.

more specifically:

  • Edit fuchsia/multiple-inheritance.rst
  • Create a new doc for misc/multiple-inheritance.rst
  • Modify list.rst for correct aliasing
  • Document the change in clang-tools-extra/docs/ReleaseNotes.rst

You can use this PR as a style reference.

@Bhuvan1527
Copy link
Contributor Author

The code change looks nice. However you still need to update the documentations.

more specifically:

  • Edit fuchsia/multiple-inheritance.rst
  • Create a new doc for misc/multiple-inheritance.rst
  • Modify list.rst for correct aliasing
  • Document the change in clang-tools-extra/docs/ReleaseNotes.rst

You can use this PR as a style reference.

Thank you very much for the detailed file list and reference pr @zeyi2 .

@Bhuvan1527 Bhuvan1527 force-pushed the move-fucshia-multiInher-misc branch 2 times, most recently from ca0c334 to de332d3 Compare December 11, 2025 12:41
Copy link
Member

@zeyi2 zeyi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be a good idea to add reference here.

@Bhuvan1527 Bhuvan1527 force-pushed the move-fucshia-multiInher-misc branch from de332d3 to afe7713 Compare December 12, 2025 05:48
Copy link
Contributor

@vbvictor vbvictor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm with nit

Copy link
Member

@zeyi2 zeyi2 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Also, you can apply vbvictor's suggestion like this.

…dule

Updated the documentation in the commit,
1. ReleaseNotes.rst
2. respective docs in the docs/clang-tidy/checks/
3. list.rst
@Bhuvan1527 Bhuvan1527 force-pushed the move-fucshia-multiInher-misc branch from afe7713 to 42a36f0 Compare December 12, 2025 11:13
@Bhuvan1527
Copy link
Contributor Author

@zeyi2 , please trigger the pr merge. I don't have permission to merge.

Thank you

@zeyi2 zeyi2 merged commit e0379b8 into llvm:main Dec 13, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[clang-tidy] Rename 'fuchsia-multiple-inheritance' check to 'misc' module and keep initial as alias.

5 participants