[PATCH] D39121: [clang-tidy] Misplaced Operator in Strlen in Alloc
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 25 12:38:15 PDT 2017
aaron.ballman added a comment.
I'm still a bit concerned about how to silence this diagnostic if the code is actually correct. Would it make sense to diagnose `malloc(strlen(s + 1))` but silence the diagnostic if the argument to `strlen()` is explicitly parenthesized? That means a user could silence the diagnostic by writing `malloc(strlen((s + 1)))`.
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:23
+ const auto BadUse =
+ callExpr(callee(functionDecl(hasName("strlen"))),
+ hasAnyArgument(ignoringParenImpCasts(
----------------
This should be checking for `::strlen` instead.
What about other `strlen`-like functions (`strnlen` and `strnlen_s` come to mind)?
What about wide-character strings using `wcslen`? (This might be another good check because those should be `wcslen(str) * sizeof(wchar_t)` instead of just `wcslen(str)`.)
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:37
+ Finder->addMatcher(callExpr(callee(functionDecl(
+ anyOf(hasName("malloc"), hasName("alloca")))),
+ hasArgument(0, BadArg))
----------------
`::malloc` (etc), here and below.
The reason is because a pathological case might have these functions inside of a namespace, so you want to ensure this only checks against the global namespace.
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:54
+
+ const std::string LHSText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(BinOp->getLHS()->getSourceRange()),
----------------
Assign into a `StringRef` to avoid a needless copy operation (same below).
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:63
+ StrLen->getSourceRange(),
+ "strlen(" + LHSText + ")" +
+ ((BinOp->getOpcode() == BO_Add) ? " + " : " - ") + RHSText);
----------------
This should use a `Twine` to avoid needless allocations and copies.
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:64
+ "strlen(" + LHSText + ")" +
+ ((BinOp->getOpcode() == BO_Add) ? " + " : " - ") + RHSText);
+
----------------
`BinOp->getOpcode()` will always be `BO_Add`, correct? That's the only binary operator you're matching against.
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:66
+
+ diag(Alloc->getLocStart(), "Binary operator %0 %1 is inside strlen")
+ << ((BinOp->getOpcode() == BO_Add) ? "+" : "-") << BinOp->getRHS()
----------------
I'm not keen on this wording as it doesn't tell the user what's wrong with their code; further, it doesn't tell the user how to silence the warning if the code is correct. Perhaps:
"addition operator is applied to the argument to `strlen` instead of the result; surround the addition subexpression with parentheses to silence this warning"
================
Comment at: clang-tidy/bugprone/MisplacedOperatorInStrlenInAllocCheck.cpp:67
+ diag(Alloc->getLocStart(), "Binary operator %0 %1 is inside strlen")
+ << ((BinOp->getOpcode() == BO_Add) ? "+" : "-") << BinOp->getRHS()
+ << Hint;
----------------
`+` is the only binop you match.
================
Comment at: docs/ReleaseNotes.rst:63
+
+ Finds cases a value is added to or subtracted from the string in the parameter
+ of ``strlen()`` method instead of to the result and use its return value as an
----------------
This comment is no longer accurate and should be reworded.
================
Comment at: docs/clang-tidy/checks/bugprone-misplaced-operator-in-strlen-in-alloc.rst:6
+
+Finds cases a value is added to or subtracted from the string in the parameter
+of ``strlen()`` method instead of to the result and use its return value as an
----------------
This comment is no longer accurate and should be reworded.
================
Comment at: test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp:36
+void intentional1(char *name) {
+ char *new_name = (char*) malloc(strlen(name + 1) + 1);
+}
----------------
This should have some comments that explain why it's valid and it should be clearly spelled out in the docs.
================
Comment at: test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp:39
+
+
+void intentional2(char *name) {
----------------
Spurious newline.
================
Comment at: test/clang-tidy/bugprone-misplaced-operator-in-strlen-in-alloc.cpp:40
+
+void intentional2(char *name) {
+ char *new_name = (char*) malloc(strlen(name + 2));
----------------
This should have some comments that explain why it's valid and it should be clearly spelled out in the docs.
https://reviews.llvm.org/D39121
More information about the cfe-commits
mailing list