[clang-tools-extra] 5b95d17 - [clang-tidy] `performance-faster-string-find` generates incorrect fixes for single quote character literals

2023-08-08 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2023-08-09T00:55:45+02:00
New Revision: 5b95d17da1f0719f0af711e032d36b18fcb92070

URL: 
https://github.com/llvm/llvm-project/commit/5b95d17da1f0719f0af711e032d36b18fcb92070
DIFF: 
https://github.com/llvm/llvm-project/commit/5b95d17da1f0719f0af711e032d36b18fcb92070.diff

LOG: [clang-tidy] `performance-faster-string-find` generates incorrect fixes 
for single quote character literals

Reviewed By: PiotrZSL

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst

clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp 
b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
index d932b5fb936cb2..ca4f6ad409b08c 100644
--- a/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/FasterStringFindCheck.cpp
@@ -26,14 +26,20 @@ std::optional makeCharacterLiteral(const 
StringLiteral *Literal) {
 Literal->outputString(OS);
   }
   // Now replace the " with '.
-  auto Pos = Result.find_first_of('"');
-  if (Pos == Result.npos)
+  auto OpenPos = Result.find_first_of('"');
+  if (OpenPos == Result.npos)
 return std::nullopt;
-  Result[Pos] = '\'';
-  Pos = Result.find_last_of('"');
-  if (Pos == Result.npos)
+  Result[OpenPos] = '\'';
+
+  auto ClosePos = Result.find_last_of('"');
+  if (ClosePos == Result.npos)
 return std::nullopt;
-  Result[Pos] = '\'';
+  Result[ClosePos] = '\'';
+
+  // "'" is OK, but ''' is not, so add a backslash
+  if ((ClosePos - OpenPos) == 2 && Result[OpenPos + 1] == '\'')
+Result.replace(OpenPos + 1, 1, "\\'");
+
   return Result;
 }
 

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 78d3dab48f5306..c4b09bae18ec37 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -188,6 +188,10 @@ Changes in existing checks
   ` to support for-loops with
   iterators initialized by free functions like ``begin``, ``end``, or ``size``.
 
+- Improved :doc:`performance-faster-string-find
+  ` check to properly escape
+  single quotes.
+
 - Improved :doc:`performanc-noexcept-swap
   ` check to enforce a stricter
   match with the swap function signature, eliminating false-positives.

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
index dc625024fd1bc9..b50d175cff3b70 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/performance/faster-string-find.cpp
@@ -56,13 +56,21 @@ void StringFind() {
   // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string 
literal
   // CHECK-FIXES: Str.find('a', 1);
 
-  // Doens't work with strings smaller or larger than 1 char.
+  // Doesn't work with strings smaller or larger than 1 char.
   Str.find("");
   Str.find("ab");
 
   // Doesn't do anything with the 3 argument overload.
   Str.find("a", 1, 1);
 
+  // Single quotes are escaped properly
+  Str.find("'");
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string 
literal
+  // CHECK-FIXES: Str.find('\'');
+  Str.find("\'");
+  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string 
literal
+  // CHECK-FIXES: Str.find('\'');
+
   // Other methods that can also be replaced
   Str.rfind("a");
   // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string 
literal



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] f263f45 - [clang-tidy] `readability-implicit-bool-conversion.AllowIntegerConditions` ignores `DoStmt`s

2023-08-08 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2023-08-08T23:07:10+02:00
New Revision: f263f45ba6494c7516a11b1af920d6ca98e79d2b

URL: 
https://github.com/llvm/llvm-project/commit/f263f45ba6494c7516a11b1af920d6ca98e79d2b
DIFF: 
https://github.com/llvm/llvm-project/commit/f263f45ba6494c7516a11b1af920d6ca98e79d2b.diff

LOG: [clang-tidy] `readability-implicit-bool-conversion.AllowIntegerConditions` 
ignores `DoStmt`s

Reviewed By: PiotrZSL

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst

clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
index 863ac4dbbf4c6d..99b792b90a3ca9 100644
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -228,7 +228,8 @@ bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
   if (!S)
 return false;
   if (isa(S) || isa(S) || isa(S) ||
-  isa(S) || isa(S))
+  isa(S) || isa(S) ||
+  isa(S))
 return true;
   if (isa(S) || isa(S) ||
   isUnaryLogicalNotOperator(S) ||

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index dbd2fbf6de6d42..78d3dab48f5306 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -196,6 +196,11 @@ Changes in existing checks
   ` check to emit proper
   warnings when a type forward declaration precedes its definition.
 
