https://github.com/tigbr updated https://github.com/llvm/llvm-project/pull/135831
>From 525459a04dd6e7d0079095ac531c7cd712ac91d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20T=C3=B3thv=C3=A1ri?= <gabor.tothv...@ericsson.com> Date: Mon, 14 Apr 2025 17:09:07 +0200 Subject: [PATCH] [clang-tidy] Fix bugprone-tagged-union-member-count false-positive Types from system headers and the std namespace are no longer considered as the enum part or the union part of a user-defined tagged union. Fixes #134840 --- .../bugprone/TaggedUnionMemberCountCheck.cpp | 12 ++++++---- .../bugprone/tagged-union-member-count.rst | 22 +++++++++++++++++++ .../bugprone/tagged-union-member-count.c | 13 +++++++++++ .../bugprone/tagged-union-member-count.cpp | 13 +++++++++++ .../bugprone/tagged-union-member-count.m | 13 +++++++++++ .../bugprone/tagged-union-member-count.mm | 13 +++++++++++ 6 files changed, 82 insertions(+), 4 deletions(-) diff --git a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp index db99ef3786e5f..b91da7db39463 100644 --- a/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/TaggedUnionMemberCountCheck.cpp @@ -106,11 +106,15 @@ void TaggedUnionMemberCountCheck::storeOptions( void TaggedUnionMemberCountCheck::registerMatchers(MatchFinder *Finder) { - auto UnionField = fieldDecl(hasType(qualType( - hasCanonicalType(recordType(hasDeclaration(recordDecl(isUnion()))))))); + auto NotFromSystemHeaderOrStdNamespace = + unless(anyOf(isExpansionInSystemHeader(), isInStdNamespace())); - auto EnumField = fieldDecl(hasType( - qualType(hasCanonicalType(enumType(hasDeclaration(enumDecl())))))); + auto UnionField = + fieldDecl(hasType(qualType(hasCanonicalType(recordType(hasDeclaration( + recordDecl(isUnion(), NotFromSystemHeaderOrStdNamespace))))))); + + auto EnumField = fieldDecl(hasType(qualType(hasCanonicalType( + enumType(hasDeclaration(enumDecl(NotFromSystemHeaderOrStdNamespace))))))); auto hasOneUnionField = fieldCountOfKindIsOne(UnionField, UnionMatchBindName); auto hasOneEnumField = fieldCountOfKindIsOne(EnumField, TagMatchBindName); diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone/tagged-union-member-count.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone/tagged-union-member-count.rst index 2f1036c10345e..b47a49543143b 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone/tagged-union-member-count.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone/tagged-union-member-count.rst @@ -9,6 +9,9 @@ different from the number of data members inside the union. A struct or a class is considered to be a tagged union if it has exactly one union data member and exactly one enum data member and any number of other data members that are neither unions or enums. +The union and enum data members that are from system header files or +the std namespace are not considered to make up the tagged union part +of a user-defined tagged union type. Example: @@ -28,6 +31,25 @@ Example: } Data; }; +The following example illustrates the exception for unions and enums from +system header files and the std namespace. + +.. code-block:: c++ + + #include <pthread.h> + + struct NotTaggedUnion { + enum MyEnum { MyEnumConstant1, MyEnumConstant2 } En; + pthread_mutex_t Mutex; + }; + +The pthread_mutex_t type may be defined as a union behind a typedef, +in which case the check could mistake this type as a user-defined tagged union. +After all it has exactly one enum data member and exactly one union data member. +To avoid false-positive cases originating from this, unions and enums from +system headers and the std namespace are ignored when pinpointing the +union part and the enum part of a potential user-defined tagged union. + How enum constants are counted ------------------------------ diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.c b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.c index 60c93c553baca..96255c7fdd4fe 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.c +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.c @@ -147,3 +147,16 @@ struct Name {\ // CHECK-MESSAGES: :[[@LINE+1]]:44: warning: tagged union has more data members (4) than tags (3) DECLARE_TAGGED_UNION_STRUCT(Tags3, Union4, TaggedUnionStructFromMacro); + +// Typedefed unions from system header files should be ignored when +// we are trying to pinpoint the union part in a user-defined tagged union. +#include "pthread.h" + +// This should not be analyzed as a user-defined tagged union, +// even though pthread_mutex_t may be declared as a typedefed union. +struct SystemTypedefedUnionDataMemberShouldBeIgnored { + pthread_mutex_t Mutex; + enum { + MyEnum + } EnumField; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.cpp index 25827e8c8de0c..f21c23b87ae44 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.cpp @@ -308,3 +308,16 @@ void DoNotMatchLambdas() { } u; auto L = [e, u] () {}; } + +// Typedefed unions from system header files should be ignored when +// we are trying to pinpoint the union part in a user-defined tagged union. +#include "pthread.h" + +// This should not be analyzed as a user-defined tagged union, +// even though pthread_mutex_t may be declared as a typedefed union. +struct SystemTypedefedUnionDataMemberShouldBeIgnored { + pthread_mutex_t Mutex; + enum { + MyEnum + } EnumField; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.m b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.m index 60c93c553baca..96255c7fdd4fe 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.m +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.m @@ -147,3 +147,16 @@ // CHECK-MESSAGES: :[[@LINE+1]]:44: warning: tagged union has more data members (4) than tags (3) DECLARE_TAGGED_UNION_STRUCT(Tags3, Union4, TaggedUnionStructFromMacro); + +// Typedefed unions from system header files should be ignored when +// we are trying to pinpoint the union part in a user-defined tagged union. +#include "pthread.h" + +// This should not be analyzed as a user-defined tagged union, +// even though pthread_mutex_t may be declared as a typedefed union. +struct SystemTypedefedUnionDataMemberShouldBeIgnored { + pthread_mutex_t Mutex; + enum { + MyEnum + } EnumField; +}; diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.mm b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.mm index 8b308555281c5..b169b5cd480b5 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.mm +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/tagged-union-member-count.mm @@ -307,3 +307,16 @@ void DoNotMatchLambdas() { } u; auto L = [e, u] () {}; } + +// Typedefed unions from system header files should be ignored when +// we are trying to pinpoint the union part in a user-defined tagged union. +#include "pthread.h" + +// This should not be analyzed as a user-defined tagged union, +// even though pthread_mutex_t may be declared as a typedefed union. +struct SystemTypedefedUnionDataMemberShouldBeIgnored { + pthread_mutex_t Mutex; + enum { + MyEnum + } EnumField; +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits