[PATCH] D52670: [clang-tidy] Add new 'readability-uppercase-literal-suffix' check (CERT DCL16-C, MISRA C:2012, 7.3, MISRA C++:2008, 2-13-4)
Jonas Toth via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sat Sep 29 03:43:07 PDT 2018
JonasToth added a comment.
Thanks for working on this!
Related as well: http://www.codingstandard.com/rule/4-2-1-ensure-that-the-u-suffix-is-applied-to-a-literal-used-in-a-context-requiring-an-unsigned-integral-expression/
I think its wort a alias is hicpp as well
Please add tests that use user-defined literals and ensure there are no collision and that they are not diagnosed. Some examples: https://en.cppreference.com/w/cpp/language/user_literal
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:26
+struct IntegerLiteral {
+ using ClangType = clang::IntegerLiteral;
+ static constexpr llvm::StringLiteral Name = llvm::StringLiteral("integer");
----------------
maybe `ClangType` is not a good name, how about just `type` to be consistent with e.g. std::vector convention.
The use-case in your template makes it clear, that we are talking about `LiteralType`s.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:33
+};
+constexpr llvm::StringLiteral IntegerLiteral::Name;
+constexpr llvm::StringLiteral IntegerLiteral::SkipFirst;
----------------
why are these declarations necessary?
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:42
+ // What should be skipped before looking for the Suffixes?
+ // Hexadecimal floating-point literals: skip until exponent first.
+ static constexpr llvm::StringLiteral SkipFirst = llvm::StringLiteral("pP");
----------------
The second line of the comment is slightly confusing, please make a full sentence out of it.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:52
+AST_MATCHER(clang::IntegerLiteral, intHasSuffix) {
+ const auto *T = dyn_cast<BuiltinType>(Node.getType().getTypePtr());
+ if (!T)
----------------
as it hit me in my check: what about `(1)ul`? Is this syntactically correct and should be diagnosed too? (Please add tests if so).
In this case it should be `Note.getType().IgnoreParens().getTypePtr())`.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:53
+ const auto *T = dyn_cast<BuiltinType>(Node.getType().getTypePtr());
+ if (!T)
+ return false;
----------------
Maybe the if could init `T`? It would require a second `return false;` if i am not mistaken, but looks more regular to me. No strong opinion from my side.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:69
+AST_MATCHER(clang::FloatingLiteral, fpHasSuffix) {
+ const auto *T = dyn_cast<BuiltinType>(Node.getType().getTypePtr());
+ if (!T)
----------------
Same comment as above
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:85
+template <typename LiteralType>
+llvm::Optional<UppercaseLiteralSuffixCheck::NewSuffix>
+UppercaseLiteralSuffixCheck::shouldReplaceLiteralSuffix(
----------------
These types get really long. Is it possible to put `NewSuffix` into the anonymous namespace as well?
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:90
+
+ NewSuffix S;
+
----------------
GIven that this variable is used mutliple times in a longer function, i feel it shuold get a longer, more descriptive name
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:95
+ // Get the whole Integer Literal from the source buffer.
+ const StringRef LiteralSourceText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(S.Range), SM, getLangOpts());
----------------
Please check if the source text could be retrieved, with a final `bool` parameter, thats in/out and at least `assert` on that.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:106
+ Skip = LiteralSourceText.find_first_of(LiteralType::SkipFirst);
+ if (Skip == StringRef::npos) // We could be in non-hexadecimal fp literal.
+ Skip = 0;
----------------
please use `flloating-point` instead of `fp` (same in other places)
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:129
+ if (S.OldSuffix == S.NewSuffix)
+ return llvm::None; // The suffix was already fully uppercase.
+
----------------
Could this function return a `Optional<FixitHint>`? That would include the range and the relacement-text. I feel that is would simplify the code, especially the amount of state that one has to keep track of.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:135
+void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) {
+ Finder->addMatcher(
+ stmt(integerLiteral(intHasSuffix())).bind(IntegerLiteral::Name), this);
----------------
I think you can merge this matcher to `stmt(eachOf(integerLiteral(intHasSuffix()).bind(), floatLiteral(fpHasSuffix()).bind()))`
`eachOf` because we want to match all, and not short-circuit.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:152
+ // Ignore literals that aren't fully written in the source code.
+ if (LiteralLocation.isMacroID() ||
+ Result.SourceManager->isMacroBodyExpansion(LiteralLocation) ||
----------------
Wouldn't it make sense to warn for the literals in macros?
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:165
+
+ diag(LiteralLocation, "%0 literal suffix '%1' is not upper-case")
+ << LiteralType::Name << S.OldSuffix
----------------
Lets move this `diag` into the true branch of the if stmt and drop the ´else`.
================
Comment at: clang-tidy/readability/UppercaseLiteralSuffixCheck.cpp:165
+
+ diag(LiteralLocation, "%0 literal suffix '%1' is not upper-case")
+ << LiteralType::Name << S.OldSuffix
----------------
JonasToth wrote:
> Lets move this `diag` into the true branch of the if stmt and drop the ´else`.
I think the warning should point at the suffix, which can be retrieved from the replacement range. Then you don't need to include the suffix itself in the diagnostic
================
Comment at: docs/ReleaseNotes.rst:96
+- New alias :doc:`cert-dcl16-c
+ <clang-tidy/checks/cert-dcl16-c>` to :doc:`readability-uppercase-literal-suffix
----------------
lebedev.ri wrote:
> Eugene.Zelenko wrote:
> > Please move alias after new checks.
> BTW, is there some tool to actually add this alias? I didn't find it, and had to do it by hand..
So far there is nothing, but would be a nice addition :)
================
Comment at: docs/clang-tidy/checks/readability-uppercase-literal-suffix.rst:9
+Detects when the integral literal or floating point (decimal or hexadecimal)
+literal has non-uppercase suffix, and suggests to make the suffix uppercase,
+with fix-it.
----------------
I feel that the sentence could be improved a bit.
- `literal has *a* non-uppercase`
- `suffix and provides a fix-it-hint with the uppercase suffix.` (i think the comma after `suffix` is not necessary)
================
Comment at: test/clang-tidy/readability-uppercase-literal-suffix-floating-point.cpp:26
+ static_assert(is_same<decltype(v0), const double>::value, "");
+ static_assert(v0 == 1, "");
+
----------------
nit: comparing int to double, same below.
================
Comment at: test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp:6
+
+template <class T, T v>
+struct integral_constant {
----------------
Please remove the TMP duplication and make a extra header for that, that is then included by these tests.
================
Comment at: test/clang-tidy/readability-uppercase-literal-suffix-hexadecimal-floating-point.cpp:31
+ static constexpr auto v1 = 0xfp0f;
+ // CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal suffix 'f' is not upper-case [readability-uppercase-literal-suffix]
+ // CHECK-MESSAGES-NEXT: static constexpr auto v1 = 0xfp0f;
----------------
you can safely drop the `[readability-..]` part of the warning message. It will just make problems if the check should be renamed at some point.
Repository:
rCTE Clang Tools Extra
https://reviews.llvm.org/D52670
More information about the cfe-commits
mailing list