File tree Expand file tree Collapse file tree 6 files changed +82
-4
lines changed Expand file tree Collapse file tree 6 files changed +82
-4
lines changed Original file line number Diff line number Diff line change @@ -105,11 +105,15 @@ void TaggedUnionMemberCountCheck::storeOptions(
105105
106106void TaggedUnionMemberCountCheck::registerMatchers (MatchFinder *Finder) {
107107
108- auto UnionField = fieldDecl ( hasType ( qualType (
109- hasCanonicalType ( recordType ( hasDeclaration ( recordDecl ( isUnion ())))) )));
108+ auto NotFromSystemHeaderOrStdNamespace =
109+ unless ( anyOf ( isExpansionInSystemHeader (), isInStdNamespace ( )));
110110
111- auto EnumField = fieldDecl (hasType (
112- qualType (hasCanonicalType (enumType (hasDeclaration (enumDecl ()))))));
111+ auto UnionField =
112+ fieldDecl (hasType (qualType (hasCanonicalType (recordType (hasDeclaration (
113+ recordDecl (isUnion (), NotFromSystemHeaderOrStdNamespace)))))));
114+
115+ auto EnumField = fieldDecl (hasType (qualType (hasCanonicalType (
116+ enumType (hasDeclaration (enumDecl (NotFromSystemHeaderOrStdNamespace)))))));
113117
114118 auto HasOneUnionField = fieldCountOfKindIsOne (UnionField, UnionMatchBindName);
115119 auto HasOneEnumField = fieldCountOfKindIsOne (EnumField, TagMatchBindName);
Original file line number Diff line number Diff line change @@ -9,6 +9,9 @@ different from the number of data members inside the union.
99A struct or a class is considered to be a tagged union if it has
1010exactly one union data member and exactly one enum data member and
1111any number of other data members that are neither unions or enums.
12+ The union and enum data members that are from system header files or
13+ the std namespace are not considered to make up the tagged union part
14+ of a user-defined tagged union type.
1215
1316Example:
1417
@@ -28,6 +31,25 @@ Example:
2831 } Data;
2932 };
3033
34+ The following example illustrates the exception for unions and enums from
35+ system header files and the std namespace.
36+
37+ .. code-block :: c++
38+
39+ #include <pthread.h>
40+
41+ struct NotTaggedUnion {
42+ enum MyEnum { MyEnumConstant1, MyEnumConstant2 } En;
43+ pthread_mutex_t Mutex;
44+ };
45+
46+ The pthread_mutex_t type may be defined as a union behind a typedef,
47+ in which case the check could mistake this type as a user-defined tagged union.
48+ After all it has exactly one enum data member and exactly one union data member.
49+ To avoid false-positive cases originating from this, unions and enums from
50+ system headers and the std namespace are ignored when pinpointing the
51+ union part and the enum part of a potential user-defined tagged union.
52+
3153How enum constants are counted
3254------------------------------
3355
Original file line number Diff line number Diff line change @@ -147,3 +147,16 @@ struct Name {\
147147
148148// CHECK-MESSAGES: :[[@LINE+1]]:44: warning: tagged union has more data members (4) than tags (3)
149149DECLARE_TAGGED_UNION_STRUCT (Tags3 , Union4 , TaggedUnionStructFromMacro );
150+
151+ // Typedefed unions from system header files should be ignored when
152+ // we are trying to pinpoint the union part in a user-defined tagged union.
153+ #include "pthread.h"
154+
155+ // This should not be analyzed as a user-defined tagged union,
156+ // even though pthread_mutex_t may be declared as a typedefed union.
157+ struct SystemTypedefedUnionDataMemberShouldBeIgnored {
158+ pthread_mutex_t Mutex ;
159+ enum {
160+ MyEnum
161+ } EnumField ;
162+ };
Original file line number Diff line number Diff line change @@ -308,3 +308,16 @@ void DoNotMatchLambdas() {
308308 } u;
309309 auto L = [e, u] () {};
310310}
311+
312+ // Typedefed unions from system header files should be ignored when
313+ // we are trying to pinpoint the union part in a user-defined tagged union.
314+ #include " pthread.h"
315+
316+ // This should not be analyzed as a user-defined tagged union,
317+ // even though pthread_mutex_t may be declared as a typedefed union.
318+ struct SystemTypedefedUnionDataMemberShouldBeIgnored {
319+ pthread_mutex_t Mutex;
320+ enum {
321+ MyEnum
322+ } EnumField;
323+ };
Original file line number Diff line number Diff line change 147147
148148// CHECK-MESSAGES: :[[@LINE+1]]:44: warning: tagged union has more data members (4) than tags (3)
149149DECLARE_TAGGED_UNION_STRUCT (Tags3, Union4, TaggedUnionStructFromMacro);
150+
151+ // Typedefed unions from system header files should be ignored when
152+ // we are trying to pinpoint the union part in a user-defined tagged union.
153+ #include " pthread.h"
154+
155+ // This should not be analyzed as a user-defined tagged union,
156+ // even though pthread_mutex_t may be declared as a typedefed union.
157+ struct SystemTypedefedUnionDataMemberShouldBeIgnored {
158+ pthread_mutex_t Mutex;
159+ enum {
160+ MyEnum
161+ } EnumField;
162+ };
Original file line number Diff line number Diff line change @@ -307,3 +307,16 @@ void DoNotMatchLambdas() {
307307 } u;
308308 auto L = [e, u] () {};
309309}
310+
311+ // Typedefed unions from system header files should be ignored when
312+ // we are trying to pinpoint the union part in a user-defined tagged union.
313+ #include " pthread.h"
314+
315+ // This should not be analyzed as a user-defined tagged union,
316+ // even though pthread_mutex_t may be declared as a typedefed union.
317+ struct SystemTypedefedUnionDataMemberShouldBeIgnored {
318+ pthread_mutex_t Mutex;
319+ enum {
320+ MyEnum
321+ } EnumField;
322+ };
You can’t perform that action at this time.
0 commit comments