+- Improved :doc:`readability-implicit-bool-conversion
+  ` check to take
+  do-while loops into account for the `AllowIntegerConditions` and
+  `AllowPointerConditions` options.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp
index f17b4dcacdb61b..e393e297140cbd 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability/implicit-bool-conversion-allow-in-conditions.cpp
@@ -38,6 +38,9 @@ void implicitConversionIntegerToBoolInConditionalsIsAllowed() 
{
   while (functionReturningInt()) {}
   while (functionReturningPointer()) {}
   while (functionReturningInt() && !functionReturningPointer() || 
(!functionReturningInt() && functionReturningPointer())) {}
+  do {} while (functionReturningInt());
+  do {} while (functionReturningPointer());
+  do {} while (functionReturningInt() && !functionReturningPointer() || 
(!functionReturningInt() && functionReturningPointer()));
   int value1 = functionReturningInt() ? 1 : 2;
   int value2 = !functionReturningInt() ? 1 : 2;
   int value3 = (functionReturningInt() && functionReturningPointer() || 
!functionReturningInt()) ? 1 : 2;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 95d7738 - [clang-tidy] Fix behavior of `modernize-use-using` with nested structs/unions

2022-04-21 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-04-21T15:18:31+02:00
New Revision: 95d77383f2ba8d3136856b52520d3f73f9bc89e7

URL: 
https://github.com/llvm/llvm-project/commit/95d77383f2ba8d3136856b52520d3f73f9bc89e7
DIFF: 
https://github.com/llvm/llvm-project/commit/95d77383f2ba8d3136856b52520d3f73f9bc89e7.diff

LOG: [clang-tidy] Fix behavior of `modernize-use-using` with nested 
structs/unions

Fixes https://github.com/llvm/llvm-project/issues/50334.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
clang-tools-extra/clang-tidy/modernize/UseUsingCheck.h
clang-tools-extra/test/clang-tidy/checkers/modernize-use-using.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp 
b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
index a12a056f13ea1..fa3cfa5e9cfca 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseUsingCheck.cpp
@@ -16,6 +16,10 @@ namespace clang {
 namespace tidy {
 namespace modernize {
 
+static constexpr llvm::StringLiteral ParentDeclName = "parent-decl";
+static constexpr llvm::StringLiteral TagDeclName = "tag-decl";
+static constexpr llvm::StringLiteral TypedefName = "typedef";
+
 UseUsingCheck::UseUsingCheck(StringRef Name, ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context),
   IgnoreMacros(Options.getLocalOrGlobal("IgnoreMacros", true)) {}
@@ -25,23 +29,45 @@ void 
UseUsingCheck::storeOptions(ClangTidyOptions::OptionMap ) {
 }
 
 void UseUsingCheck::registerMatchers(MatchFinder *Finder) {
-  Finder->addMatcher(typedefDecl(unless(isInstantiated())).bind("typedef"),
+  Finder->addMatcher(typedefDecl(unless(isInstantiated()),
+ hasParent(decl().bind(ParentDeclName)))
+ .bind(TypedefName),
  this);
-  // This matcher used to find tag declarations in source code within typedefs.
-  // They appear in the AST just *prior* to the typedefs.
-  Finder->addMatcher(tagDecl(unless(isImplicit())).bind("tagdecl"), this);
+
+  // This matcher is used to find tag declarations in source code within
+  // typedefs. They appear in the AST just *prior* to the typedefs.
+  Finder->addMatcher(
+  tagDecl(
+  anyOf(allOf(unless(anyOf(isImplicit(),
+   classTemplateSpecializationDecl())),
+  hasParent(decl().bind(ParentDeclName))),
+// We want the parent of the ClassTemplateDecl, not the parent
+// of the specialization.
+classTemplateSpecializationDecl(hasAncestor(classTemplateDecl(
+hasParent(decl().bind(ParentDeclName)))
+  .bind(TagDeclName),
+  this);
 }
 
 void UseUsingCheck::check(const MatchFinder::MatchResult ) {
+  const auto *ParentDecl = Result.Nodes.getNodeAs(ParentDeclName);
+  if (!ParentDecl)
+return;
+
   // Match CXXRecordDecl only to store the range of the last non-implicit full
   // declaration, to later check whether it's within the typdef itself.
-  const auto *MatchedTagDecl = Result.Nodes.getNodeAs("tagdecl");
+  const auto *MatchedTagDecl = Result.Nodes.getNodeAs(TagDeclName);
   if (MatchedTagDecl) {
-LastTagDeclRange = MatchedTagDecl->getSourceRange();
+// It is not sufficient to just track the last TagDecl that we've seen,
+// because if one struct or union is nested inside another, the last 
TagDecl
+// before the typedef will be the nested one (PR#50990). Therefore, we also
+// keep track of the parent declaration, so that we can look up the last
+// TagDecl that is a sibling of the typedef in the AST.
+LastTagDeclRanges[ParentDecl] = MatchedTagDecl->getSourceRange();
 return;
   }
 
-  const auto *MatchedDecl = Result.Nodes.getNodeAs("typedef");
+  const auto *MatchedDecl = Result.Nodes.getNodeAs(TypedefName);
   if (MatchedDecl->getLocation().isInvalid())
 return;
 
@@ -102,13 +128,14 @@ void UseUsingCheck::check(const MatchFinder::MatchResult 
) {
   auto Diag = diag(ReplaceRange.getBegin(), UseUsingWarning);
 
   // If typedef contains a full tag declaration, extract its full text.
-  if (LastTagDeclRange.isValid() &&
-  ReplaceRange.fullyContains(LastTagDeclRange)) {
-bool Invalid;
-Type = std::string(
-Lexer::getSourceText(CharSourceRange::getTokenRange(LastTagDeclRange),
- *Result.SourceManager, getLangOpts(), ));
-if (Invalid)
+  auto LastTagDeclRange = LastTagDeclRanges.find(ParentDecl);
+  if (LastTagDeclRange != LastTagDeclRanges.end() &&
+  LastTagDeclRange->second.isValid() &&
+  ReplaceRange.fullyContains(LastTagDeclRange->second)) {
+Type = std::string(Lexer::getSourceText(
+

[clang-tools-extra] cce7951 - [clang-tidy] Reduce false positives for `bugprone-infinite-loop` with dependent expressions

2022-04-20 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-04-20T17:17:54+02:00
New Revision: cce79514ff405d93ab7aab79974e6f80ced85980

URL: 
https://github.com/llvm/llvm-project/commit/cce79514ff405d93ab7aab79974e6f80ced85980
DIFF: 
https://github.com/llvm/llvm-project/commit/cce79514ff405d93ab7aab79974e6f80ced85980.diff

LOG: [clang-tidy] Reduce false positives for `bugprone-infinite-loop` with 
dependent expressions

Fixes https://github.com/llvm/llvm-project/issues/51423.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
index 99775b2400458..3359a7f8932ed 100644
--- a/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/InfiniteLoopCheck.cpp
@@ -117,12 +117,32 @@ static std::string getCondVarNames(const Stmt *Cond) {
   return Result;
 }
 
-static bool isKnownFalse(const Expr , const ASTContext ) {
-  if (Cond.isValueDependent())
+static bool isKnownToHaveValue(const Expr , const ASTContext ,
+   bool ExpectedValue) {
+  if (Cond.isValueDependent()) {
+if (const auto *BinOp = dyn_cast()) {
+  // Conjunctions (disjunctions) can still be handled if at least one
+  // conjunct (disjunct) is known to be false (true).
+  if (!ExpectedValue && BinOp->getOpcode() == BO_LAnd)
+return isKnownToHaveValue(*BinOp->getLHS(), Ctx, false) ||
+   isKnownToHaveValue(*BinOp->getRHS(), Ctx, false);
+  if (ExpectedValue && BinOp->getOpcode() == BO_LOr)
+return isKnownToHaveValue(*BinOp->getLHS(), Ctx, true) ||
+   isKnownToHaveValue(*BinOp->getRHS(), Ctx, true);
+  if (BinOp->getOpcode() == BO_Comma)
+return isKnownToHaveValue(*BinOp->getRHS(), Ctx, ExpectedValue);
+} else if (const auto *UnOp = dyn_cast()) {
+  if (UnOp->getOpcode() == UO_LNot)
+return isKnownToHaveValue(*UnOp->getSubExpr(), Ctx, !ExpectedValue);
+} else if (const auto *Paren = dyn_cast())
+  return isKnownToHaveValue(*Paren->getSubExpr(), Ctx, ExpectedValue);
+else if (const auto *ImplCast = dyn_cast())
+  return isKnownToHaveValue(*ImplCast->getSubExpr(), Ctx, ExpectedValue);
 return false;
+  }
   bool Result = false;
   if (Cond.EvaluateAsBooleanCondition(Result, Ctx))
-return !Result;
+return Result == ExpectedValue;
   return false;
 }
 
@@ -144,7 +164,7 @@ void InfiniteLoopCheck::check(const 
MatchFinder::MatchResult ) {
   const auto *LoopStmt = Result.Nodes.getNodeAs("loop-stmt");
   const auto *Func = Result.Nodes.getNodeAs("func");
 
-  if (isKnownFalse(*Cond, *Result.Context))
+  if (isKnownToHaveValue(*Cond, *Result.Context, false))
 return;
 
   bool ShouldHaveConditionVariables = true;

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 541ff89c14803..81becb0031a45 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -176,6 +176,9 @@ Changes in existing checks
 - Fixed incorrect suggestions for :doc:`readability-container-size-empty
   ` when smart pointers 
are involved.
 
+- Fixed some false positives in :doc:`bugprone-infinite-loop
+  ` involving dependent expressions.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
index ed50b5c7d74ea..0074266ce4b87 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-infinite-loop.cpp
@@ -1,5 +1,5 @@
 // RUN: %check_clang_tidy %s bugprone-infinite-loop %t \
-// RUN:   -- -- -fexceptions -fblocks
+// RUN:   -- -- -fexceptions -fblocks 
-fno-delayed-template-parsing
 
 void simple_infinite_loop1() {
   int i = 0;
@@ -622,3 +622,31 @@ void test_volatile_concrete_address(int i, int size) {
 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of 
its condition variables (size) are updated in the loop body 
[bugprone-infinite-loop]
   }
 }
+
+template 
+int some_template_fn() { return 1; }
+
+template 
+void test_dependent_condition() {
+  const int error = some_template_fn();
+  do {
+  } while (false && error == 0);
+
+  const int val = some_template_fn();
+  for (; !(val == 0 || true);) {
+  }
+
+  const int val2 = some_template_fn();
+  for (; !(val2 == 0 || false);) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: this loop is infinite; none of 
its condition variables (val2) 

[clang-tools-extra] fb3b3f7 - [clang-tidy] Fix `readability-container-size-empty` check for smart pointers

2022-04-20 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-04-20T17:03:30+02:00
New Revision: fb3b3f76bf75875684eedfe0711424e7ceba4b41

URL: 
https://github.com/llvm/llvm-project/commit/fb3b3f76bf75875684eedfe0711424e7ceba4b41
DIFF: 
https://github.com/llvm/llvm-project/commit/fb3b3f76bf75875684eedfe0711424e7ceba4b41.diff

LOG: [clang-tidy] Fix `readability-container-size-empty` check for smart 
pointers

Fixes https://github.com/llvm/llvm-project/issues/51118.

Reviewed By: Sockke

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst

clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
index d399c957c7c73..cc7a6834e3b6e 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerSizeEmptyCheck.cpp
@@ -191,10 +191,17 @@ void ContainerSizeEmptyCheck::check(const 
MatchFinder::MatchResult ) {
   std::string ReplacementText = std::string(
   Lexer::getSourceText(CharSourceRange::getTokenRange(E->getSourceRange()),
*Result.SourceManager, getLangOpts()));
-  if (isBinaryOrTernary(E) || isa(E)) {
+  const auto *OpCallExpr = dyn_cast(E);
+  if (isBinaryOrTernary(E) || isa(E) ||
+  (OpCallExpr && (OpCallExpr->getOperator() == OO_Star))) {
 ReplacementText = "(" + ReplacementText + ")";
   }
-  if (E->getType()->isPointerType())
+  if (OpCallExpr &&
+  OpCallExpr->getOperator() == OverloadedOperatorKind::OO_Arrow) {
+// This can happen if the object is a smart pointer. Don't add anything
+// because a '->' is already there (PR#51776), just call the method.
+ReplacementText += "empty()";
+  } else if (E->getType()->isPointerType())
 ReplacementText += "->empty()";
   else
 ReplacementText += ".empty()";

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 491bc92f4ef38..541ff89c14803 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -173,6 +173,9 @@ Changes in existing checks
 - Fixed nonsensical suggestion of :doc:`altera-struct-pack-align
   ` check for empty structs.
 
+- Fixed incorrect suggestions for :doc:`readability-container-size-empty
+  ` when smart pointers 
are involved.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
index 31dccd20427e2..0759e0308e91a 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability-container-size-empty.cpp
@@ -696,3 +696,25 @@ void instantiator() {
   instantiatedTemplateWithSizeCall();
   instantiatedTemplateWithSizeCall>();
 }
+
+namespace std {
+template 
+struct unique_ptr {
+  T *operator->() const;
+  T *() const;
+};
+} // namespace std
+
+bool call_through_unique_ptr(const std::unique_ptr> ) {
+  return ptr->size() > 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be 
used
+  // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
+  // CHECK-FIXES: {{^  }}return !ptr->empty();
+}
+
+bool call_through_unique_ptr_deref(const std::unique_ptr> 
) {
+  return (*ptr).size() > 0;
+  // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: the 'empty' method should be 
used
+  // CHECK-MESSAGES: :9:8: note: method 'vector'::empty() defined here
+  // CHECK-FIXES: {{^  }}return !(*ptr).empty();
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] f25935a - [clang-tidy] Fix `altera-struct-pack-align` check for empty structs

2022-04-20 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-04-20T16:55:29+02:00
New Revision: f25935a000917f2c06b52bbc7273e20a82543782

URL: 
https://github.com/llvm/llvm-project/commit/f25935a000917f2c06b52bbc7273e20a82543782
DIFF: 
https://github.com/llvm/llvm-project/commit/f25935a000917f2c06b52bbc7273e20a82543782.diff

LOG: [clang-tidy] Fix `altera-struct-pack-align` check for empty structs

Fixes https://github.com/llvm/llvm-project/issues/50962.

Reviewed By: whisperity, aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp 
b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp
index 6ae53512fca5e..b5f8d082d8877 100644
--- a/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp
+++ b/clang-tools-extra/clang-tidy/altera/StructPackAlignCheck.cpp
@@ -77,7 +77,8 @@ void StructPackAlignCheck::check(const 
MatchFinder::MatchResult ) {
   uint64_t CharSize = Result.Context->getCharWidth();
   CharUnits CurrSize = Result.Context->getASTRecordLayout(Struct).getSize();
   CharUnits MinByteSize =
-  CharUnits::fromQuantity(ceil((float)TotalBitSize / CharSize));
+  CharUnits::fromQuantity(std::max(
+  ceil(static_cast(TotalBitSize) / CharSize), 1));
   CharUnits MaxAlign = CharUnits::fromQuantity(
   ceil((float)Struct->getMaxAlignment() / CharSize));
   CharUnits CurrAlign =

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 50d5b8ecc72c1..491bc92f4ef38 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -170,6 +170,9 @@ Changes in existing checks
   ` to work when
   the vector is a member of a structure.
 
+- Fixed nonsensical suggestion of :doc:`altera-struct-pack-align
+  ` check for empty structs.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp
index 615b6cafe87a2..472372ffe35c1 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/altera-struct-pack-align.cpp
@@ -99,3 +99,22 @@ void no_trigger_on_instantiation() {
   struct bad_align3 instantiated { 'a', 0.001, 'b' };
 }
 
+// Make sure that we don't recommend aligning an empty struct to zero bytes 
(PR#51620)
+struct StructWithNoFields {};
+
+struct ContainsStructWithNoFields {
+  StructWithNoFields s;
+};
+
+// Make sure that an empty struct is treated like "char" for padding and 
alignment purposes
+struct ContainsStructWithNoFields2 {
+  StructWithNoFields s;
+  double d;
+  StructWithNoFields t;
+};
+// CHECK-MESSAGES: :[[@LINE-5]]:8: warning: accessing fields in struct 
'ContainsStructWithNoFields2' is inefficient due to padding; only needs 10 
bytes but is using 24 bytes [altera-struct-pack-align]
+// CHECK-MESSAGES: :[[@LINE-6]]:8: note: use "__attribute__((packed))" to 
reduce the amount of padding applied to struct 'ContainsStructWithNoFields2'
+// CHECK-MESSAGES: :[[@LINE-7]]:8: warning: accessing fields in struct 
'ContainsStructWithNoFields2' is inefficient due to poor alignment; currently 
aligned to 8 bytes, but recommended alignment is 16 bytes 
[altera-struct-pack-align]
+// CHECK-MESSAGES: :[[@LINE-8]]:8: note: use "__attribute__((aligned(16)))" to 
align struct 'ContainsStructWithNoFields2' to 16 bytes
+// CHECK-FIXES: __attribute__((packed))
+// CHECK-FIXES: __attribute__((aligned(16)));



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] a18634b - [clang-tidy] Never consider assignments as equivalent in `misc-redundant-expression` check

2022-04-12 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-04-12T16:03:14+02:00
New Revision: a18634b74fc0ee1ca0d580cb5b71cd6807d18ce9

URL: 
https://github.com/llvm/llvm-project/commit/a18634b74fc0ee1ca0d580cb5b71cd6807d18ce9
DIFF: 
https://github.com/llvm/llvm-project/commit/a18634b74fc0ee1ca0d580cb5b71cd6807d18ce9.diff

LOG: [clang-tidy] Never consider assignments as equivalent in 
`misc-redundant-expression` check

Fixes https://github.com/llvm/llvm-project/issues/35853.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index e68384348bd9c..5d30ad23a8531 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -134,6 +134,8 @@ static bool areEquivalentExpr(const Expr *Left, const Expr 
*Right) {
 return cast(Left)->getOpcode() ==
cast(Right)->getOpcode();
   case Stmt::BinaryOperatorClass:
+if (cast(Left)->isAssignmentOp())
+  return false;
 return cast(Left)->getOpcode() ==
cast(Right)->getOpcode();
   case Stmt::UnaryExprOrTypeTraitExprClass:

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 11ed0e3ed2b66..870a043c6b813 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -132,7 +132,7 @@ Changes in existing checks
   the vector is a member of a structure.
 
 - Fixed a false positive in :doc:`readability-non-const-parameter
-  ` when the parameter is 
referenced by an lvalue
+  ` when the parameter is 
referenced by an lvalue.
 
 - Fixed a crash in :doc:`readability-const-return-type
   ` when a pure virtual 
function
@@ -150,6 +150,9 @@ Changes in existing checks
   Fixed an issue when there was already an initializer in the constructor and
   the check would try to create another initializer for the same member.
 
+- Fixed a false positive in :doc:`misc-redundant-expression 
`
+  involving assignments in conditions. This fixes `Issue 35853 
`_.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
index 31fe8e0275b02..6597d05e44966 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
@@ -831,3 +831,15 @@ struct Bar2 {
 };
 
 } // namespace no_crash
+
+int TestAssignSideEffect(int i) {
+  int k = i;
+
+  if ((k = k + 1) != 1 || (k = k + 1) != 2)
+return 0;
+
+  if ((k = foo(0)) != 1 || (k = foo(0)) != 2)
+return 1;
+
+  return 2;
+}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] 528e6eb - [clang] Improve diagnostic for reopened inline namespace

2022-03-23 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-03-23T22:30:45+01:00
New Revision: 528e6eba2f7906d974594b1fc50362dfad239609

URL: 
https://github.com/llvm/llvm-project/commit/528e6eba2f7906d974594b1fc50362dfad239609
DIFF: 
https://github.com/llvm/llvm-project/commit/528e6eba2f7906d974594b1fc50362dfad239609.diff

LOG: [clang] Improve diagnostic for reopened inline namespace

Reviewed By: cor3ntin, aaron.ballman

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

Added: 
clang/test/SemaCXX/warn-inline-namespace-reopened-twice.cpp

Modified: 
clang/docs/ReleaseNotes.rst
clang/lib/Sema/SemaDeclCXX.cpp
clang/test/Parser/cxx2a-inline-nested-namespace-definition.cpp

Removed: 




diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 83d5dbdda2607..373d4156cd797 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -83,6 +83,11 @@ Improvements to Clang's diagnostics
 - ``-Wliteral-range`` will warn on floating-point equality comparisons with
   constants that are not representable in a casted value. For example,
   ``(float) f == 0.1`` is always false.
+- ``-Winline-namespace-reopened-noninline`` now takes into account that the
+  ``inline`` keyword must appear on the original but not necessarily all
+  extension definitions of an inline namespace and therefore points its note
+  at the original definition. This fixes `Issue 50794 (PR51452)
+  `_.
 
 Non-comprehensive list of changes in this release
 -

diff  --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 7992e4a349611..0b5440c227d1c 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11060,6 +11060,11 @@ static void DiagnoseNamespaceInlineMismatch(Sema , 
SourceLocation KeywordLoc,
 NamespaceDecl *PrevNS) {
   assert(*IsInline != PrevNS->isInline());
 
+  // 'inline' must appear on the original definition, but not necessarily
+  // on all extension definitions, so the note should point to the first
+  // definition to avoid confusion.
+  PrevNS = PrevNS->getFirstDecl();
+
   if (PrevNS->isInline())
 // The user probably just forgot the 'inline', so suggest that it
 // be added back.

diff  --git a/clang/test/Parser/cxx2a-inline-nested-namespace-definition.cpp 
b/clang/test/Parser/cxx2a-inline-nested-namespace-definition.cpp
index f37dc8c033cec..72a0cbf8da8f1 100644
--- a/clang/test/Parser/cxx2a-inline-nested-namespace-definition.cpp
+++ b/clang/test/Parser/cxx2a-inline-nested-namespace-definition.cpp
@@ -17,7 +17,7 @@ inline namespace foo4::foo5::foo6 { // expected-error 
{{nested namespace definit
 // expected-warning@+2 {{inline nested namespace definition is incompatible 
with C++ standards before C++20}}
 #endif
 namespace valid1::valid2::inline valid3::inline valid4::valid5 {}
-// expected-note@-1 2 {{previous definition is here}}
+// expected-note@-1 4 {{previous definition is here}}
 
 #if __cplusplus <= 201402L
 // expected-warning@+3 {{nested namespace definition is a C++17 extension; 
define each namespace separately}}
@@ -34,7 +34,6 @@ namespace valid1::valid2::valid3::valid4::valid5 {}
 // expected-warning@+2 {{inline nested namespace definition is incompatible 
with C++ standards before C++20}}
 #endif
 namespace valid1::valid2::inline valid3::inline valid4::valid5 {}
-// expected-note@-1 2 {{previous definition is here}}
 
 namespace valid1 {
 namespace valid2 {

diff  --git a/clang/test/SemaCXX/warn-inline-namespace-reopened-twice.cpp 
b/clang/test/SemaCXX/warn-inline-namespace-reopened-twice.cpp
new file mode 100644
index 0..ac22280fdf800
--- /dev/null
+++ b/clang/test/SemaCXX/warn-inline-namespace-reopened-twice.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -Wall -verify -std=c++11 %s
+
+// Regression test for #50794.
+
+// expected-note@+1 2 {{previous definition is here}}
+inline namespace X {}
+
+namespace X {} // expected-warning {{inline namespace reopened as a non-inline 
namespace}}
+namespace X {} // expected-warning {{inline namespace reopened as a non-inline 
namespace}}



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 07675b0 - [clang-tidy] Fix false positives in `misc-redundant-expression` check

2022-03-22 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-03-23T00:32:45+01:00
New Revision: 07675b0b38e930c2c582122ac93efcdf7859a772

URL: 
https://github.com/llvm/llvm-project/commit/07675b0b38e930c2c582122ac93efcdf7859a772
DIFF: 
https://github.com/llvm/llvm-project/commit/07675b0b38e930c2c582122ac93efcdf7859a772.diff

LOG: [clang-tidy] Fix false positives in `misc-redundant-expression` check

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index f8073bff5ea98..e68384348bd9c 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -569,6 +569,7 @@ matchRelationalIntegerConstantExpr(StringRef Id) {
   std::string SwapId = (Id + "-swap").str();
   std::string NegateId = (Id + "-negate").str();
   std::string OverloadId = (Id + "-overload").str();
+  std::string ConstId = (Id + "-const").str();
 
   const auto RelationalExpr = ignoringParenImpCasts(binaryOperator(
   isComparisonOperator(), expr().bind(Id),
@@ -600,7 +601,9 @@ matchRelationalIntegerConstantExpr(StringRef Id) {
   cxxOperatorCallExpr(
   hasAnyOverloadedOperatorName("==", "!=", "<", "<=", ">", ">="),
   // Filter noisy false positives.
-  unless(isMacro()), unless(isInTemplateInstantiation()))
+  unless(isMacro()), unless(isInTemplateInstantiation()),
+  anyOf(hasLHS(ignoringParenImpCasts(integerLiteral().bind(ConstId))),
+hasRHS(ignoringParenImpCasts(integerLiteral().bind(ConstId)
   .bind(OverloadId);
 
   return anyOf(RelationalExpr, CastExpr, NegateRelationalExpr,
@@ -674,16 +677,38 @@ static bool retrieveRelationalIntegerConstantExpr(
 if (canOverloadedOperatorArgsBeModified(OverloadedOperatorExpr, false))
   return false;
 
+bool IntegerConstantIsFirstArg = false;
+
 if (const auto *Arg = OverloadedOperatorExpr->getArg(1)) {
   if (!Arg->isValueDependent() &&
-  !Arg->isIntegerConstantExpr(*Result.Context))
-return false;
-}
-Symbol = OverloadedOperatorExpr->getArg(0);
+  !Arg->isIntegerConstantExpr(*Result.Context)) {
+IntegerConstantIsFirstArg = true;
+if (const auto *Arg = OverloadedOperatorExpr->getArg(0)) {
+  if (!Arg->isValueDependent() &&
+  !Arg->isIntegerConstantExpr(*Result.Context))
+return false;
+} else
+  return false;
+  }
+} else
+  return false;
+
+Symbol = OverloadedOperatorExpr->getArg(IntegerConstantIsFirstArg ? 1 : 0);
 OperandExpr = OverloadedOperatorExpr;
 Opcode = 
BinaryOperator::getOverloadedOpcode(OverloadedOperatorExpr->getOperator());
 
-return BinaryOperator::isComparisonOp(Opcode);
+if (!retrieveIntegerConstantExpr(Result, Id, Value, ConstExpr))
+  return false;
+
+if (!BinaryOperator::isComparisonOp(Opcode))
+  return false;
+
+// The call site of this function expects the constant on the RHS,
+// so change the opcode accordingly.
+if (IntegerConstantIsFirstArg)
+  Opcode = BinaryOperator::reverseComparisonOp(Opcode);
+
+return true;
   } else {
 return false;
   }

diff  --git a/clang-tools-extra/docs/ReleaseNotes.rst 
b/clang-tools-extra/docs/ReleaseNotes.rst
index 551e36dea0937..9e68fb1c7b0f8 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -116,6 +116,9 @@ Changes in existing checks
   ` when a pure virtual 
function
   overrided has a const return type. Removed the fix for a virtual function.
 
+- Fixed a false positive in :doc:`misc-redundant-expression 
`
+  involving overloaded comparison operators.
+
 Removed checks
 ^^
 

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
index 075c3aca9d03f..31fe8e0275b02 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/misc-redundant-expression.cpp
@@ -369,6 +369,11 @@ struct S {
 bool operator<=(const S , int i) { return s.x <= i; } // not modifying
 bool operator>=(const S , const int ) { return s.x >= i; } // not modifying
 
+bool operator==(int i, const S ) { return s == i; } // not modifying
+bool operator<(const int , const S ) { return s > i; } // not modifying
+bool operator<=(const int , const S ) { return s >= i; } // not modifying
+bool operator>(const int , const S ) { return s < i; 

[clang-tools-extra] d3b188a - [clang-tidy] Include constructor initializers in `bugprone-exception-escape` check

2022-01-20 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-01-21T00:53:57+01:00
New Revision: d3b188a2d72f9c398e4b1a36d23888c4ac783e9f

URL: 
https://github.com/llvm/llvm-project/commit/d3b188a2d72f9c398e4b1a36d23888c4ac783e9f
DIFF: 
https://github.com/llvm/llvm-project/commit/d3b188a2d72f9c398e4b1a36d23888c4ac783e9f.diff

LOG: [clang-tidy] Include constructor initializers in 
`bugprone-exception-escape` check

Fixes PR#52435.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp 
b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
index 97895115a7d5c..1f22c1d936561 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionAnalyzer.cpp
@@ -119,6 +119,16 @@ ExceptionAnalyzer::ExceptionInfo 
ExceptionAnalyzer::throwsException(
 CallStack.insert(Func);
 ExceptionInfo Result =
 throwsException(Body, ExceptionInfo::Throwables(), CallStack);
+
+// For a constructor, we also have to check the initializers.
+if (const auto *Ctor = dyn_cast(Func)) {
+  for (const CXXCtorInitializer *Init : Ctor->inits()) {
+ExceptionInfo Excs = throwsException(
+Init->getInit(), ExceptionInfo::Throwables(), CallStack);
+Result.merge(Excs);
+  }
+}
+
 CallStack.erase(Func);
 return Result;
   }
@@ -195,6 +205,14 @@ ExceptionAnalyzer::ExceptionInfo 
ExceptionAnalyzer::throwsException(
   ExceptionInfo Excs = throwsException(Func, CallStack);
   Results.merge(Excs);
 }
+  } else if (const auto *Construct = dyn_cast(St)) {
+ExceptionInfo Excs =
+throwsException(Construct->getConstructor(), CallStack);
+Results.merge(Excs);
+  } else if (const auto *DefaultInit = dyn_cast(St)) {
+ExceptionInfo Excs =
+throwsException(DefaultInit->getExpr(), Caught, CallStack);
+Results.merge(Excs);
   } else {
 for (const Stmt *Child : St->children()) {
   ExceptionInfo Excs = throwsException(Child, Caught, CallStack);

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp
index ebb44f84f67cc..769064d74adc5 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-exception-escape.cpp
@@ -288,6 +288,49 @@ int indirectly_recursive(int n) noexcept {
   return recursion_helper(n);
 }
 
+struct super_throws {
+  super_throws() noexcept(false) { throw 42; }
+};
+
+struct sub_throws : super_throws {
+  sub_throws() noexcept : super_throws() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in 
function 'sub_throws' which should not throw exceptions
+};
+
+struct super_throws_again {
+  super_throws_again() throw(int);
+};
+
+struct sub_throws_again : super_throws_again {
+  sub_throws_again() noexcept : super_throws_again() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in 
function 'sub_throws_again' which should not throw exceptions
+};
+
+struct init_member_throws {
+  super_throws s;
+
+  init_member_throws() noexcept : s() {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in 
function 'init_member_throws' which should not throw exceptions
+};
+
+struct implicit_init_member_throws {
+  super_throws s;
+
+  implicit_init_member_throws() noexcept {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in 
function 'implicit_init_member_throws' which should not throw exceptions
+};
+
+struct init {
+  explicit init(int, int) noexcept(false) { throw 42; }
+};
+
+struct in_class_init_throws {
+  init i{1, 2};
+
+  in_class_init_throws() noexcept {}
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: an exception may be thrown in 
function 'in_class_init_throws' which should not throw exceptions
+};
+
 int main() {
   // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: an exception may be thrown in 
function 'main' which should not throw exceptions
   throw 1;



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] f7b7138 - [clang-tidy] Make `readability-container-data-pointer` more robust

2022-01-18 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-01-18T21:08:59+01:00
New Revision: f7b7138a62648f4019c55e4671682af1f851f295

URL: 
https://github.com/llvm/llvm-project/commit/f7b7138a62648f4019c55e4671682af1f851f295
DIFF: 
https://github.com/llvm/llvm-project/commit/f7b7138a62648f4019c55e4671682af1f851f295.diff

LOG: [clang-tidy] Make `readability-container-data-pointer` more robust

Fixes PR#52245. I've also added a few test cases beyond PR#52245 that would 
also fail with the current implementation, which is quite brittle in many 
respects (e.g. it uses the `hasDescendant()` matcher to find the container that 
is being accessed, which is very easy to trick, as in the example in PR#52245).

I have not been able to reproduce the second issue mentioned in PR#52245 
(namely that using the `data()` member function is suggested even for 
containers that don't have it), but I've added a test case for it to be sure.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp

clang-tools-extra/test/clang-tidy/checkers/readability-container-data-pointer.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
index 3a670509ec2e2..d9851a89ebe1b 100644
--- a/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ContainerDataPointerCheck.cpp
@@ -16,6 +16,13 @@ using namespace clang::ast_matchers;
 namespace clang {
 namespace tidy {
 namespace readability {
+
+constexpr llvm::StringLiteral ContainerExprName = "container-expr";
+constexpr llvm::StringLiteral DerefContainerExprName = "deref-container-expr";
+constexpr llvm::StringLiteral AddrOfContainerExprName =
+"addr-of-container-expr";
+constexpr llvm::StringLiteral AddressOfName = "address-of";
+
 ContainerDataPointerCheck::ContainerDataPointerCheck(StringRef Name,
  ClangTidyContext *Context)
 : ClangTidyCheck(Name, Context) {}
@@ -38,69 +45,63 @@ void 
ContainerDataPointerCheck::registerMatchers(MatchFinder *Finder) {
   const auto Container =
   qualType(anyOf(NonTemplateContainerType, TemplateContainerType));
 
+  const auto ContainerExpr = anyOf(
+  unaryOperator(
+  hasOperatorName("*"),
+  hasUnaryOperand(
+  expr(hasType(pointsTo(Container))).bind(DerefContainerExprName)))
+  .bind(ContainerExprName),
+  unaryOperator(hasOperatorName("&"),
+hasUnaryOperand(expr(anyOf(hasType(Container),
+   hasType(references(Container
+.bind(AddrOfContainerExprName)))
+  .bind(ContainerExprName),
+  expr(anyOf(hasType(Container), hasType(pointsTo(Container)),
+ hasType(references(Container
+  .bind(ContainerExprName));
+
+  const auto Zero = integerLiteral(equals(0));
+
+  const auto SubscriptOperator = callee(cxxMethodDecl(hasName("operator[]")));
+
   Finder->addMatcher(
   unaryOperator(
   unless(isExpansionInSystemHeader()), hasOperatorName("&"),
-  hasUnaryOperand(anyOf(
-  ignoringParenImpCasts(
-  cxxOperatorCallExpr(
-  callee(cxxMethodDecl(hasName("operator[]"))
- .bind("operator[]")),
-  argumentCountIs(2),
-  hasArgument(
-  0,
-  anyOf(ignoringParenImpCasts(
-declRefExpr(
-to(varDecl(anyOf(
-hasType(Container),
-hasType(references(Container))
-.bind("var")),
-ignoringParenImpCasts(hasDescendant(
-declRefExpr(
-to(varDecl(anyOf(
-hasType(Container),
-hasType(pointsTo(Container)),
-hasType(references(Container))
-.bind("var"),
-  hasArgument(1,
-  ignoringParenImpCasts(
-  integerLiteral(equals(0)).bind("zero"
-  .bind("operator-call")),
-  ignoringParenImpCasts(
-  cxxMemberCallExpr(
-  hasDescendant(
-  declRefExpr(to(varDecl(anyOf(
-  

[clang-tools-extra] 2cd2acc - [clang-tidy] Fix false positives involving type aliases in `misc-unconventional-assign-operator` check

2022-01-17 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-01-17T21:16:17+01:00
New Revision: 2cd2accc61ea0900bde66c79d1d04b29bb9e3ed7

URL: 
https://github.com/llvm/llvm-project/commit/2cd2accc61ea0900bde66c79d1d04b29bb9e3ed7
DIFF: 
https://github.com/llvm/llvm-project/commit/2cd2accc61ea0900bde66c79d1d04b29bb9e3ed7.diff

LOG: [clang-tidy] Fix false positives involving type aliases in 
`misc-unconventional-assign-operator` check

clang-tidy currently reports false positives even for simple cases such as:
```
struct S {
using X = S;
X =(const X&) { return *this; }
};
```
This is due to the fact that the `misc-unconventional-assign-operator` check 
fails to look at the //canonical// types. This patch fixes this behavior.

Reviewed By: aaron.ballman, mizvekov

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp

clang-tools-extra/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst

clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp 
b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
index 594c83a30e7ef..12ba5d9997fb1 100644
--- a/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnconventionalAssignOperatorCheck.cpp
@@ -18,13 +18,14 @@ namespace misc {
 
 void UnconventionalAssignOperatorCheck::registerMatchers(
 ast_matchers::MatchFinder *Finder) {
-  const auto HasGoodReturnType = cxxMethodDecl(returns(lValueReferenceType(
-  pointee(unless(isConstQualified()),
-  anyOf(autoType(), hasDeclaration(equalsBoundNode("class")));
+  const auto HasGoodReturnType =
+  cxxMethodDecl(returns(hasCanonicalType(lValueReferenceType(pointee(
+  unless(isConstQualified()),
+  anyOf(autoType(), hasDeclaration(equalsBoundNode("class";
 
-  const auto IsSelf = qualType(
+  const auto IsSelf = qualType(hasCanonicalType(
   anyOf(hasDeclaration(equalsBoundNode("class")),
-referenceType(pointee(hasDeclaration(equalsBoundNode("class"));
+
referenceType(pointee(hasDeclaration(equalsBoundNode("class")));
   const auto IsAssign =
   cxxMethodDecl(unless(anyOf(isDeleted(), isPrivate(), isImplicit())),
 hasName("operator="), ofClass(recordDecl().bind("class")))
@@ -37,9 +38,9 @@ void UnconventionalAssignOperatorCheck::registerMatchers(
   cxxMethodDecl(IsAssign, unless(HasGoodReturnType)).bind("ReturnType"),
   this);
 
-  const auto BadSelf = referenceType(
+  const auto BadSelf = qualType(hasCanonicalType(referenceType(
   anyOf(lValueReferenceType(pointee(unless(isConstQualified(,
-rValueReferenceType(pointee(isConstQualified();
+rValueReferenceType(pointee(isConstQualified()));
 
   Finder->addMatcher(
   cxxMethodDecl(IsSelfAssign,

diff  --git 
a/clang-tools-extra/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
 
b/clang-tools-extra/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
index 8b85332fa0c35..49e3fd5b6ee42 100644
--- 
a/clang-tools-extra/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
+++ 
b/clang-tools-extra/docs/clang-tidy/checks/misc-unconventional-assign-operator.rst
@@ -8,6 +8,8 @@ Finds declarations of assign operators with the wrong return 
and/or argument
 types and definitions with good return type but wrong ``return`` statements.
 
   * The return type must be ``Class&``.
-  * Works with move-assign and assign by value.
+  * The assignment may be from the class type by value, const lvalue
+reference, non-const rvalue reference, or from a completely 
diff erent
+type (e.g. ``int``).
   * Private and deleted operators are ignored.
   * The operator must always return ``*this``.

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp
index 4f0713a01f6f4..b010a8a230bcc 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/misc-unconventional-assign-operator.cpp
@@ -127,3 +127,39 @@ struct AssignmentCallAtReturn {
 // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: operator=() should always 
return '*this'
   }
 };
+
+// Check that no false positives are issued when using type aliases.
+struct TypeAlias {
+  using Alias = TypeAlias;
+  // This is correct and should not produce any warnings:
+  Alias =(const Alias &) { return *this; }
+
+  using AliasRef = Alias &;
+  // So is this (assignments from other types are fine):
+  AliasRef operator=(int) { return *this; }
+};
+
+// Same 

[clang-tools-extra] 42bc327 - [clang-tidy] Fix `readability-redundant-declaration` false positive for template friend declaration

2022-01-17 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2022-01-17T20:50:32+01:00
New Revision: 42bc3275d3687524ddc0d20c72722b9324f87be4

URL: 
https://github.com/llvm/llvm-project/commit/42bc3275d3687524ddc0d20c72722b9324f87be4
DIFF: 
https://github.com/llvm/llvm-project/commit/42bc3275d3687524ddc0d20c72722b9324f87be4.diff

LOG: [clang-tidy] Fix `readability-redundant-declaration` false positive for 
template friend declaration

Fixes [[ https://bugs.llvm.org/show_bug.cgi?id=48086 | PR#48086 ]]. The problem 
is that the current matcher uses `hasParent()` to detect friend declarations, 
but for a template friend declaration, the immediate parent of the 
`FunctionDecl` is a `FunctionTemplateDecl`, not the `FriendDecl`. Therefore, I 
have replaced the matcher with `hasAncestor()`.

Reviewed By: aaron.ballman

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp

clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp

Removed: 




diff  --git 
a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp 
b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
index dfe3fbc96bf1b..78ba9691c2557 100644
--- a/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/RedundantDeclarationCheck.cpp
@@ -37,7 +37,7 @@ void RedundantDeclarationCheck::registerMatchers(MatchFinder 
*Finder) {
   functionDecl(unless(anyOf(
   isDefinition(), isDefaulted(),
   doesDeclarationForceExternallyVisibleDefinition(),
-  hasParent(friendDecl()))
+  hasAncestor(friendDecl()))
   .bind("Decl"),
   this);
 }

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp
 
b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp
index 90fb98a882983..85ee9a52dfb7e 100644
--- 
a/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp
+++ 
b/clang-tools-extra/test/clang-tidy/checkers/readability-redundant-declaration.cpp
@@ -70,6 +70,32 @@ struct Friendly {
 
 void enemy();
 
+template 
+struct TemplateFriendly {
+  template 
+  friend void generic_friend();
+};
+
+template 
+void generic_friend() {}
+
+TemplateFriendly template_friendly;
+
+template 
+struct TemplateFriendly2 {
+  template 
+  friend void generic_friend2() {}
+};
+
+template 
+void generic_friend2();
+
+void generic_friend_caller() {
+  TemplateFriendly2 f;
+  generic_friend2();
+}
+
+
 namespace macros {
 #define DECLARE(x) extern int x
 #define DEFINE(x) extern int x; int x = 42



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] 987a215 - [clang-tidy] Use `hasCanonicalType()` matcher in `bugprone-unused-raii` check

2021-12-01 Thread Fabian Wolff via cfe-commits

Author: Fabian Wolff
Date: 2021-12-02T01:53:12+01:00
New Revision: 987a21522f2c7d799d0c2a720b3315a4fb6d1e74

URL: 
https://github.com/llvm/llvm-project/commit/987a21522f2c7d799d0c2a720b3315a4fb6d1e74
DIFF: 
https://github.com/llvm/llvm-project/commit/987a21522f2c7d799d0c2a720b3315a4fb6d1e74.diff

LOG: [clang-tidy] Use `hasCanonicalType()` matcher in `bugprone-unused-raii` 
check

Fixes PR#52217.

Reviewed By: simon.giesecke

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

Added: 


Modified: 
clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii.cpp

Removed: 




diff  --git a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp 
b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
index 9b8d8d7bf5f4c..435c47348c7c0 100644
--- a/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/UnusedRaiiCheck.cpp
@@ -29,10 +29,11 @@ void UnusedRaiiCheck::registerMatchers(MatchFinder *Finder) 
{
   Finder->addMatcher(
   mapAnyOf(cxxConstructExpr, cxxUnresolvedConstructExpr)
   .with(hasParent(compoundStmt().bind("compound")),
-anyOf(hasType(cxxRecordDecl(hasNonTrivialDestructor())),
-  hasType(templateSpecializationType(
+anyOf(hasType(hasCanonicalType(recordType(hasDeclaration(
+  cxxRecordDecl(hasNonTrivialDestructor()),
+  hasType(hasCanonicalType(templateSpecializationType(
   hasDeclaration(classTemplateDecl(has(
-  cxxRecordDecl(hasNonTrivialDestructor()
+  cxxRecordDecl(hasNonTrivialDestructor())
   .bind("expr"),
   this);
 }

diff  --git 
a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii.cpp 
b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii.cpp
index 94643676f45ce..1b285768fdb33 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone-unused-raii.cpp
@@ -82,6 +82,28 @@ void templatetest() {
   (void)i;
 }
 
+template 
+void aliastest() {
+  using X = Foo;
+  using Y = X;
+  using Z = Y;
+  Z(42);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately 
after creation; did you mean to name the object?
+  // CHECK-FIXES: Z give_me_a_name(42);
+
+  typedef Z ZT;
+  ZT(42, 13);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately 
after creation; did you mean to name the object?
+  // CHECK-FIXES: ZT give_me_a_name(42, 13);
+
+  using TT = TCtorDefaultArg;
+  TT(42);
+  // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately 
after creation; did you mean to name the object?
+  // CHECK-FIXES: TT give_me_a_name(42);
+
+  (void)0;
+}
+
 void test() {
   Foo(42);
 // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: object destroyed immediately after 
creation; did you mean to name the object?



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits