[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-11 Thread Piotr Zegar via Phabricator via cfe-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGf1e2469edcfc: [clang-tidy] Fix false-positive in 
cppcoreguidelines-slicing (authored by PiotrZSL).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,25 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 
'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+namespace PR31187 {
+// Don't warn when calling constructor of base virtual class, from
+// initialization list of derived class constructor.
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), 
BaseB(other) {}
+};
+
+}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -199,11 +199,15 @@
   ` check. Basic support
   for bit-field and integer members as a loop variable or upper limit were 
added.
 
-- Improved :doc:`readability-magic-numbers 
+- Improved :doc:`readability-magic-numbers
   ` check, now allows for
   magic numbers in type aliases such as ``using`` and ``typedef`` declarations 
if
   the new ``IgnoreTypeAliases`` option is set to true.
 
+- Fixed a false positive in :doc:`cppcoreguidelines-slicing
+  ` check when warning would be
+  emitted in constructor for virtual base class initialization.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -40,12 +40,15 @@
   const auto HasTypeDerivedFromBaseDecl =
   anyOf(hasType(IsDerivedFromBaseDecl),
 hasType(references(IsDerivedFromBaseDecl)));
-  const auto IsWithinDerivedCtor =
-  hasParent(cxxConstructorDecl(ofClass(equalsBoundNode("DerivedDecl";
+  const auto IsCallToBaseClass = hasParent(cxxConstructorDecl(
+  ofClass(isSameOrDerivedFrom(equalsBoundNode("DerivedDecl"))),
+  hasAnyConstructorInitializer(allOf(
+  isBaseInitializer(), withInitializer(equalsBoundNode("Call"));
 
   // Assignment slicing: "a = b;" and "a = std::move(b);" variants.
   const auto SlicesObjectInAssignment =
-  callExpr(callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
+  callExpr(expr().bind("Call"),
+   callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
   isMoveAssignmentOperator()),
 OfBaseClass)),
hasArgument(1, HasTypeDerivedFromBaseDecl));
@@ -53,17 +56,17 @@
   // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of
   // slicing the letter will create a temporary and therefore call a ctor.
   const auto SlicesObjectInCtor = cxxConstructExpr(
+  expr().bind("Call"),
   hasDeclaration(cxxConstructorDecl(
   anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)),
   hasArgument(0, HasTypeDerivedFromBaseDecl),
   // We need to disable matching on the call to the base copy/move
   // constructor in DerivedDecl's constructors.
-  unless(IsWithinDerivedCtor));
+  unless(IsCallToBaseClass));
 
-  Finder->addMatcher(traverse(TK_AsIs, expr(anyOf(SlicesObjectInAssignment,
-  SlicesObjectInCtor))
-   .bind("Call")),
- this);
+  Finder->addMatcher(
+  traverse(TK_AsIs, expr(SlicesObjectInAssignment).bind("Call")), this);
+  Finder->addMatcher(traverse(TK_AsIs, SlicesObjectInCtor), this);
 }
 
 /// Warns on methods overridden in DerivedDecl with respect to BaseDecl.


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 

[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-11 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp accepted this revision.
carlosgalvezp added a comment.
This revision is now accepted and ready to land.

LGTM, thanks for the fix!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-11 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL added a comment.

Ack.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-11 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL updated this revision to Diff 504377.
PiotrZSL marked an inline comment as done.
PiotrZSL added a comment.

Review comments fix


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,25 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 
'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+namespace PR31187 {
+// Don't warn when calling constructor of base virtual class, from
+// initialization list of derived class constructor.
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), 
BaseB(other) {}
+};
+
+}
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -199,11 +199,15 @@
   ` check. Basic support
   for bit-field and integer members as a loop variable or upper limit were 
added.
 
-- Improved :doc:`readability-magic-numbers 
+- Improved :doc:`readability-magic-numbers
   ` check, now allows for
   magic numbers in type aliases such as ``using`` and ``typedef`` declarations 
if
   the new ``IgnoreTypeAliases`` option is set to true.
 
+- Fixed a false positive in :doc:`cppcoreguidelines-slicing
+  ` check when warning would be
+  emitted in constructor for virtual base class initialization.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -40,12 +40,15 @@
   const auto HasTypeDerivedFromBaseDecl =
   anyOf(hasType(IsDerivedFromBaseDecl),
 hasType(references(IsDerivedFromBaseDecl)));
-  const auto IsWithinDerivedCtor =
-  hasParent(cxxConstructorDecl(ofClass(equalsBoundNode("DerivedDecl";
+  const auto IsCallToBaseClass = hasParent(cxxConstructorDecl(
+  ofClass(isSameOrDerivedFrom(equalsBoundNode("DerivedDecl"))),
+  hasAnyConstructorInitializer(allOf(
+  isBaseInitializer(), withInitializer(equalsBoundNode("Call"));
 
   // Assignment slicing: "a = b;" and "a = std::move(b);" variants.
   const auto SlicesObjectInAssignment =
-  callExpr(callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
+  callExpr(expr().bind("Call"),
+   callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
   isMoveAssignmentOperator()),
 OfBaseClass)),
hasArgument(1, HasTypeDerivedFromBaseDecl));
@@ -53,17 +56,17 @@
   // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of
   // slicing the letter will create a temporary and therefore call a ctor.
   const auto SlicesObjectInCtor = cxxConstructExpr(
+  expr().bind("Call"),
   hasDeclaration(cxxConstructorDecl(
   anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)),
   hasArgument(0, HasTypeDerivedFromBaseDecl),
   // We need to disable matching on the call to the base copy/move
   // constructor in DerivedDecl's constructors.
-  unless(IsWithinDerivedCtor));
+  unless(IsCallToBaseClass));
 
-  Finder->addMatcher(traverse(TK_AsIs, expr(anyOf(SlicesObjectInAssignment,
-  SlicesObjectInCtor))
-   .bind("Call")),
- this);
+  Finder->addMatcher(
+  traverse(TK_AsIs, expr(SlicesObjectInAssignment).bind("Call")), this);
+  Finder->addMatcher(traverse(TK_AsIs, SlicesObjectInCtor), this);
 }
 
 /// Warns on methods overridden in DerivedDecl with respect to BaseDecl.


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,25 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: 

[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-11 Thread Carlos Galvez via Phabricator via cfe-commits
carlosgalvezp added a comment.

Looks good, just a small comment!




Comment at: 
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp:102
+
+struct BaseA {
+virtual ~BaseA() {}

Please briefly document this test case, i.e. why in this case this is not 
considered slicing and the check should not warn. It would be good to also 
mention the Github issue for traceability.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-08 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL updated this revision to Diff 503287.
PiotrZSL added a comment.

Rebase due to broken baseline


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 
'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), 
BaseB(other) {}
+};
+
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -192,6 +192,10 @@
   ` check. Basic support
   for bit-field and integer members as a loop variable or upper limit were 
added.
 
+- Fixed a false positive in :doc:`cppcoreguidelines-slicing
+  ` check when warning would be
+  emitted in constructor for virtual base class initialization.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -40,12 +40,15 @@
   const auto HasTypeDerivedFromBaseDecl =
   anyOf(hasType(IsDerivedFromBaseDecl),
 hasType(references(IsDerivedFromBaseDecl)));
-  const auto IsWithinDerivedCtor =
-  hasParent(cxxConstructorDecl(ofClass(equalsBoundNode("DerivedDecl";
+  const auto IsCallToBaseClass = hasParent(cxxConstructorDecl(
+  ofClass(isSameOrDerivedFrom(equalsBoundNode("DerivedDecl"))),
+  hasAnyConstructorInitializer(allOf(
+  isBaseInitializer(), withInitializer(equalsBoundNode("Call"));
 
   // Assignment slicing: "a = b;" and "a = std::move(b);" variants.
   const auto SlicesObjectInAssignment =
-  callExpr(callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
+  callExpr(expr().bind("Call"),
+   callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
   isMoveAssignmentOperator()),
 OfBaseClass)),
hasArgument(1, HasTypeDerivedFromBaseDecl));
@@ -53,17 +56,17 @@
   // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of
   // slicing the letter will create a temporary and therefore call a ctor.
   const auto SlicesObjectInCtor = cxxConstructExpr(
+  expr().bind("Call"),
   hasDeclaration(cxxConstructorDecl(
   anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)),
   hasArgument(0, HasTypeDerivedFromBaseDecl),
   // We need to disable matching on the call to the base copy/move
   // constructor in DerivedDecl's constructors.
-  unless(IsWithinDerivedCtor));
+  unless(IsCallToBaseClass));
 
-  Finder->addMatcher(traverse(TK_AsIs, expr(anyOf(SlicesObjectInAssignment,
-  SlicesObjectInCtor))
-   .bind("Call")),
- this);
+  Finder->addMatcher(
+  traverse(TK_AsIs, expr(SlicesObjectInAssignment).bind("Call")), this);
+  Finder->addMatcher(traverse(TK_AsIs, SlicesObjectInCtor), this);
 }
 
 /// Warns on methods overridden in DerivedDecl with respect to BaseDecl.


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), BaseB(other) {}

[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-03-07 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL updated this revision to Diff 503082.
PiotrZSL added a comment.

Ping, Rebase


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D144206/new/

https://reviews.llvm.org/D144206

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 
'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), 
BaseB(other) {}
+};
+
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -192,6 +192,10 @@
   ` check. Basic support
   for bit-field and integer members as a loop variable or upper limit were 
added.
 
+- Fixed a false positive in :doc:`cppcoreguidelines-slicing
+  ` check when warning would be
+  emitted in constructor for virtual base class initialization.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -40,12 +40,15 @@
   const auto HasTypeDerivedFromBaseDecl =
   anyOf(hasType(IsDerivedFromBaseDecl),
 hasType(references(IsDerivedFromBaseDecl)));
-  const auto IsWithinDerivedCtor =
-  hasParent(cxxConstructorDecl(ofClass(equalsBoundNode("DerivedDecl";
+  const auto IsCallToBaseClass = hasParent(cxxConstructorDecl(
+  ofClass(isSameOrDerivedFrom(equalsBoundNode("DerivedDecl"))),
+  hasAnyConstructorInitializer(allOf(
+  isBaseInitializer(), withInitializer(equalsBoundNode("Call"));
 
   // Assignment slicing: "a = b;" and "a = std::move(b);" variants.
   const auto SlicesObjectInAssignment =
-  callExpr(callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
+  callExpr(expr().bind("Call"),
+   callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
   isMoveAssignmentOperator()),
 OfBaseClass)),
hasArgument(1, HasTypeDerivedFromBaseDecl));
@@ -53,17 +56,17 @@
   // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of
   // slicing the letter will create a temporary and therefore call a ctor.
   const auto SlicesObjectInCtor = cxxConstructExpr(
+  expr().bind("Call"),
   hasDeclaration(cxxConstructorDecl(
   anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)),
   hasArgument(0, HasTypeDerivedFromBaseDecl),
   // We need to disable matching on the call to the base copy/move
   // constructor in DerivedDecl's constructors.
-  unless(IsWithinDerivedCtor));
+  unless(IsCallToBaseClass));
 
-  Finder->addMatcher(traverse(TK_AsIs, expr(anyOf(SlicesObjectInAssignment,
-  SlicesObjectInCtor))
-   .bind("Call")),
- this);
+  Finder->addMatcher(
+  traverse(TK_AsIs, expr(SlicesObjectInAssignment).bind("Call")), this);
+  Finder->addMatcher(traverse(TK_AsIs, SlicesObjectInCtor), this);
 }
 
 /// Warns on methods overridden in DerivedDecl with respect to BaseDecl.


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), BaseB(other) {}
+};
+
Index: 

[PATCH] D144206: [clang-tidy] Fix false-positive in cppcoreguidelines-slicing

2023-02-16 Thread Piotr Zegar via Phabricator via cfe-commits
PiotrZSL created this revision.
Herald added subscribers: carlosgalvezp, shchenz, kbarton, xazax.hun, nemanjai.
Herald added a reviewer: njames93.
Herald added a project: All.
PiotrZSL published this revision for review.
PiotrZSL added a comment.
Herald added a project: clang-tools-extra.
Herald added a subscriber: cfe-commits.

Ready for review.


When warning would be emitted in constructor for virtual base class
initialization.

Fixes: https://github.com/llvm/llvm-project/issues/31187


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D144206

Files:
  clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 
'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+
+struct BaseB : virtual BaseA {
+virtual void foo() {}
+};
+
+struct ClassWithVirtualBases : BaseB {
+  ClassWithVirtualBases(const BaseB& other) : BaseA(other), BaseB(other) {}
+  ClassWithVirtualBases(const ClassWithVirtualBases& other) : BaseA(other), 
BaseB(other) {}
+};
+
Index: clang-tools-extra/docs/ReleaseNotes.rst
===
--- clang-tools-extra/docs/ReleaseNotes.rst
+++ clang-tools-extra/docs/ReleaseNotes.rst
@@ -130,6 +130,10 @@
 Changes in existing checks
 ^^
 
+- Fixed a false positive in :doc:`cppcoreguidelines-slicing
+  ` check when warning would be
+  emitted in constructor for virtual base class initialization.
+
 Removed checks
 ^^
 
Index: clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
===
--- clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -40,12 +40,15 @@
   const auto HasTypeDerivedFromBaseDecl =
   anyOf(hasType(IsDerivedFromBaseDecl),
 hasType(references(IsDerivedFromBaseDecl)));
-  const auto IsWithinDerivedCtor =
-  hasParent(cxxConstructorDecl(ofClass(equalsBoundNode("DerivedDecl";
+  const auto IsCallToBaseClass = hasParent(cxxConstructorDecl(
+  ofClass(isSameOrDerivedFrom(equalsBoundNode("DerivedDecl"))),
+  hasAnyConstructorInitializer(allOf(
+  isBaseInitializer(), withInitializer(equalsBoundNode("Call"));
 
   // Assignment slicing: "a = b;" and "a = std::move(b);" variants.
   const auto SlicesObjectInAssignment =
-  callExpr(callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
+  callExpr(expr().bind("Call"),
+   callee(cxxMethodDecl(anyOf(isCopyAssignmentOperator(),
   isMoveAssignmentOperator()),
 OfBaseClass)),
hasArgument(1, HasTypeDerivedFromBaseDecl));
@@ -53,17 +56,17 @@
   // Construction slicing: "A a{b};" and "f(b);" variants. Note that in case of
   // slicing the letter will create a temporary and therefore call a ctor.
   const auto SlicesObjectInCtor = cxxConstructExpr(
+  expr().bind("Call"),
   hasDeclaration(cxxConstructorDecl(
   anyOf(isCopyConstructor(), isMoveConstructor()), OfBaseClass)),
   hasArgument(0, HasTypeDerivedFromBaseDecl),
   // We need to disable matching on the call to the base copy/move
   // constructor in DerivedDecl's constructors.
-  unless(IsWithinDerivedCtor));
+  unless(IsCallToBaseClass));
 
-  Finder->addMatcher(traverse(TK_AsIs, expr(anyOf(SlicesObjectInAssignment,
-  SlicesObjectInCtor))
-   .bind("Call")),
- this);
+  Finder->addMatcher(
+  traverse(TK_AsIs, expr(SlicesObjectInAssignment).bind("Call")), this);
+  Finder->addMatcher(traverse(TK_AsIs, SlicesObjectInCtor), this);
 }
 
 /// Warns on methods overridden in DerivedDecl with respect to BaseDecl.


Index: clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
===
--- clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
+++ clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines/slicing.cpp
@@ -98,3 +98,20 @@
   a = h;
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: slicing object from type 'DerivedThatOverridesH' to 'Base' discards override 'h'
 }
+
+struct BaseA {
+virtual ~BaseA() {}
+virtual void foo() {}
+
+int i;
+};
+