[clang-tidy] Re-commit: Add new 'readability-uppercase-literal-suffix' check (CERT DCL16-C, MISRA C:2012, 7.3, MISRA C++:2008, 2-13-4)

Summary:
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.

All valid combinations of suffixes are supported.

```
  auto x = 1;  // OK, no suffix.

  auto x = 1u; // warning: integer literal suffix 'u' is not upper-case

  auto x = 1U; // OK, suffix is uppercase.

  ...
```

This is a re-commit, the original was reverted by me in
rL345305 due to discovered bugs. (implicit code, template instantiation)
Tests were added, and the bugs were fixed.
I'm unable to find any further bugs, hopefully there aren't any..

References:
* [[ https://wiki.sei.cmu.edu/confluence/pages/viewpage.action?pageId=87152241 | CERT DCL16-C ]]
* MISRA C:2012, 7.3 - The lowercase character "l" shall not be used in a literal suffix
* MISRA C++:2008, 2-13-4 - Literal suffixes shall be upper case

Reviewers: JonasToth, aaron.ballman, alexfh, hokein, xazax.hun

Reviewed By: aaron.ballman

Subscribers: Eugene.Zelenko, mgorny, rnkovacs, cfe-commits

Tags: #clang-tools-extra

Differential Revision: https://reviews.llvm.org/D52670

llvm-svn: 345381
This commit is contained in:
Roman Lebedev 2018-10-26 13:09:27 +00:00
parent 40ccbd315d
commit 08701ec753
24 changed files with 1479 additions and 19 deletions

View File

@ -16,6 +16,7 @@
#include "../misc/StaticAssertCheck.h"
#include "../misc/ThrowByValueCatchByReferenceCheck.h"
#include "../performance/MoveConstructorInitCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
#include "CommandProcessorCheck.h"
#include "DontModifyStdNamespaceCheck.h"
#include "FloatLoopCounter.h"
@ -65,6 +66,8 @@ public:
// C checkers
// DCL
CheckFactories.registerCheck<misc::StaticAssertCheck>("cert-dcl03-c");
CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>(
"cert-dcl16-c");
// ENV
CheckFactories.registerCheck<CommandProcessorCheck>("cert-env33-c");
// FLP
@ -78,6 +81,13 @@ public:
CheckFactories.registerCheck<ProperlySeededRandomGeneratorCheck>(
"cert-msc32-c");
}
ClangTidyOptions getModuleOptions() override {
ClangTidyOptions Options;
ClangTidyOptions::OptionMap &Opts = Options.CheckOptions;
Opts["cert-dcl16-c.NewSuffixes"] = "L;LL;LU;LLU";
return Options;
}
};
} // namespace cert

View File

@ -24,5 +24,6 @@ add_clang_library(clangTidyCERTModule
clangTidyGoogleModule
clangTidyMiscModule
clangTidyPerformanceModule
clangTidyReadabilityModule
clangTidyUtils
)

View File

@ -35,6 +35,7 @@
#include "../readability/BracesAroundStatementsCheck.h"
#include "../readability/FunctionSizeCheck.h"
#include "../readability/IdentifierNamingCheck.h"
#include "../readability/UppercaseLiteralSuffixCheck.h"
#include "ExceptionBaseclassCheck.h"
#include "MultiwayPathsCoveredCheck.h"
#include "NoAssemblerCheck.h"
@ -100,6 +101,8 @@ public:
"hicpp-use-nullptr");
CheckFactories.registerCheck<modernize::UseOverrideCheck>(
"hicpp-use-override");
CheckFactories.registerCheck<readability::UppercaseLiteralSuffixCheck>(
"hicpp-uppercase-literal-suffix");
CheckFactories.registerCheck<cppcoreguidelines::ProTypeVarargCheck>(
"hicpp-vararg");
}

View File

@ -31,6 +31,7 @@ add_clang_library(clangTidyReadabilityModule
StaticDefinitionInAnonymousNamespaceCheck.cpp
StringCompareCheck.cpp
UniqueptrDeleteReleaseCheck.cpp
UppercaseLiteralSuffixCheck.cpp
LINK_LIBS
clangAST

View File

@ -9,6 +9,7 @@
#include "IdentifierNamingCheck.h"
#include "../utils/ASTUtils.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PPCallbacks.h"
@ -681,25 +682,7 @@ static void addUsage(IdentifierNamingCheck::NamingCheckFailureMap &Failures,
if (!Failure.ShouldFix)
return;
// Check if the range is entirely contained within a macro argument.
SourceLocation MacroArgExpansionStartForRangeBegin;
SourceLocation MacroArgExpansionStartForRangeEnd;
bool RangeIsEntirelyWithinMacroArgument =
SourceMgr &&
SourceMgr->isMacroArgExpansion(Range.getBegin(),
&MacroArgExpansionStartForRangeBegin) &&
SourceMgr->isMacroArgExpansion(Range.getEnd(),
&MacroArgExpansionStartForRangeEnd) &&
MacroArgExpansionStartForRangeBegin == MacroArgExpansionStartForRangeEnd;
// Check if the range contains any locations from a macro expansion.
bool RangeContainsMacroExpansion = RangeIsEntirelyWithinMacroArgument ||
Range.getBegin().isMacroID() ||
Range.getEnd().isMacroID();
bool RangeCanBeFixed =
RangeIsEntirelyWithinMacroArgument || !RangeContainsMacroExpansion;
Failure.ShouldFix = RangeCanBeFixed;
Failure.ShouldFix = utils::rangeCanBeFixed(Range, SourceMgr);
}
/// Convenience method when the usage to be added is a NamedDecl

View File

@ -38,6 +38,7 @@
#include "StaticDefinitionInAnonymousNamespaceCheck.h"
#include "StringCompareCheck.h"
#include "UniqueptrDeleteReleaseCheck.h"
#include "UppercaseLiteralSuffixCheck.h"
namespace clang {
namespace tidy {
@ -102,6 +103,8 @@ public:
"readability-simplify-boolean-expr");
CheckFactories.registerCheck<UniqueptrDeleteReleaseCheck>(
"readability-uniqueptr-delete-release");
CheckFactories.registerCheck<UppercaseLiteralSuffixCheck>(
"readability-uppercase-literal-suffix");
}
};

View File

