[clang-tools-extra] 06f3dab - [clang-tidy] Fix readability-redundant-string-init for c++17/c++2a
Mitchell Balan via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 15 15:11:13 PST 2019
Author: Mitchell Balan
Date: 2019-11-15T18:09:42-05:00
New Revision: 06f3dabe4a2e85a32ade27c0769b6084c828a206
URL: https://github.com/llvm/llvm-project/commit/06f3dabe4a2e85a32ade27c0769b6084c828a206
DIFF: https://github.com/llvm/llvm-project/commit/06f3dabe4a2e85a32ade27c0769b6084c828a206.diff
LOG: [clang-tidy] Fix readability-redundant-string-init for c++17/c++2a
Summary:
`readability-redundant-string-init` was one of several clang-tidy checks documented as failing for C++17. (The failure mode in C++17 is that it changes `std::string Name = ""`; to `std::string Name = Name;`, which actually compiles but crashes at run-time.)
Analyzing the AST with `clang -Xclang -ast-dump` showed that the outer `CXXConstructExprs` that previously held the correct SourceRange were being elided in C++17/2a, but the containing `VarDecl` expressions still had all the relevant information. So this patch changes the fix to get its source ranges from `VarDecl`.
It adds one test `std::string g = "u", h = "", i = "uuu", j = "", k;` to confirm proper warnings and fixit replacements in a single `DeclStmt` where some strings require replacement and others don't. The readability-redundant-string-init.cpp and readability-redundant-string-init-msvc.cpp tests now pass for C++11/14/17/2a.
Reviewers: gribozavr, etienneb, alexfh, hokein, aaron.ballman, gribozavr2
Patch by: poelmanc
Subscribers: NoQ, MyDeveloperDay, Eugene.Zelenko, dylanmckay, cfe-commits
Tags: #clang, #clang-tools-extra
Differential Revision: https://reviews.llvm.org/D69238
Added:
Modified:
clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp
clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/docs/clang-tidy/checks/modernize-use-override.rst
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp
index 2f15213dca8c..8ee77ccd16ff 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp
@@ -20,11 +20,13 @@ namespace modernize {
UseOverrideCheck::UseOverrideCheck(StringRef Name, ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
IgnoreDestructors(Options.get("IgnoreDestructors", false)),
+ AllowOverrideAndFinal(Options.get("AllowOverrideAndFinal", false)),
OverrideSpelling(Options.get("OverrideSpelling", "override")),
FinalSpelling(Options.get("FinalSpelling", "final")) {}
void UseOverrideCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "IgnoreDestructors", IgnoreDestructors);
+ Options.store(Opts, "AllowOverrideAndFinal", AllowOverrideAndFinal);
Options.store(Opts, "OverrideSpelling", OverrideSpelling);
Options.store(Opts, "FinalSpelling", FinalSpelling);
}
@@ -103,7 +105,8 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
bool OnlyVirtualSpecified = HasVirtual && !HasOverride && !HasFinal;
unsigned KeywordCount = HasVirtual + HasOverride + HasFinal;
- if (!OnlyVirtualSpecified && KeywordCount == 1)
+ if ((!OnlyVirtualSpecified && KeywordCount == 1) ||
+ (!HasVirtual && HasOverride && HasFinal && AllowOverrideAndFinal))
return; // Nothing to do.
std::string Message;
@@ -113,8 +116,9 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
Message = "annotate this function with '%0' or (rarely) '%1'";
} else {
StringRef Redundant =
- HasVirtual ? (HasOverride && HasFinal ? "'virtual' and '%0' are"
- : "'virtual' is")
+ HasVirtual ? (HasOverride && HasFinal && !AllowOverrideAndFinal
+ ? "'virtual' and '%0' are"
+ : "'virtual' is")
: "'%0' is";
StringRef Correct = HasFinal ? "'%1'" : "'%0'";
@@ -211,7 +215,7 @@ void UseOverrideCheck::check(const MatchFinder::MatchResult &Result) {
Diag << FixItHint::CreateInsertion(InsertLoc, ReplacementText);
}
- if (HasFinal && HasOverride) {
+ if (HasFinal && HasOverride && !AllowOverrideAndFinal) {
SourceLocation OverrideLoc = Method->getAttr<OverrideAttr>()->getLocation();
Diag << FixItHint::CreateRemoval(
CharSourceRange::getTokenRange(OverrideLoc, OverrideLoc));
diff --git a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h
index ed163956ecdb..082778f2957c 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h
+++ b/clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.h
@@ -26,6 +26,7 @@ class UseOverrideCheck : public ClangTidyCheck {
private:
const bool IgnoreDestructors;
+ const bool AllowOverrideAndFinal;
const std::string OverrideSpelling;
const std::string FinalSpelling;
};
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 5737dc3d288d..d0305446806b 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -164,6 +164,12 @@ Improvements to clang-tidy
Finds non-static member functions that can be made ``const``
because the functions don't use ``this`` in a non-const way.
+- Improved :doc:`modernize-use-override
+ <clang-tidy/checks/modernize-use-override>` check.
+
+ The check now supports the ``AllowOverrideAndFinal`` option to eliminate
+ conflicts with ``gcc -Wsuggest-override`` or ``gcc -Werror=suggest-override``.
+
Improvements to include-fixer
-----------------------------
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize-use-override.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize-use-override.rst
index 4273c6e57708..d20c1d88520e 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize-use-override.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize-use-override.rst
@@ -27,6 +27,14 @@ Options
If set to non-zero, this check will not diagnose destructors. Default is `0`.
+.. option:: AllowOverrideAndFinal
+
+ If set to non-zero, this check will not diagnose ``override`` as redundant
+ with ``final``. This is useful when code will be compiled by a compiler with
+ warning/error checking flags requiring ``override`` explicitly on overriden
+ members, such as ``gcc -Wsuggest-override``/``gcc -Werror=suggest-override``.
+ Default is `0`.
+
.. option:: OverrideSpelling
Specifies a macro to use instead of ``override``. This is useful when
More information about the cfe-commits
mailing list