[clang-tidy] Skip unions in use-equals-default

For unions constructors with empty bodies behave differently
(in comparison with structs/classes) and clang-tidy's fix
might break the code. This diff adjusts the check to skip unions
for now (it seems to be a relatively rare case).

Test plan: ninja check-all

Differential revision: https://reviews.llvm.org/D132290
This commit is contained in:
Alexander Shaposhnikov 2022-08-23 20:09:40 +00:00
parent 35a56e5ddc
commit 083e3a173d
4 changed files with 35 additions and 3 deletions

View File

@ -217,12 +217,17 @@ void UseEqualsDefaultCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
// Skip unions since constructors with empty bodies behave differently
// in comparison with structs/classes.
// Destructor.
Finder->addMatcher(cxxDestructorDecl(isDefinition()).bind(SpecialFunction),
Finder->addMatcher(cxxDestructorDecl(unless(hasParent(recordDecl(isUnion()))),
isDefinition())
.bind(SpecialFunction),
this);
Finder->addMatcher(
cxxConstructorDecl(
isDefinition(),
unless(hasParent(recordDecl(isUnion()))), isDefinition(),
anyOf(
// Default constructor.
allOf(unless(hasAnyConstructorInitializer(isWritten())),
@ -237,7 +242,8 @@ void UseEqualsDefaultCheck::registerMatchers(MatchFinder *Finder) {
this);
// Copy-assignment operator.
Finder->addMatcher(
cxxMethodDecl(isDefinition(), isCopyAssignmentOperator(),
cxxMethodDecl(unless(hasParent(recordDecl(isUnion()))), isDefinition(),
isCopyAssignmentOperator(),
// isCopyAssignmentOperator() allows the parameter to be
// passed by value, and in this case it cannot be
// defaulted.

View File

@ -127,6 +127,11 @@ Changes in existing checks
``push_front`` on STL-style containers and replacing them with ``emplace``
or ``emplace_front``.
- Improved `modernize-use-equals-default <clang-tidy/checks/modernize/use-equals-default.html>`_ check.
The check now skips unions since in this case a default constructor with empty body
is not equivalent to the explicitly defaulted one.
Removed checks
^^^^^^^^^^^^^^

View File

@ -32,6 +32,18 @@ struct IL {
int Field;
};
// Skip unions.
union NU {
NU(const NU &Other) : Field(Other.Field) {}
// CHECK-FIXES: NU(const NU &Other) :
NU &operator=(const NU &Other) {
Field = Other.Field;
return *this;
}
// CHECK-FIXES: NU &operator=(const NU &Other) {
IL Field;
};
// Wrong type.
struct WT {
WT(const IL &Other) {}

View File

@ -33,6 +33,15 @@ public:
~NE() { f(); }
};
// Skip unions.
union NU {
NU() {}
// CHECK-FIXES: NU() {}
~NU() {}
// CHECK-FIXES: ~NU() {}
NE Field;
};
// Initializer or arguments.
class IA {
public: