[PATCH] Add some automatic tests for DivideZero checker
Hi all, I'm a new contributor in clang / llvm. I'm planning to work on clang static analyzer: maybe add new checker, imporve the exisiting one, etc. As the first step I checked how core.DivideZero checker works now and added some test cases for regression testing (see attached patch). The patch contains not only test cases when the checker catches an issue, but also use cases when the checker misses a division by zero situation, showing that there is some points where the checker can be improved. Best Regards, Tamás Zolnai divide_by_zero_tests Description: Binary data ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] Add some automatic tests for DivideZero checker
Hi, I uploaded this patch to phabricator: https://reviews.llvm.org/D52936 Best Regards, Tamás Tamás Zolnai ezt írta (időpont: 2018. okt. 5., P, 14:14): > Hi all, > > I'm a new contributor in clang / llvm. I'm planning to work on clang > static analyzer: maybe add new checker, imporve the exisiting one, etc. As > the first step I checked how core.DivideZero checker works now and added > some test cases for regression testing (see attached patch). > The patch contains not only test cases when the checker catches an issue, > but also use cases when the checker misses a division by zero situation, > showing that there is some points where the checker can be improved. > > Best Regards, > Tamás Zolnai > ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 0f9e1e3 - [clang-tidy]: fix false positive of cert-oop54-cpp check.
Author: Tamás Zolnai Date: 2020-04-04T17:19:17+02:00 New Revision: 0f9e1e3ae750df483b7fff905a8bc89262e3179e URL: https://github.com/llvm/llvm-project/commit/0f9e1e3ae750df483b7fff905a8bc89262e3179e DIFF: https://github.com/llvm/llvm-project/commit/0f9e1e3ae750df483b7fff905a8bc89262e3179e.diff LOG: [clang-tidy]: fix false positive of cert-oop54-cpp check. Summary: It seems we need a different matcher for binary operator in a template context. Fixes this issue: https://bugs.llvm.org/show_bug.cgi?id=44499 Reviewers: aaron.ballman, alexfh, hokein, njames93 Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D76990 Added: Modified: clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp index f2de9fbde2a6..d91353e21fb1 100644 --- a/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/UnhandledSelfAssignmentCheck.cpp @@ -40,9 +40,12 @@ void UnhandledSelfAssignmentCheck::registerMatchers(MatchFinder *Finder) { // Self-check: Code compares something with 'this' pointer. We don't check // whether it is actually the parameter what we compare. - const auto HasNoSelfCheck = cxxMethodDecl(unless( + const auto HasNoSelfCheck = cxxMethodDecl(unless(anyOf( hasDescendant(binaryOperator(hasAnyOperatorName("==", "!="), - has(ignoringParenCasts(cxxThisExpr())); + has(ignoringParenCasts(cxxThisExpr(), + hasDescendant(cxxOperatorCallExpr( + hasAnyOverloadedOperatorName("==", "!="), argumentCountIs(2), + has(ignoringParenCasts(cxxThisExpr(; // Both copy-and-swap and copy-and-move method creates a copy first and // assign it to 'this' with swap or move. diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp index 49bb5314f9eb..fb7c089ae8cd 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unhandled-self-assignment.cpp @@ -212,6 +212,21 @@ class WrongTemplateCopyAndMove { T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo2; +template +bool operator!=(Foo2 &, Foo2 &) { + class Bar2 { +Bar2 &operator=(const Bar2 &other) { + // CHECK-MESSAGES: [[@LINE-1]]:11: warning: operator=() does not handle self-assignment properly [bugprone-unhandled-self-assignment] + p = other.p; + return *this; +} + +int *p; + }; +} + /// /// Test cases correctly ignored by the check. @@ -283,6 +298,21 @@ class TemplateSelfCheck { T *p; }; +// https://bugs.llvm.org/show_bug.cgi?id=44499 +class Foo; +template +bool operator!=(Foo &, Foo &) { + class Bar { +Bar &operator=(const Bar &other) { + if (this != &other) { + } + return *this; +} + +int *p; + }; +} + // There is no warning if the copy assignment operator gets the object by value. class PassedByValue { public: ___ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[clang-tools-extra] 030ff90 - [clang-tidy] extend bugprone-signed-char-misuse check with array subscript case.
Author: Tamás Zolnai Date: 2020-05-02T14:05:05+02:00 New Revision: 030ff901f43258d18b68a77b0085d0fae2a0fbc6 URL: https://github.com/llvm/llvm-project/commit/030ff901f43258d18b68a77b0085d0fae2a0fbc6 DIFF: https://github.com/llvm/llvm-project/commit/030ff901f43258d18b68a77b0085d0fae2a0fbc6.diff LOG: [clang-tidy] extend bugprone-signed-char-misuse check with array subscript case. Summary: To cover STR34-C rule's second use case, where ``signed char`` is used for array subscript after an integer conversion. In the case of non-ASCII character this conversion will result in a value in excess of UCHAR_MAX. There is another clang-tidy check which catches these cases. cppcoreguidelines-pro-bounds-constant-array-index catches any indexing which is not integer constant. I think this check is very strict about the index (e.g. constant), so it's still useful to cover the ``signed char`` use case in this check, so we can provide a way to catch the SEI cert rule's use cases on a codebase, where this CPP guideline is not used. Reviewers: aaron.ballman, njames93 Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D78904 Added: Modified: clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp index 732ccbc9dd2a..66f00e35c7e7 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -102,11 +102,31 @@ void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { .bind("comparison"); Finder->addMatcher(CompareOperator, this); + + // Catch array subscripts with signed char -> integer conversion. + // Matcher for C arrays. + const auto CArraySubscript = + arraySubscriptExpr(hasIndex(SignedCharCastExpr)).bind("arraySubscript"); + + Finder->addMatcher(CArraySubscript, this); + + // Matcher for std arrays. + const auto STDArraySubscript = + cxxOperatorCallExpr( + hasOverloadedOperatorName("[]"), + hasArgument(0, hasType(cxxRecordDecl(hasName("::std::array", + hasArgument(1, SignedCharCastExpr)) + .bind("arraySubscript"); + + Finder->addMatcher(STDArraySubscript, this); } void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) { const auto *SignedCastExpression = Result.Nodes.getNodeAs("signedCastExpression"); + const auto *IntegerType = Result.Nodes.getNodeAs("integerType"); + assert(SignedCastExpression); + assert(IntegerType); // Ignore the match if we know that the signed char's value is not negative. // The potential misinterpretation happens for negative values only. @@ -135,14 +155,17 @@ void SignedCharMisuseCheck::check(const MatchFinder::MatchResult &Result) { diag(Comparison->getBeginLoc(), "comparison between 'signed char' and 'unsigned char'"); - } else if (const auto *IntegerType = - Result.Nodes.getNodeAs("integerType")) { + } else if (Result.Nodes.getNodeAs("arraySubscript")) { +diag(SignedCastExpression->getBeginLoc(), + "'signed char' to %0 conversion in array subscript; " + "consider casting to 'unsigned char' first.") +<< *IntegerType; + } else { diag(SignedCastExpression->getBeginLoc(), "'signed char' to %0 conversion; " "consider casting to 'unsigned char' first.") << *IntegerType; - } else -llvm_unreachable("Unexpected match"); + } } } // namespace bugprone diff --git a/clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst b/clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst index e3ecf75a3a52..c2bd2df062b1 100644 --- a/clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst +++ b/clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst @@ -31,11 +31,10 @@ It depends on the actual platform whether plain ``char`` is handled as ``signed by default and so it is caught by this check or not. To change the default behavior you can use ``-funsigned-char`` and ``-fsigned-char`` compilation options. -Currently, this check is limited to assignments and variable declarations, -where a ``signed char`` is assigned to an integer variable and to -equality/inequality comparisons between ``signed char`` and ``unsigned char``. -There are other use cases where the unexpected value ranges might lead to -similar bogus behavior. +Currently, this check warns in the following cases: +- ``signed char`` is assigned to a
[clang-tools-extra] fedd526 - [clang-tidy]: Add cert-str34-c alias for bugprone-signed-char-misuse.
Author: Tamás Zolnai Date: 2020-05-06T12:36:01+02:00 New Revision: fedd52682ec70fd13b08eeac99ee0954292af9da URL: https://github.com/llvm/llvm-project/commit/fedd52682ec70fd13b08eeac99ee0954292af9da DIFF: https://github.com/llvm/llvm-project/commit/fedd52682ec70fd13b08eeac99ee0954292af9da.diff LOG: [clang-tidy]: Add cert-str34-c alias for bugprone-signed-char-misuse. Summary: Added `DiagnoseSignedUnsignedCharComparisons` option to filter out unrelated use cases. The SEI cert catches explicit integer casts (two use cases), while in the case of `signed char` \ `unsigned char` comparison, we have implicit conversions. Reviewers: aaron.ballman Reviewed By: aaron.ballman Subscribers: xazax.hun, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D79334 Added: clang-tools-extra/docs/clang-tidy/checks/cert-str34-c.rst clang-tools-extra/test/clang-tidy/checkers/cert-str34-c.cpp Modified: clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp clang-tools-extra/docs/ReleaseNotes.rst clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst clang-tools-extra/docs/clang-tidy/checks/list.rst Removed: diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp index 66f00e35c7e7..3f72e5d516c5 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -29,10 +29,14 @@ static Matcher hasAnyListedName(const std::string &Names) { SignedCharMisuseCheck::SignedCharMisuseCheck(StringRef Name, ClangTidyContext *Context) : ClangTidyCheck(Name, Context), - CharTypdefsToIgnoreList(Options.get("CharTypdefsToIgnore", "")) {} + CharTypdefsToIgnoreList(Options.get("CharTypdefsToIgnore", "")), + DiagnoseSignedUnsignedCharComparisons( + Options.get("DiagnoseSignedUnsignedCharComparisons", true)) {} void SignedCharMisuseCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "CharTypdefsToIgnore", CharTypdefsToIgnoreList); + Options.store(Opts, "DiagnoseSignedUnsignedCharComparisons", +DiagnoseSignedUnsignedCharComparisons); } // Create a matcher for char -> integer cast. @@ -92,16 +96,18 @@ void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { Finder->addMatcher(Declaration, this); - // Catch signed char/unsigned char comparison. - const auto CompareOperator = - expr(binaryOperator(hasAnyOperatorName("==", "!="), - anyOf(allOf(hasLHS(SignedCharCastExpr), - hasRHS(UnSignedCharCastExpr)), -allOf(hasLHS(UnSignedCharCastExpr), - hasRHS(SignedCharCastExpr) - .bind("comparison"); - - Finder->addMatcher(CompareOperator, this); + if (DiagnoseSignedUnsignedCharComparisons) { +// Catch signed char/unsigned char comparison. +const auto CompareOperator = +expr(binaryOperator(hasAnyOperatorName("==", "!="), +anyOf(allOf(hasLHS(SignedCharCastExpr), +hasRHS(UnSignedCharCastExpr)), + allOf(hasLHS(UnSignedCharCastExpr), +hasRHS(SignedCharCastExpr) +.bind("comparison"); + +Finder->addMatcher(CompareOperator, this); + } // Catch array subscripts with signed char -> integer conversion. // Matcher for C arrays. diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h index 3fa0c9c0a088..84d3bbbf4e76 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h @@ -38,6 +38,7 @@ class SignedCharMisuseCheck : public ClangTidyCheck { const std::string &CastBindName) const; const std::string CharTypdefsToIgnoreList; + const bool DiagnoseSignedUnsignedCharComparisons; }; } // namespace bugprone diff --git a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp index 6459dcf5627d..6592d2247b56 100644 --- a/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp +++ b/clang-tools-extra/clang-tidy/cert/CERTTidyModule.cpp @@ -11,6 +11,7 @@ #include "../ClangTidyModuleRegistry.h" #include "../bugprone/BadSignalToKillThreadCheck.h" #include "../bugprone/ReservedIdentifierCheck.h" +#include "../bugprone/SignedCharMisuseCheck.h" #include "../bugprone/SpuriouslyWakeUpFunctionsCheck.h" #include
[clang-tools-extra] 04410c5 - [clang-tidy] extend bugprone-signed-char-misuse check.
Author: Tamás Zolnai Date: 2020-03-14T20:00:00+01:00 New Revision: 04410c565aa08b703ef5d11b454e7fba47163e3c URL: https://github.com/llvm/llvm-project/commit/04410c565aa08b703ef5d11b454e7fba47163e3c DIFF: https://github.com/llvm/llvm-project/commit/04410c565aa08b703ef5d11b454e7fba47163e3c.diff LOG: [clang-tidy] extend bugprone-signed-char-misuse check. Summary: Cover a new use case when using a 'signed char' as an integer might lead to issue with non-ASCII characters. Comparing a 'signed char' with an 'unsigned char' using equality / unequality operator produces an unexpected result for non-ASCII characters. Reviewers: aaron.ballman, alexfh, hokein, njames93 Reviewed By: njames93 Subscribers: xazax.hun, cfe-commits Tags: #clang, #clang-tools-extra Differential Revision: https://reviews.llvm.org/D75749 Added: Modified: clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.h clang-tools-extra/docs/clang-tidy/checks/bugprone-signed-char-misuse.rst clang-tools-extra/test/clang-tidy/checkers/bugprone-signed-char-misuse.cpp Removed: diff --git a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp index 32949a878497..732ccbc9dd2a 100644 --- a/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp +++ b/clang-tools-extra/clang-tidy/bugprone/SignedCharMisuseCheck.cpp @@ -18,6 +18,8 @@ namespace clang { namespace tidy { namespace bugprone { +static constexpr int UnsignedASCIIUpperBound = 127; + static Matcher hasAnyListedName(const std::string &Names) { const std::vector NameList = utils::options::parseStringList(Names); @@ -33,25 +35,29 @@ void SignedCharMisuseCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "CharTypdefsToIgnore", CharTypdefsToIgnoreList); } -void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { +// Create a matcher for char -> integer cast. +BindableMatcher SignedCharMisuseCheck::charCastExpression( +bool IsSigned, const Matcher &IntegerType, +const std::string &CastBindName) const { // We can ignore typedefs which are some kind of integer types // (e.g. typedef char sal_Int8). In this case, we don't need to // worry about the misinterpretation of char values. const auto IntTypedef = qualType( hasDeclaration(typedefDecl(hasAnyListedName(CharTypdefsToIgnoreList; - const auto SignedCharType = expr(hasType(qualType( - allOf(isAnyCharacter(), isSignedInteger(), unless(IntTypedef); - - const auto IntegerType = qualType(allOf(isInteger(), unless(isAnyCharacter()), - unless(booleanType( - .bind("integerType"); + auto CharTypeExpr = expr(); + if (IsSigned) { +CharTypeExpr = expr(hasType( +qualType(isAnyCharacter(), isSignedInteger(), unless(IntTypedef; + } else { +CharTypeExpr = expr(hasType(qualType( +isAnyCharacter(), unless(isSignedInteger()), unless(IntTypedef; + } - // We are interested in signed char -> integer conversion. const auto ImplicitCastExpr = - implicitCastExpr(hasSourceExpression(SignedCharType), + implicitCastExpr(hasSourceExpression(CharTypeExpr), hasImplicitDestinationType(IntegerType)) - .bind("castExpression"); + .bind(CastBindName); const auto CStyleCastExpr = cStyleCastExpr(has(ImplicitCastExpr)); const auto StaticCastExpr = cxxStaticCastExpr(has(ImplicitCastExpr)); @@ -59,44 +65,84 @@ void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { // We catch any type of casts to an integer. We need to have these cast // expressions explicitly to catch only those casts which are direct children - // of an assignment/declaration. - const auto CastExpr = expr(anyOf(ImplicitCastExpr, CStyleCastExpr, - StaticCastExpr, FunctionalCastExpr)); + // of the checked expressions. (e.g. assignment, declaration). + return expr(anyOf(ImplicitCastExpr, CStyleCastExpr, StaticCastExpr, +FunctionalCastExpr)); +} - // Catch assignments with the suspicious type conversion. - const auto AssignmentOperatorExpr = expr(binaryOperator( - hasOperatorName("="), hasLHS(hasType(IntegerType)), hasRHS(CastExpr))); +void SignedCharMisuseCheck::registerMatchers(MatchFinder *Finder) { + const auto IntegerType = + qualType(isInteger(), unless(isAnyCharacter()), unless(booleanType())) + .bind("integerType"); + const auto SignedCharCastExpr = + charCastExpression(true, IntegerType, "signedCastExpression"); + const auto UnSignedCharCastExpr = + charCastExpression(false, IntegerType, "unsignedCastExpression"); + + // Catch assignments with singed char ->