@ -0,0 +1,238 @@
//===--- UppercaseLiteralSuffixCheck.cpp - clang-tidy ---------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "UppercaseLiteralSuffixCheck.h"
#include "../utils/ASTUtils.h"
#include "../utils/OptionsUtils.h"
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallString.h"
using namespace clang::ast_matchers;
namespace clang {
namespace tidy {
namespace readability {
namespace {
struct IntegerLiteralCheck {
using type = clang::IntegerLiteral;
static constexpr llvm::StringLiteral Name = llvm::StringLiteral("integer");
// What should be skipped before looking for the Suffixes? (Nothing here.)
static constexpr llvm::StringLiteral SkipFirst = llvm::StringLiteral("");
// Suffix can only consist of 'u' and 'l' chars, and can be a complex number
// ('i', 'j'). In MS compatibility mode, suffixes like i32 are supported.
static constexpr llvm::StringLiteral Suffixes =
llvm::StringLiteral("uUlLiIjJ");
};
constexpr llvm::StringLiteral IntegerLiteralCheck::Name;
constexpr llvm::StringLiteral IntegerLiteralCheck::SkipFirst;
constexpr llvm::StringLiteral IntegerLiteralCheck::Suffixes;
struct FloatingLiteralCheck {
using type = clang::FloatingLiteral;
static constexpr llvm::StringLiteral Name =
llvm::StringLiteral("floating point");
// C++17 introduced hexadecimal floating-point literals, and 'f' is both a
// valid hexadecimal digit in a hex float literal and a valid floating-point
// literal suffix.
// So we can't just "skip to the chars that can be in the suffix".
// Since the exponent ('p'/'P') is mandatory for hexadecimal floating-point
// literals, we first skip everything before the exponent.
static constexpr llvm::StringLiteral SkipFirst = llvm::StringLiteral("pP");
// Suffix can only consist of 'f', 'l', "f16", 'h', 'q' chars,
// and can be a complex number ('i', 'j').
static constexpr llvm::StringLiteral Suffixes =
llvm::StringLiteral("fFlLhHqQiIjJ");
};
constexpr llvm::StringLiteral FloatingLiteralCheck::Name;
constexpr llvm::StringLiteral FloatingLiteralCheck::SkipFirst;
constexpr llvm::StringLiteral FloatingLiteralCheck::Suffixes;
struct NewSuffix {
SourceRange LiteralLocation;
StringRef OldSuffix;
llvm::Optional<FixItHint> FixIt;
};
llvm::Optional<SourceLocation> GetMacroAwareLocation(SourceLocation Loc,
const SourceManager &SM) {
// Do nothing if the provided location is invalid.
if (Loc.isInvalid())
return llvm::None;
// Look where the location was *actually* written.
SourceLocation SpellingLoc = SM.getSpellingLoc(Loc);
if (SpellingLoc.isInvalid())
return llvm::None;
return SpellingLoc;
}
llvm::Optional<SourceRange> GetMacroAwareSourceRange(SourceRange Loc,
const SourceManager &SM) {
llvm::Optional<SourceLocation> Begin =
GetMacroAwareLocation(Loc.getBegin(), SM);
llvm::Optional<SourceLocation> End = GetMacroAwareLocation(Loc.getEnd(), SM);
if (!Begin || !End)
return llvm::None;
return SourceRange(*Begin, *End);
}
llvm::Optional<std::string>
getNewSuffix(llvm::StringRef OldSuffix,
const std::vector<std::string> &NewSuffixes) {
// If there is no config, just uppercase the entirety of the suffix.
if (NewSuffixes.empty())
return OldSuffix.upper();
// Else, find matching suffix, case-*insensitive*ly.
auto NewSuffix = llvm::find_if(
NewSuffixes, [OldSuffix](const std::string &PotentialNewSuffix) {
return OldSuffix.equals_lower(PotentialNewSuffix);
});
// Have a match, return it.
if (NewSuffix != NewSuffixes.end())
return *NewSuffix;
// Nope, I guess we have to keep it as-is.
return llvm::None;
}
template <typename LiteralType>
llvm::Optional<NewSuffix>
shouldReplaceLiteralSuffix(const Expr &Literal,
const std::vector<std::string> &NewSuffixes,
const SourceManager &SM, const LangOptions &LO) {
NewSuffix ReplacementDsc;
const auto &L = cast<typename LiteralType::type>(Literal);
// The naive location of the literal. Is always valid.
ReplacementDsc.LiteralLocation = L.getSourceRange();
// Was this literal fully spelled or is it a product of macro expansion?
bool RangeCanBeFixed =
utils::rangeCanBeFixed(ReplacementDsc.LiteralLocation, &SM);
// The literal may have macro expansion, we need the final expanded src range.
llvm::Optional<SourceRange> Range =
GetMacroAwareSourceRange(ReplacementDsc.LiteralLocation, SM);
if (!Range)
return llvm::None;
if (RangeCanBeFixed)
ReplacementDsc.LiteralLocation = *Range;
// Else keep the naive literal location!
// Get the whole literal from the source buffer.
bool Invalid;
const StringRef LiteralSourceText = Lexer::getSourceText(
CharSourceRange::getTokenRange(*Range), SM, LO, &Invalid);
assert(!Invalid && "Failed to retrieve the source text.");
size_t Skip = 0;
// Do we need to ignore something before actually looking for the suffix?
if (!LiteralType::SkipFirst.empty()) {
// E.g. we can't look for 'f' suffix in hexadecimal floating-point literals
// until after we skip to the exponent (which is mandatory there),
// because hex-digit-sequence may contain 'f'.
Skip = LiteralSourceText.find_first_of(LiteralType::SkipFirst);
// We could be in non-hexadecimal floating-point literal, with no exponent.
if (Skip == StringRef::npos)
Skip = 0;
}
// Find the beginning of the suffix by looking for the first char that is
// one of these chars that can be in the suffix, potentially starting looking
// in the exponent, if we are skipping hex-digit-sequence.
Skip = LiteralSourceText.find_first_of(LiteralType::Suffixes, /*From=*/Skip);
// We can't check whether the *Literal has any suffix or not without actually
// looking for the suffix. So it is totally possible that there is no suffix.
if (Skip == StringRef::npos)
return llvm::None;
// Move the cursor in the source range to the beginning of the suffix.
Range->setBegin(Range->getBegin().getLocWithOffset(Skip));
// And in our textual representation too.
ReplacementDsc.OldSuffix = LiteralSourceText.drop_front(Skip);
assert(!ReplacementDsc.OldSuffix.empty() &&
"We still should have some chars left.");
// And get the replacement suffix.
llvm::Optional<std::string> NewSuffix =
getNewSuffix(ReplacementDsc.OldSuffix, NewSuffixes);
if (!NewSuffix || ReplacementDsc.OldSuffix == *NewSuffix)
return llvm::None; // The suffix was already the way it should be.
if (RangeCanBeFixed)
ReplacementDsc.FixIt = FixItHint::CreateReplacement(*Range, *NewSuffix);
return ReplacementDsc;
}
} // namespace
UppercaseLiteralSuffixCheck::UppercaseLiteralSuffixCheck(
StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
NewSuffixes(
utils::options::parseStringList(Options.get("NewSuffixes", ""))) {}
void UppercaseLiteralSuffixCheck::storeOptions(
ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "NewSuffixes",
utils::options::serializeStringList(NewSuffixes));
}
void UppercaseLiteralSuffixCheck::registerMatchers(MatchFinder *Finder) {
// Sadly, we can't check whether the literal has sufix or not.
// E.g. i32 suffix still results in 'BuiltinType::Kind::Int'.
// And such an info is not stored in the *Literal itself.
Finder->addMatcher(
stmt(allOf(eachOf(integerLiteral().bind(IntegerLiteralCheck::Name),
floatLiteral().bind(FloatingLiteralCheck::Name)),
unless(anyOf(hasParent(userDefinedLiteral()),
hasAncestor(isImplicit()),
hasAncestor(substNonTypeTemplateParmExpr()))))),
this);
}
template <typename LiteralType>
bool UppercaseLiteralSuffixCheck::checkBoundMatch(
const MatchFinder::MatchResult &Result) {
const auto *Literal =
Result.Nodes.getNodeAs<typename LiteralType::type>(LiteralType::Name);
if (!Literal)
return false;
// We won't *always* want to diagnose.
// We might have a suffix that is already uppercase.
if (auto Details = shouldReplaceLiteralSuffix<LiteralType>(
*Literal, NewSuffixes, *Result.SourceManager, getLangOpts())) {
auto Complaint = diag(Details->LiteralLocation.getBegin(),
"%0 literal has suffix '%1', which is not uppercase")
<< LiteralType::Name << Details->OldSuffix;
if (Details->FixIt) // Similarly, a fix-it is not always possible.
Complaint << *(Details->FixIt);
}
return true;
}
void UppercaseLiteralSuffixCheck::check(
const MatchFinder::MatchResult &Result) {
if (checkBoundMatch<IntegerLiteralCheck>(Result))
return; // If it *was* IntegerLiteral, don't check for FloatingLiteral.
checkBoundMatch<FloatingLiteralCheck>(Result);
}
} // namespace readability
} // namespace tidy
} // namespace clang

View File

@ -0,0 +1,44 @@
//===--- UppercaseLiteralSuffixCheck.h - clang-tidy -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UPPERCASELITERALSUFFIXCHECK_H
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UPPERCASELITERALSUFFIXCHECK_H
#include "../ClangTidy.h"
#include "../utils/OptionsUtils.h"
namespace clang {
namespace tidy {
namespace readability {
/// Detects when the integral literal or floating point literal has
/// non-uppercase suffix, and suggests to make the suffix uppercase.
/// Alternatively, a list of destination suffixes can be provided.
///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/readability-uppercase-literal-suffix.html
class UppercaseLiteralSuffixCheck : public ClangTidyCheck {
public:
UppercaseLiteralSuffixCheck(StringRef Name, ClangTidyContext *Context);
void registerMatchers(ast_matchers::MatchFinder *Finder) override;
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
private:
template <typename LiteralType>
bool checkBoundMatch(const ast_matchers::MatchFinder::MatchResult &Result);
const std::vector<std::string> NewSuffixes;
};
} // namespace readability
} // namespace tidy
} // namespace clang
#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_UPPERCASELITERALSUFFIXCHECK_H

View File

@ -67,6 +67,32 @@ bool exprHasBitFlagWithSpelling(const Expr *Flags, const SourceManager &SM,
return true;
}
bool rangeIsEntirelyWithinMacroArgument(SourceRange Range,
const SourceManager *SM) {
// Check if the range is entirely contained within a macro argument.
SourceLocation MacroArgExpansionStartForRangeBegin;
SourceLocation MacroArgExpansionStartForRangeEnd;
bool RangeIsEntirelyWithinMacroArgument =
SM &&
SM->isMacroArgExpansion(Range.getBegin(),
&MacroArgExpansionStartForRangeBegin) &&
SM->isMacroArgExpansion(Range.getEnd(),
&MacroArgExpansionStartForRangeEnd) &&
MacroArgExpansionStartForRangeBegin == MacroArgExpansionStartForRangeEnd;
return RangeIsEntirelyWithinMacroArgument;
}
bool rangeContainsMacroExpansion(SourceRange Range, const SourceManager *SM) {
return rangeIsEntirelyWithinMacroArgument(Range, SM) ||
Range.getBegin().isMacroID() || Range.getEnd().isMacroID();
}
bool rangeCanBeFixed(SourceRange Range, const SourceManager *SM) {
return utils::rangeIsEntirelyWithinMacroArgument(Range, SM) ||
!utils::rangeContainsMacroExpansion(Range, SM);
}
} // namespace utils
} // namespace tidy
} // namespace clang

View File

@ -27,6 +27,18 @@ bool IsBinaryOrTernary(const Expr *E);
bool exprHasBitFlagWithSpelling(const Expr *Flags, const SourceManager &SM,
const LangOptions &LangOpts,
StringRef FlagName);
// Check if the range is entirely contained within a macro argument.
bool rangeIsEntirelyWithinMacroArgument(SourceRange Range,
const SourceManager *SM);
// Check if the range contains any locations from a macro expansion.
bool rangeContainsMacroExpansion(SourceRange Range, const SourceManager *SM);
// Can a fix-it be issued for this whole Range?
// FIXME: false-negative if the entire range is fully expanded from a macro.
bool rangeCanBeFixed(SourceRange Range, const SourceManager *SM);
} // namespace utils
} // namespace tidy
} // namespace clang

View File

@ -142,12 +142,30 @@ Improvements to clang-tidy
Detects usage of magic numbers, numbers that are used as literals instead of
introduced via constants or symbols.
- New :doc:`readability-uppercase-literal-suffix
<clang-tidy/checks/readability-uppercase-literal-suffix>` check.
Detects when the integral literal or floating point literal has non-uppercase
suffix, and suggests to make the suffix uppercase. The list of destination
suffixes can be optionally provided.
- New alias :doc:`cert-dcl16-c
<clang-tidy/checks/cert-dcl16-c>` to :doc:`readability-uppercase-literal-suffix
<clang-tidy/checks/readability-uppercase-literal-suffix>`
added.
- New alias :doc:`cppcoreguidelines-non-private-member-variables-in-classes
<clang-tidy/checks/cppcoreguidelines-non-private-member-variables-in-classes>`
to :doc:`misc-non-private-member-variables-in-classes
<clang-tidy/checks/misc-non-private-member-variables-in-classes>`
added.
- New alias :doc:`hicpp-uppercase-literal-suffix
<clang-tidy/checks/hicpp-uppercase-literal-suffix>` to
:doc:`readability-uppercase-literal-suffix
<clang-tidy/checks/readability-uppercase-literal-suffix>`
added.
- The :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability-redundant-smartptr-get>` check does not warn
about calls inside macros anymore by default.

View File

@ -0,0 +1,9 @@
.. title:: clang-tidy - cert-dcl16-c
.. meta::
:http-equiv=refresh: 5;URL=readability-uppercase-literal-suffix.html
cert-dcl16-c
============
The cert-dcl16-c check is an alias, please see
`readability-uppercase-literal-suffix <readability-uppercase-literal-suffix.html>`_ for more information.

View File

@ -0,0 +1,9 @@
.. title:: clang-tidy - hicpp-uppercase-literal-suffix
.. meta::
:http-equiv=refresh: 5;URL=readability-uppercase-literal-suffix.html
hicpp-uppercase-literal-suffix
==============================
The hicpp-uppercase-literal-suffix check is an alias, please see
`readability-uppercase-literal-suffix <readability-uppercase-literal-suffix.html>`_ for more information.

View File

@ -66,6 +66,7 @@ Clang-Tidy Checks
bugprone-use-after-move
bugprone-virtual-near-miss
cert-dcl03-c (redirects to misc-static-assert) <cert-dcl03-c>
cert-dcl16-c (redirects to readability-uppercase-literal-suffix) <cert-dcl16-c>
cert-dcl21-cpp
cert-dcl50-cpp
cert-dcl54-cpp (redirects to misc-new-delete-overloads) <cert-dcl54-cpp>
@ -158,6 +159,7 @@ Clang-Tidy Checks
hicpp-use-nullptr (redirects to modernize-use-nullptr) <hicpp-use-nullptr>
hicpp-use-override (redirects to modernize-use-override) <hicpp-use-override>
hicpp-vararg (redirects to cppcoreguidelines-pro-type-vararg) <hicpp-vararg>
hicpp-uppercase-literal-suffix (redirects to readability-uppercase-literal-suffix) <hicpp-uppercase-literal-suffix>
llvm-header-guard
llvm-include-order
llvm-namespace-comment
@ -249,4 +251,5 @@ Clang-Tidy Checks
readability-static-definition-in-anonymous-namespace
readability-string-compare
readability-uniqueptr-delete-release
readability-uppercase-literal-suffix
zircon-temporary-objects

View File

@ -0,0 +1,42 @@
.. title:: clang-tidy - readability-uppercase-literal-suffix
readability-uppercase-literal-suffix
====================================
`cert-dcl16-c` redirects here as an alias for this check.
By default, only the suffixes that begin with 'l' ("l", "ll", "lu", "llu",
but not "u", "ul", "ull") are diagnosed by that alias.
`hicpp-uppercase-literal-suffix` redirects here as an alias for this check.
Detects when the integral literal or floating point (decimal or hexadecimal)
literal has a non-uppercase suffix and provides a fix-it-hint
with the uppercase suffix.
All valid combinations of suffixes are supported.
.. code:: c
auto x = 1; // OK, no suffix.
auto x = 1u; // warning: integer literal suffix 'u' is not upper-case
auto x = 1U; // OK, suffix is uppercase.
...
Optionally, a list of the destination suffixes can be provided.
When the suffix is found, a case-insensitive lookup in that list is made,
and if a replacement is found that is different from the current suffix,
then the diagnostic is issued. This allows for fine-grained control of
what suffixes to consider and what their replacements should be.
For example, given a list ``L;uL``:
* ``l`` -> ``L``
* ``L`` will be kept as is.
* ``ul`` -> ``uL``
* ``Ul`` -> ``uL``
* ``UL`` -> ``uL``
* ``uL`` will be kept as is.
* ``ull`` will be kept as is, since it is not in the list
* and so on.

View File

@ -0,0 +1,159 @@
// RUN: %check_clang_tidy %s cert-dcl16-c %t -- -- -I %S
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -fix -- -I %S
// RUN: clang-tidy %t.cpp -checks='-*,cert-dcl16-c' -warnings-as-errors='-*,cert-dcl16-c' -- -I %S
#include "readability-uppercase-literal-suffix.h"
void integer_suffix() {
static constexpr auto v0 = __LINE__; // synthetic
static_assert(v0 == 9 || v0 == 5, "");
static constexpr auto v1 = __cplusplus; // synthetic, long
static constexpr auto v2 = 1; // no literal
static_assert(is_same<decltype(v2), const int>::value, "");
static_assert(v2 == 1, "");
// Unsigned
static constexpr auto v3 = 1u;
static_assert(is_same<decltype(v3), const unsigned int>::value, "");
static_assert(v3 == 1, "");
static constexpr auto v4 = 1U; // OK.
static_assert(is_same<decltype(v4), const unsigned int>::value, "");
static_assert(v4 == 1, "");
// Long
static constexpr auto v5 = 1l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v5 = 1L;
static_assert(is_same<decltype(v5), const long>::value, "");
static_assert(v5 == 1, "");
static constexpr auto v6 = 1L; // OK.
static_assert(is_same<decltype(v6), const long>::value, "");
static_assert(v6 == 1, "");
// Long Long
static constexpr auto v7 = 1ll;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}}
// CHECK-FIXES: static constexpr auto v7 = 1LL;
static_assert(is_same<decltype(v7), const long long>::value, "");
static_assert(v7 == 1, "");
static constexpr auto v8 = 1LL; // OK.
static_assert(is_same<decltype(v8), const long long>::value, "");
static_assert(v8 == 1, "");
// Unsigned Long
static constexpr auto v9 = 1ul;
static_assert(is_same<decltype(v9), const unsigned long>::value, "");
static_assert(v9 == 1, "");
static constexpr auto v10 = 1uL;
static_assert(is_same<decltype(v10), const unsigned long>::value, "");
static_assert(v10 == 1, "");
static constexpr auto v11 = 1Ul;
static_assert(is_same<decltype(v11), const unsigned long>::value, "");
static_assert(v11 == 1, "");
static constexpr auto v12 = 1UL; // OK.
static_assert(is_same<decltype(v12), const unsigned long>::value, "");
static_assert(v12 == 1, "");
// Long Unsigned
static constexpr auto v13 = 1lu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v13 = 1LU;
static_assert(is_same<decltype(v13), const unsigned long>::value, "");
static_assert(v13 == 1, "");
static constexpr auto v14 = 1Lu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v14 = 1LU;
static_assert(is_same<decltype(v14), const unsigned long>::value, "");
static_assert(v14 == 1, "");
static constexpr auto v15 = 1lU;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v15 = 1LU;
static_assert(is_same<decltype(v15), const unsigned long>::value, "");
static_assert(v15 == 1, "");
static constexpr auto v16 = 1LU; // OK.
static_assert(is_same<decltype(v16), const unsigned long>::value, "");
static_assert(v16 == 1, "");
// Unsigned Long Long
static constexpr auto v17 = 1ull;
static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
static_assert(v17 == 1, "");
static constexpr auto v18 = 1uLL;
static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
static_assert(v18 == 1, "");
static constexpr auto v19 = 1Ull;
static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
static_assert(v19 == 1, "");
static constexpr auto v20 = 1ULL; // OK.
static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
static_assert(v20 == 1, "");
// Long Long Unsigned
static constexpr auto v21 = 1llu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v21 = 1LLU;
static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
static_assert(v21 == 1, "");
static constexpr auto v22 = 1LLu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v22 = 1LLU;
static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
static_assert(v22 == 1, "");
static constexpr auto v23 = 1llU;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v23 = 1LLU;
static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
static_assert(v23 == 1, "");
static constexpr auto v24 = 1LLU; // OK.
static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
static_assert(v24 == 1, "");
}

View File

@ -0,0 +1,30 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -std=cl2.0 -x cl
#pragma OPENCL EXTENSION cl_khr_fp16 : enable
void floating_point_half_suffix() {
static half v0 = 0x0p0; // no literal
// half
static half v2 = 1.h;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: floating point literal has suffix 'h', which is not uppercase
// CHECK-MESSAGES-NEXT: static half v2 = 1.h;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}H{{$}}
// CHECK-HIXES: static half v2 = 1.H;
static half v3 = 1.e0h;
// CHECK-MESSAGES: :[[@LINE-1]]:20: warning: floating point literal has suffix 'h', which is not uppercase
// CHECK-MESSAGES-NEXT: static half v3 = 1.e0h;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}H{{$}}
// CHECK-HIXES: static half v3 = 1.e0H;
static half v4 = 1.H; // OK.
static half v5 = 1.e0H; // OK.
}

View File

@ -0,0 +1,198 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S
#include "readability-uppercase-literal-suffix.h"
void floating_point_suffix() {
static constexpr auto v0 = 1.; // no literal
static_assert(is_same<decltype(v0), const double>::value, "");
static_assert(v0 == 1., "");
static constexpr auto v1 = 1.e0; // no literal
static_assert(is_same<decltype(v1), const double>::value, "");
static_assert(v1 == 1., "");
// Float
static constexpr auto v2 = 1.f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v2 = 1.f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v2 = 1.F;
static_assert(is_same<decltype(v2), const float>::value, "");
static_assert(v2 == 1.0F, "");
static constexpr auto v3 = 1.e0f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1.e0f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v3 = 1.e0F;
static_assert(is_same<decltype(v3), const float>::value, "");
static_assert(v3 == 1.0F, "");
static constexpr auto v4 = 1.F; // OK.
static_assert(is_same<decltype(v4), const float>::value, "");
static_assert(v4 == 1.0F, "");
static constexpr auto v5 = 1.e0F; // OK.
static_assert(is_same<decltype(v5), const float>::value, "");
static_assert(v5 == 1.0F, "");
// Long double
static constexpr auto v6 = 1.l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v6 = 1.l;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v6 = 1.L;
static_assert(is_same<decltype(v6), const long double>::value, "");
static_assert(v6 == 1., "");
static constexpr auto v7 = 1.e0l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1.e0l;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v7 = 1.e0L;
static_assert(is_same<decltype(v7), const long double>::value, "");
static_assert(v7 == 1., "");
static constexpr auto v8 = 1.L; // OK.
static_assert(is_same<decltype(v8), const long double>::value, "");
static_assert(v8 == 1., "");
static constexpr auto v9 = 1.e0L; // OK.
static_assert(is_same<decltype(v9), const long double>::value, "");
static_assert(v9 == 1., "");
// __float128
static constexpr auto v10 = 1.q;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v10 = 1.q;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
// CHECK-FIXES: static constexpr auto v10 = 1.Q;
static_assert(is_same<decltype(v10), const __float128>::value, "");
static_assert(v10 == 1., "");
static constexpr auto v11 = 1.e0q;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1.e0q;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
// CHECK-FIXES: static constexpr auto v11 = 1.e0Q;
static_assert(is_same<decltype(v11), const __float128>::value, "");
static_assert(v11 == 1., "");
static constexpr auto v12 = 1.Q; // OK.
static_assert(is_same<decltype(v12), const __float128>::value, "");
static_assert(v12 == 1., "");
static constexpr auto v13 = 1.e0Q; // OK.
static_assert(is_same<decltype(v13), const __float128>::value, "");
static_assert(v13 == 1., "");
// _Float16
static constexpr auto v14 = 1.f16;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.f16;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
// CHECK-FIXES: static constexpr auto v14 = 1.F16;
static_assert(is_same<decltype(v14), const _Float16>::value, "");
static_assert(v14 == 1.F16, "");
static constexpr auto v15 = 1.e0f16;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0f16;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
// CHECK-FIXES: static constexpr auto v15 = 1.e0F16;
static_assert(is_same<decltype(v15), const _Float16>::value, "");
static_assert(v15 == 1.F16, "");
static constexpr auto v16 = 1.F16; // OK.
static_assert(is_same<decltype(v16), const _Float16>::value, "");
static_assert(v16 == 1.F16, "");
static constexpr auto v17 = 1.e0F16; // OK.
static_assert(is_same<decltype(v17), const _Float16>::value, "");
static_assert(v17 == 1.F16, "");
}
void floating_point_complex_suffix() {
// _Complex, I
static constexpr auto v14 = 1.i;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1.i;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
// CHECK-FIXES: static constexpr auto v14 = 1.I;
static_assert(is_same<decltype(v14), const _Complex double>::value, "");
static_assert(v14 == 1.I, "");
static constexpr auto v15 = 1.e0i;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1.e0i;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
// CHECK-FIXES: static constexpr auto v15 = 1.e0I;
static_assert(is_same<decltype(v15), const _Complex double>::value, "");
static_assert(v15 == 1.I, "");
static constexpr auto v16 = 1.I; // OK.
static_assert(is_same<decltype(v16), const _Complex double>::value, "");
static_assert(v16 == 1.I, "");
static constexpr auto v17 = 1.e0I; // OK.
static_assert(is_same<decltype(v17), const _Complex double>::value, "");
static_assert(v17 == 1.I, "");
// _Complex, J
static constexpr auto v18 = 1.j;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v18 = 1.j;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
// CHECK-FIXES: static constexpr auto v18 = 1.J;
static_assert(is_same<decltype(v18), const _Complex double>::value, "");
static_assert(v18 == 1.J, "");
static constexpr auto v19 = 1.e0j;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v19 = 1.e0j;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
// CHECK-FIXES: static constexpr auto v19 = 1.e0J;
static_assert(is_same<decltype(v19), const _Complex double>::value, "");
static_assert(v19 == 1.J, "");
static constexpr auto v20 = 1.J; // OK.
static_assert(is_same<decltype(v20), const _Complex double>::value, "");
static_assert(v20 == 1.J, "");
static constexpr auto v21 = 1.e0J; // OK.
static_assert(is_same<decltype(v21), const _Complex double>::value, "");
static_assert(v21 == 1.J, "");
}
void macros() {
#define PASSTHROUGH(X) X
static constexpr auto m0 = PASSTHROUGH(1.f);
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(1.f);
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(1.F);
static_assert(is_same<decltype(m0), const float>::value, "");
static_assert(m0 == 1.0F, "");
}

View File

@ -0,0 +1,155 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S
#include "readability-uppercase-literal-suffix.h"
void floating_point_suffix() {
static constexpr auto v0 = 0x0p0; // no literal
static_assert(is_same<decltype(v0), const double>::value, "");
static_assert(v0 == 0, "");
// Float
static constexpr auto v1 = 0xfp0f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v1 = 0xfp0f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v1 = 0xfp0F;
static_assert(is_same<decltype(v1), const float>::value, "");
static_assert(v1 == 15, "");
static constexpr auto v2 = 0xfp0F; // OK
static_assert(is_same<decltype(v2), const float>::value, "");
static_assert(v2 == 15, "");
static constexpr auto v3 = 0xfP0f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v3 = 0xfP0f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v3 = 0xfP0F;
static_assert(is_same<decltype(v3), const float>::value, "");
static_assert(v3 == 15, "");
static constexpr auto v4 = 0xfP0F; // OK
static_assert(is_same<decltype(v4), const float>::value, "");
static_assert(v4 == 15, "");
static constexpr auto v5 = 0xFP0f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 0xFP0f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v5 = 0xFP0F;
static_assert(is_same<decltype(v5), const float>::value, "");
static_assert(v5 == 15, "");
static constexpr auto v6 = 0xFP0F; // OK
static_assert(is_same<decltype(v6), const float>::value, "");
static_assert(v6 == 15, "");
static constexpr auto v7 = 0xFp0f;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 0xFp0f;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto v7 = 0xFp0F;
static_assert(is_same<decltype(v7), const float>::value, "");
static_assert(v7 == 15, "");
static constexpr auto v8 = 0xFp0F; // OK
static_assert(is_same<decltype(v8), const float>::value, "");
static_assert(v8 == 15, "");
// long double
static constexpr auto v9 = 0xfp0l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v9 = 0xfp0l;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v9 = 0xfp0L;
static_assert(is_same<decltype(v9), const long double>::value, "");
static_assert(v9 == 0xfp0, "");
static constexpr auto v10 = 0xfp0L; // OK.
static_assert(is_same<decltype(v10), const long double>::value, "");
static_assert(v10 == 0xfp0, "");
// __float128
static constexpr auto v11 = 0xfp0q;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'q', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v11 = 0xfp0q;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}Q{{$}}
// CHECK-FIXES: static constexpr auto v11 = 0xfp0Q;
static_assert(is_same<decltype(v11), const __float128>::value, "");
static_assert(v11 == 0xfp0, "");
static constexpr auto v12 = 0xfp0Q; // OK.
static_assert(is_same<decltype(v12), const __float128>::value, "");
static_assert(v12 == 0xfp0, "");
// _Float16
static constexpr auto v13 = 0xfp0f16;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'f16', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v13 = 0xfp0f16;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F16{{$}}
// CHECK-FIXES: static constexpr auto v13 = 0xfp0F16;
static_assert(is_same<decltype(v13), const _Float16>::value, "");
static_assert(v13 == 0xfp0F16, "");
static constexpr auto v14 = 0xfp0F16; // OK.
static_assert(is_same<decltype(v14), const _Float16>::value, "");
static_assert(v14 == 0xfp0F16, "");
}
void floating_point_complex_suffix() {
// _Complex, I
static constexpr auto v14 = 0xfp0i;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'i', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 0xfp0i;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
// CHECK-FIXES: static constexpr auto v14 = 0xfp0I;
static_assert(is_same<decltype(v14), const _Complex double>::value, "");
static_assert(v14 == 0xfp0I, "");
static constexpr auto v16 = 0xfp0I; // OK.
static_assert(is_same<decltype(v16), const _Complex double>::value, "");
static_assert(v16 == 0xfp0I, "");
// _Complex, J
static constexpr auto v18 = 0xfp0j;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: floating point literal has suffix 'j', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v18 = 0xfp0j;
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
// CHECK-FIXES: static constexpr auto v18 = 0xfp0J;
static_assert(is_same<decltype(v18), const _Complex double>::value, "");
static_assert(v18 == 0xfp0J, "");
static constexpr auto v20 = 0xfp0J; // OK.
static_assert(is_same<decltype(v20), const _Complex double>::value, "");
static_assert(v20 == 0xfp0J, "");
}
void macros() {
#define PASSTHROUGH(X) X
static constexpr auto m0 = PASSTHROUGH(0x0p0f);
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(0x0p0f);
// CHECK-MESSAGES-NEXT: ^ ~
// CHECK-MESSAGES-NEXT: {{^ *}}F{{$}}
// CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(0x0p0F);
static_assert(is_same<decltype(m0), const float>::value, "");
static_assert(m0 == 0x0p0F, "");
}

View File

@ -0,0 +1,130 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -config="{CheckOptions: [{key: readability-uppercase-literal-suffix.NewSuffixes, value: 'L;uL'}]}" -- -I %S
#include "readability-uppercase-literal-suffix.h"
void integer_suffix() {
// Unsigned
static constexpr auto v3 = 1u; // OK.
static_assert(is_same<decltype(v3), const unsigned int>::value, "");
static_assert(v3 == 1, "");
static constexpr auto v4 = 1U; // OK.
static_assert(is_same<decltype(v4), const unsigned int>::value, "");
static_assert(v4 == 1, "");
// Long
static constexpr auto v5 = 1l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v5 = 1L;
static_assert(is_same<decltype(v5), const long>::value, "");
static_assert(v5 == 1, "");
static constexpr auto v6 = 1L; // OK.
static_assert(is_same<decltype(v6), const long>::value, "");
static_assert(v6 == 1, "");
// Long Long
static constexpr auto v7 = 1ll; // OK.
static_assert(is_same<decltype(v7), const long long>::value, "");
static_assert(v7 == 1, "");
static constexpr auto v8 = 1LL; // OK.
static_assert(is_same<decltype(v8), const long long>::value, "");
static_assert(v8 == 1, "");
// Unsigned Long
static constexpr auto v9 = 1ul;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'ul', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1ul;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
// CHECK-FIXES: static constexpr auto v9 = 1uL;
static_assert(is_same<decltype(v9), const unsigned long>::value, "");
static_assert(v9 == 1, "");
static constexpr auto v10 = 1uL; // OK.
static_assert(is_same<decltype(v10), const unsigned long>::value, "");
static_assert(v10 == 1, "");
static constexpr auto v11 = 1Ul;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ul', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1Ul;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
// CHECK-FIXES: static constexpr auto v11 = 1uL;
static_assert(is_same<decltype(v11), const unsigned long>::value, "");
static_assert(v11 == 1, "");
static constexpr auto v12 = 1UL; // OK.
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'UL', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v12 = 1UL;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}uL{{$}}
// CHECK-FIXES: static constexpr auto v12 = 1uL;
static_assert(is_same<decltype(v12), const unsigned long>::value, "");
static_assert(v12 == 1, "");
// Long Unsigned
static constexpr auto v13 = 1lu; // OK.
static_assert(is_same<decltype(v13), const unsigned long>::value, "");
static_assert(v13 == 1, "");
static constexpr auto v14 = 1Lu; // OK.
static_assert(is_same<decltype(v14), const unsigned long>::value, "");
static_assert(v14 == 1, "");
static constexpr auto v15 = 1lU; // OK.
static_assert(is_same<decltype(v15), const unsigned long>::value, "");
static_assert(v15 == 1, "");
static constexpr auto v16 = 1LU; // OK.
static_assert(is_same<decltype(v16), const unsigned long>::value, "");
static_assert(v16 == 1, "");
// Unsigned Long Long
static constexpr auto v17 = 1ull; // OK.
static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
static_assert(v17 == 1, "");
static constexpr auto v18 = 1uLL; // OK.
static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
static_assert(v18 == 1, "");
static constexpr auto v19 = 1Ull; // OK.
static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
static_assert(v19 == 1, "");
static constexpr auto v20 = 1ULL; // OK.
static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
static_assert(v20 == 1, "");
// Long Long Unsigned
static constexpr auto v21 = 1llu; // OK.
static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
static_assert(v21 == 1, "");
static constexpr auto v22 = 1LLu; // OK.
static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
static_assert(v22 == 1, "");
static constexpr auto v23 = 1llU; // OK.
static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
static_assert(v23 == 1, "");
static constexpr auto v24 = 1LLU; // OK.
static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
static_assert(v24 == 1, "");
}

View File

@ -0,0 +1,25 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -I %S
void macros() {
#define INMACRO(X) 1.f
static constexpr auto m1 = INMACRO();
// CHECK-NOTES: :[[@LINE-1]]:30: warning: floating point literal has suffix 'f', which is not uppercase
// CHECK-NOTES: :[[@LINE-3]]:20: note: expanded from macro 'INMACRO'
// CHECK-FIXES: #define INMACRO(X) 1.f
// CHECK-FIXES: static constexpr auto m1 = INMACRO();
// ^ so no fix-its here.
}
void horrible_macros() {
#define MAKE_UNSIGNED(x) x##u
#define ONE MAKE_UNSIGNED(1)
static constexpr auto hm0 = ONE;
// CHECK-NOTES: :[[@LINE-1]]:31: warning: integer literal has suffix 'u', which is not uppercase
// CHECK-NOTES: :[[@LINE-3]]:13: note: expanded from macro 'ONE'
// CHECK-NOTES: :[[@LINE-5]]:26: note: expanded from macro 'MAKE_UNSIGNED'
// CHECK-NOTES: note: expanded from here
// CHECK-FIXES: #define MAKE_UNSIGNED(x) x##u
// CHECK-FIXES: #define ONE MAKE_UNSIGNED(1)
// CHECK-FIXES: static constexpr auto hm0 = ONE;
// Certainly no fix-its.
}

View File

@ -0,0 +1,77 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -target x86_64-pc-linux-gnu -I %S -fms-extensions
#include "readability-uppercase-literal-suffix.h"
void integer_suffix() {
static constexpr auto v0 = __LINE__; // synthetic
static_assert(v0 == 9 || v0 == 5, "");
static constexpr auto v1 = __cplusplus; // synthetic, long
static constexpr auto v2 = 1; // no literal
static_assert(is_same<decltype(v2), const int>::value, "");
static_assert(v2 == 1, "");
// i32
static constexpr auto v3 = 1i32;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i32', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1i32;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}I32{{$}}
// CHECK-FIXES: static constexpr auto v3 = 1I32;
static_assert(is_same<decltype(v3), const int>::value, "");
static_assert(v3 == 1I32, "");
static constexpr auto v4 = 1I32; // OK.
static_assert(is_same<decltype(v4), const int>::value, "");
static_assert(v4 == 1I32, "");
// i64
static constexpr auto v5 = 1i64;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i64', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1i64;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}I64{{$}}
// CHECK-FIXES: static constexpr auto v5 = 1I64;
static_assert(is_same<decltype(v5), const long int>::value, "");
static_assert(v5 == 1I64, "");
static constexpr auto v6 = 1I64; // OK.
static_assert(is_same<decltype(v6), const long int>::value, "");
static_assert(v6 == 1I64, "");
// i16
static constexpr auto v7 = 1i16;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i16', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1i16;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}I16{{$}}
// CHECK-FIXES: static constexpr auto v7 = 1I16;
static_assert(is_same<decltype(v7), const short>::value, "");
static_assert(v7 == 1I16, "");
static constexpr auto v8 = 1I16; // OK.
static_assert(is_same<decltype(v8), const short>::value, "");
static_assert(v8 == 1I16, "");
// i8
static constexpr auto v9 = 1i8;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'i8', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1i8;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}I8{{$}}
// CHECK-FIXES: static constexpr auto v9 = 1I8;
static_assert(is_same<decltype(v9), const char>::value, "");
static_assert(v9 == 1I8, "");
static constexpr auto v10 = 1I8; // OK.
static_assert(is_same<decltype(v10), const char>::value, "");
static_assert(v10 == 1I8, "");
}

View File

@ -0,0 +1,268 @@
// RUN: %check_clang_tidy %s readability-uppercase-literal-suffix %t -- -- -I %S
// RUN: grep -Ev "// *[A-Z-]+:" %s > %t.cpp
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -fix -- -I %S
// RUN: clang-tidy %t.cpp -checks='-*,readability-uppercase-literal-suffix' -warnings-as-errors='-*,readability-uppercase-literal-suffix' -- -I %S
#include "readability-uppercase-literal-suffix.h"
void integer_suffix() {
static constexpr auto v0 = __LINE__; // synthetic
static_assert(v0 == 9 || v0 == 5, "");
static constexpr auto v1 = __cplusplus; // synthetic, long
static constexpr auto v2 = 1; // no literal
static_assert(is_same<decltype(v2), const int>::value, "");
static_assert(v2 == 1, "");
// Unsigned
static constexpr auto v3 = 1u;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'u', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v3 = 1u;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}U{{$}}
// CHECK-FIXES: static constexpr auto v3 = 1U;
static_assert(is_same<decltype(v3), const unsigned int>::value, "");
static_assert(v3 == 1, "");
static constexpr auto v4 = 1U; // OK.
static_assert(is_same<decltype(v4), const unsigned int>::value, "");
static_assert(v4 == 1, "");
// Long
static constexpr auto v5 = 1l;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'l', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v5 = 1l;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}L{{$}}
// CHECK-FIXES: static constexpr auto v5 = 1L;
static_assert(is_same<decltype(v5), const long>::value, "");
static_assert(v5 == 1, "");
static constexpr auto v6 = 1L; // OK.
static_assert(is_same<decltype(v6), const long>::value, "");
static_assert(v6 == 1, "");
// Long Long
static constexpr auto v7 = 1ll;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'll', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v7 = 1ll;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LL{{$}}
// CHECK-FIXES: static constexpr auto v7 = 1LL;
static_assert(is_same<decltype(v7), const long long>::value, "");
static_assert(v7 == 1, "");
static constexpr auto v8 = 1LL; // OK.
static_assert(is_same<decltype(v8), const long long>::value, "");
static_assert(v8 == 1, "");
// Unsigned Long
static constexpr auto v9 = 1ul;
// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: integer literal has suffix 'ul', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v9 = 1ul;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
// CHECK-FIXES: static constexpr auto v9 = 1UL;
static_assert(is_same<decltype(v9), const unsigned long>::value, "");
static_assert(v9 == 1, "");
static constexpr auto v10 = 1uL;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'uL', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v10 = 1uL;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
// CHECK-FIXES: static constexpr auto v10 = 1UL;
static_assert(is_same<decltype(v10), const unsigned long>::value, "");
static_assert(v10 == 1, "");
static constexpr auto v11 = 1Ul;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ul', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v11 = 1Ul;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}UL{{$}}
// CHECK-FIXES: static constexpr auto v11 = 1UL;
static_assert(is_same<decltype(v11), const unsigned long>::value, "");
static_assert(v11 == 1, "");
static constexpr auto v12 = 1UL; // OK.
static_assert(is_same<decltype(v12), const unsigned long>::value, "");
static_assert(v12 == 1, "");
// Long Unsigned
static constexpr auto v13 = 1lu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v13 = 1lu;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v13 = 1LU;
static_assert(is_same<decltype(v13), const unsigned long>::value, "");
static_assert(v13 == 1, "");
static constexpr auto v14 = 1Lu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Lu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v14 = 1Lu;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v14 = 1LU;
static_assert(is_same<decltype(v14), const unsigned long>::value, "");
static_assert(v14 == 1, "");
static constexpr auto v15 = 1lU;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'lU', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v15 = 1lU;
// CHECK-MESSAGES-NEXT: ^~~
// CHECK-MESSAGES-NEXT: {{^ *}}LU{{$}}
// CHECK-FIXES: static constexpr auto v15 = 1LU;
static_assert(is_same<decltype(v15), const unsigned long>::value, "");
static_assert(v15 == 1, "");
static constexpr auto v16 = 1LU; // OK.
static_assert(is_same<decltype(v16), const unsigned long>::value, "");
static_assert(v16 == 1, "");
// Unsigned Long Long
static constexpr auto v17 = 1ull;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'ull', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v17 = 1ull;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
// CHECK-FIXES: static constexpr auto v17 = 1ULL;
static_assert(is_same<decltype(v17), const unsigned long long>::value, "");
static_assert(v17 == 1, "");
static constexpr auto v18 = 1uLL;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'uLL', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v18 = 1uLL;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
// CHECK-FIXES: static constexpr auto v18 = 1ULL;
static_assert(is_same<decltype(v18), const unsigned long long>::value, "");
static_assert(v18 == 1, "");
static constexpr auto v19 = 1Ull;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'Ull', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v19 = 1Ull;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}ULL{{$}}
// CHECK-FIXES: static constexpr auto v19 = 1ULL;
static_assert(is_same<decltype(v19), const unsigned long long>::value, "");
static_assert(v19 == 1, "");
static constexpr auto v20 = 1ULL; // OK.
static_assert(is_same<decltype(v20), const unsigned long long>::value, "");
static_assert(v20 == 1, "");
// Long Long Unsigned
static constexpr auto v21 = 1llu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v21 = 1llu;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v21 = 1LLU;
static_assert(is_same<decltype(v21), const unsigned long long>::value, "");
static_assert(v21 == 1, "");
static constexpr auto v22 = 1LLu;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'LLu', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v22 = 1LLu;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v22 = 1LLU;
static_assert(is_same<decltype(v22), const unsigned long long>::value, "");
static_assert(v22 == 1, "");
static constexpr auto v23 = 1llU;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'llU', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v23 = 1llU;
// CHECK-MESSAGES-NEXT: ^~~~
// CHECK-MESSAGES-NEXT: {{^ *}}LLU{{$}}
// CHECK-FIXES: static constexpr auto v23 = 1LLU;
static_assert(is_same<decltype(v23), const unsigned long long>::value, "");
static_assert(v23 == 1, "");
static constexpr auto v24 = 1LLU; // OK.
static_assert(is_same<decltype(v24), const unsigned long long>::value, "");
static_assert(v24 == 1, "");
}
void integer_complex_suffix() {
// _Complex, I
static constexpr auto v25 = 1i;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'i', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v25 = 1i;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}I{{$}}
// CHECK-FIXES: static constexpr auto v25 = 1I;
static_assert(is_same<decltype(v25), const _Complex int>::value, "");
static_assert(v25 == 1I, "");
static constexpr auto v26 = 1I; // OK.
static_assert(is_same<decltype(v26), const _Complex int>::value, "");
static_assert(v26 == 1I, "");
// _Complex, J
static constexpr auto v27 = 1j;
// CHECK-MESSAGES: :[[@LINE-1]]:31: warning: integer literal has suffix 'j', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto v27 = 1j;
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}J{{$}}
// CHECK-FIXES: static constexpr auto v27 = 1J;
static_assert(is_same<decltype(v27), const _Complex int>::value, "");
static_assert(v27 == 1J, "");
static constexpr auto v28 = 1J; // OK.
static_assert(is_same<decltype(v28), const _Complex int>::value, "");
static_assert(v28 == 1J, "");
}
void macros() {
#define PASSTHROUGH(X) X
static constexpr auto m0 = PASSTHROUGH(1u);
// CHECK-MESSAGES: :[[@LINE-1]]:42: warning: integer literal has suffix 'u', which is not uppercase
// CHECK-MESSAGES-NEXT: static constexpr auto m0 = PASSTHROUGH(1u);
// CHECK-MESSAGES-NEXT: ^~
// CHECK-MESSAGES-NEXT: {{^ *}}U{{$}}
// CHECK-FIXES: static constexpr auto m0 = PASSTHROUGH(1U);
static_assert(is_same<decltype(m0), const unsigned int>::value, "");
static_assert(m0 == 1, "");
}
// Check that user-defined literals do not cause any diags.
unsigned long long int operator"" _ull(unsigned long long int);
void user_defined_literals() {
1_ull;
}
template <unsigned alignment>
void template_test() {
static_assert(alignment, "");
}
void actual_template_test() {
template_test<4>();
}
const int table[6] = {};
void read_test() {
for (auto i : table) {
}
}
namespace {
enum a { b };
constexpr bool operator&(a, a) { return int(); }
template <a l>
void c() { l &a(); }
void d();
void d() { c<b>(); }
} // namespace

View File

@ -0,0 +1,16 @@
template <class T, T v>
struct integral_constant {
static constexpr T value = v;
typedef T value_type;
typedef integral_constant type; // using injected-class-name
constexpr operator value_type() const noexcept { return value; }
};
using false_type = integral_constant<bool, false>;
using true_type = integral_constant<bool, true>;
template <class T, class U>
struct is_same : false_type {};
template <class T>
struct is_same<T, T> : true_type {};