[PATCH] D51680: [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields
This revision was automatically updated to reflect the committed changes. Closed by commit rL342220: [analyzer][UninitializedObjectChecker] New flag to ignore records based on its… (authored by Szelethus, committed by ). Herald added a subscriber: llvm-commits. Changed prior to commit: https://reviews.llvm.org/D51680?vs=164696=165454#toc Repository: rL LLVM https://reviews.llvm.org/D51680 Files: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp cfe/trunk/www/analyzer/alpha_checks.html Index: cfe/trunk/www/analyzer/alpha_checks.html === --- cfe/trunk/www/analyzer/alpha_checks.html +++ cfe/trunk/www/analyzer/alpha_checks.html @@ -356,6 +356,13 @@ whether the object itself is initialized. Defaults to false. -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true. + +"IgnoreRecordsWithField" (string). If supplied, the checker will not + analyze structures that have a field with a name or type name that + matches the given pattern. Defaults to "". + + -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind". + Index: cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp === --- cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp +++ cfe/trunk/test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp @@ -0,0 +1,136 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ +// RUN: -std=c++11 -verify %s + +// expected-no-diagnostics + +// Both type and name contains "kind". +struct UnionLikeStruct1 { + enum Kind { +volume, +area + } kind; + + int Volume; + int Area; + + UnionLikeStruct1(Kind kind, int Val) : kind(kind) { +switch (kind) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct1() { + UnionLikeStruct1 t(UnionLikeStruct1::volume, 10); +} + +// Only name contains "kind". +struct UnionLikeStruct2 { + enum Type { +volume, +area + } kind; + + int Volume; + int Area; + + UnionLikeStruct2(Type kind, int Val) : kind(kind) { +switch (kind) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct2() { + UnionLikeStruct2 t(UnionLikeStruct2::volume, 10); +} + +// Only type contains "kind". +struct UnionLikeStruct3 { + enum Kind { +volume, +area + } type; + + int Volume; + int Area; + + UnionLikeStruct3(Kind type, int Val) : type(type) { +switch (type) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct3() { + UnionLikeStruct3 t(UnionLikeStruct3::volume, 10); +} + +// Only type contains "tag". +struct UnionLikeStruct4 { + enum Tag { +volume, +area + } type; + + int Volume; + int Area; + + UnionLikeStruct4(Tag type, int Val) : type(type) { +switch (type) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct4() { + UnionLikeStruct4 t(UnionLikeStruct4::volume, 10); +} + +// Both name and type name contains but does not equal to tag/kind. +struct UnionLikeStruct5 { + enum WhateverTagBlahBlah { +volume, +area + } FunnyKindName; + + int Volume; + int Area; + + UnionLikeStruct5(WhateverTagBlahBlah type, int Val) : FunnyKindName(type) { +switch (FunnyKindName) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct5() { + UnionLikeStruct5 t(UnionLikeStruct5::volume, 10); +} Index: cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp === --- cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ cfe/trunk/lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -109,6 +109,10 @@ static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor, CheckerContext ); +/// Checks whether RD contains a field with a name or type name that matches +/// \p Pattern. +static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern); +
[PATCH] D51680: [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields
Szelethus marked an inline comment as done. Szelethus added inline comments. Comment at: test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp:1-4 +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ +// RUN: -std=c++11 -verify %s NoQ wrote: > If you like, you can make a directory for your tests, instead of a filename > prefix. > > Btw, thanks for pointing out that we can use `\` in run-lines, i never > noticed it before you started using it. Cheers! I actually saw this trick in D45050. https://reviews.llvm.org/D51680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51680: [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields
NoQ accepted this revision. NoQ added a comment. This revision is now accepted and ready to land. I hope we'll be able to come up with a reasonable default regex. Comment at: test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp:1-4 +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ +// RUN: -std=c++11 -verify %s If you like, you can make a directory for your tests, instead of a filename prefix. Btw, thanks for pointing out that we can use `\` in run-lines, i never noticed it before you started using it. https://reviews.llvm.org/D51680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51680: [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields
Szelethus marked an inline comment as done. Szelethus added inline comments. Comment at: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp:468 +static bool isUnionLike(const RecordDecl *RD) { + llvm::Regex ContainsKindOrTag("[kK]ind|[tT]ag"); + george.karpenkov wrote: > 1. Since you are using `match`, you would reject an extra prefix - but what > about an extra suffix? > 2. Would it make sense to expose the entire regexp as a flag? Then you could > remove the boolean flag (if you can change the regexp to match if only the > entire field name matches, then an empty regexp would correspond to "no > matches") 1. Added a new test case, seems to be fine ^-^ 2. Sounds cool, so I made it happen. https://reviews.llvm.org/D51680 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D51680: [analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields
Szelethus updated this revision to Diff 164696. Szelethus retitled this revision from "[analyzer][UninitializedObjectChecker] New flag to ignore union-like constructs" to "[analyzer][UninitializedObjectChecker] New flag to ignore records based on it's fields". Szelethus edited the summary of this revision. Szelethus added a comment. Generalized the patch so that the user can supply the pattern that is matched against the fields of the records. https://reviews.llvm.org/D51680 Files: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObject.h lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp www/analyzer/alpha_checks.html Index: www/analyzer/alpha_checks.html === --- www/analyzer/alpha_checks.html +++ www/analyzer/alpha_checks.html @@ -356,6 +356,13 @@ whether the object itself is initialized. Defaults to false. -analyzer-config alpha.cplusplus.UninitializedObject:CheckPointeeInitialization=true. + +"IgnoreRecordsWithField" (string). If supplied, the checker will not + analyze structures that have a field with a name or type name that + matches the given pattern. Defaults to "". + + -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind". + Index: test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp === --- /dev/null +++ test/Analysis/cxx-uninitialized-object-unionlike-constructs.cpp @@ -0,0 +1,136 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.cplusplus.UninitializedObject \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:Pedantic=true -DPEDANTIC \ +// RUN: -analyzer-config alpha.cplusplus.UninitializedObject:IgnoreRecordsWithField="[Tt]ag|[Kk]ind" \ +// RUN: -std=c++11 -verify %s + +// expected-no-diagnostics + +// Both type and name contains "kind". +struct UnionLikeStruct1 { + enum Kind { +volume, +area + } kind; + + int Volume; + int Area; + + UnionLikeStruct1(Kind kind, int Val) : kind(kind) { +switch (kind) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct1() { + UnionLikeStruct1 t(UnionLikeStruct1::volume, 10); +} + +// Only name contains "kind". +struct UnionLikeStruct2 { + enum Type { +volume, +area + } kind; + + int Volume; + int Area; + + UnionLikeStruct2(Type kind, int Val) : kind(kind) { +switch (kind) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct2() { + UnionLikeStruct2 t(UnionLikeStruct2::volume, 10); +} + +// Only type contains "kind". +struct UnionLikeStruct3 { + enum Kind { +volume, +area + } type; + + int Volume; + int Area; + + UnionLikeStruct3(Kind type, int Val) : type(type) { +switch (type) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct3() { + UnionLikeStruct3 t(UnionLikeStruct3::volume, 10); +} + +// Only type contains "tag". +struct UnionLikeStruct4 { + enum Tag { +volume, +area + } type; + + int Volume; + int Area; + + UnionLikeStruct4(Tag type, int Val) : type(type) { +switch (type) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct4() { + UnionLikeStruct4 t(UnionLikeStruct4::volume, 10); +} + +// Both name and type name contains but does not equal to tag/kind. +struct UnionLikeStruct5 { + enum WhateverTagBlahBlah { +volume, +area + } FunnyKindName; + + int Volume; + int Area; + + UnionLikeStruct5(WhateverTagBlahBlah type, int Val) : FunnyKindName(type) { +switch (FunnyKindName) { +case volume: + Volume = Val; + break; +case area: + Area = Val; + break; +} + } +}; + +void fUnionLikeStruct5() { + UnionLikeStruct5 t(UnionLikeStruct5::volume, 10); +} Index: lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp === --- lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp +++ lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp @@ -107,6 +107,10 @@ static bool willObjectBeAnalyzedLater(const CXXConstructorDecl *Ctor, CheckerContext ); +/// Checks whether RD contains a field with a name or type name that matches +/// \p Pattern. +static bool shouldIgnoreRecord(const RecordDecl *RD, StringRef Pattern); + //===--===// // Methods for UninitializedObjectChecker.